代码
一. 前言 前面我们实现了shell命令行,现在就可以方便的添加 自定义命令了。 为了方便调试我们来实现任意存储地址的内容打印与修改的功能。这样可以实现任意外设寄存器的查看与配置,片内存储 的查看与修改,方便调试 。 二.过程2.1 打印任意地址内容shell_func.c中 申明函数 static void printmemfunc(uint8_t* param); g_shell_cmd_list_ast中添加命令行 { (uint8_t*)"printmem", printmemfunc, (uint8_t*)"printmem mode[hex/dec] addr[hex] len datasize[8/16/32] sig[1/0]"}, 命令实现函数 static void printmemfunc(uint8_t* param) { uint32_t addr; uint32_t len; uint8_t mode[64]; int datasize; uint8_t* tmp8_u; uint16_t* tmp16_u; uint32_t* tmp32_u; int8_t* tmp8_i; int16_t* tmp16_i; int32_t* tmp32_i; int sig; #if 0 if(5 == sscanf((const char*)param, "%*s %s %x %ld %d %d", mode, &addr, &len, &datasize, &sig)) #else char* p =(char*)param; while(1){ /* 跳过%*s部分 */ if((*p > 'z') || (*p < 'a')){ break; }else{ p++; } } while(1){ /* Skip leading spaces */ if(*p != ' '){ break; }else{ p++; } } uint8_t* p_mode = mode; while(1){ /* mode部分 */ if((*p > 'z') || (*p < 'a')){ break; *p_mode = 0; }else{ *p_mode = *p; p_mode++; p++; } } long tmp; xatoi(&p, &tmp); addr = tmp; xatoi(&p, &tmp); len = tmp; xatoi(&p, &tmp); datasize = tmp; xatoi(&p, &tmp); sig = tmp; #endif { if(strncmp((const char*)mode,"hex", 3) == 0) { if(datasize == 8) { tmp8_u = (uint8_t*)addr; for(uint32_t i=0; i 'z') || (*p < 'a')){ break; }else{ p++; } } while(1){ /* Skip leading spaces */ if(*p != ' '){ break; }else{ p++; } } long tmp; xatoi(&p, &tmp); addr = tmp; xatoi(&p, &tmp); val = tmp; #endif { xprintf("setmem %x %xrn",addr,val); if((addr % 4) ==0) { *(volatile uint32_t*)addr = val; xprintf("%xrn",*(volatile uint32_t*)addr); } else { xprintf("addr must be mul of 4rn"); } } } 三.测试设置栈大小,scanf需要栈比较大 我们 从map文件中一个全局变量,比如 s_uart_rx_buffer地址为0x20000670 修改指定地址处0x20000670内容再打印显示 看到后面44变为了0d是因为这里是串口缓冲区,最后是输入的回车换行。 四. 总结以上实现任意地址读写修改,就可以直接动态配置寄存器查看寄存器,修改 打印内存,而无需重新修改程序了,方便调试,甚至配合上位机可以 实现自动化测试 等 。
|