2024-07-02
GR5526 GUI专题(4) - Lvgl字体的位图数组合并转换为bin文件的说明
写技术文章
精选推荐
best
本文背景:
在分析hardfault 现场时,往往会遇到一个比较头疼的问题是内存越界/踩踏,从现场中分析只能确认到某些变量,某些寄存器的值被异常改写。被改写的时刻并非当下,有可能发生在几分钟之前,此时再去分析堆栈就很找到根本原因。
故需要一种手段去监控变量/地址的值,一旦发生改变,就触发中断,并while 1现场。
采用arm跟踪组件:数据观察点与跟踪(DWT) 可以实现这个目的
下文是介绍 如何基于GR5515系列移植DWT组件,同时该组件也支持GR5x其他系列。
1..将dwt_monitor.c和dwt_monitor.h这两个文件添加到应用工程中
2..将里dwt_monitor.h里的宏定义DWT_MONITOR_HANDLER_TYPE设为自己想要的监控提示类型。
复现概率较高,且方便引出jlink的,建议采用2;
3.在用户main函数初始化时,调用debug_monitor_init接口设置要监控的地址、监控的范围和监控的行为,其中:
--入参val_addr是要监控的变量或函数的地址;
--入参moni_mask是该地址被监控的范围,分字节、半字、字;
--入参moni_function是监控的行为,分读、写、读写。
可以同时设置4路监控。具体可以参考dwt_monitor.c里面的test code代码。
4. 当被监控的地址发生监控的行为时,会跳到DebugMon_Handler中断服务函数,进行现场分析和打印提示等(根据宏定义DWT_MONITOR_HANDLER_TYPE来执行不同的分析)
基于freertos工程测试如下:
uint8_t t_data;
void test_all_monitors(void)
{
printf("test_all_monitors \r\n");
printf("test_all_monitors %x %x %x \r\n",(uint32_t)&t_data,(uint32_t)&test_data1,(uint32_t)&test_data2); debug_monitor0_init((uint32_t)&t_data, MONITOR_MASK_BYTE, MONITOR_FUNCTION_WRITE);
}
2.在main函数初始化该组件:
int main(void)
{
app_periph_init(); /*<init user periph .*/
//test_data_all_monitors();
test_all_monitors();
ble_stack_init(&s_app_ble_callback, &heaps_table); /*< init ble stack*/
xTaskCreate(vStartTasks, "create_task", 512, NULL, 0, NULL); /*< create some demo tasks via freertos */
vTaskStartScheduler(); /*< freertos run all tasks*/
for (;;); /*< Never perform here */
}
3.在print_test_task 中 修改t_data 值:
static uint32_t i =0;
static void print_test_task(void *p_arg)
{
while (1)
{
app_rtc_get_time(&g_calendar_time);
APP_LOG_INFO("TickCount: %d, Time: %02d/%02d %02d:%02d:%02d.%03d\r\n",
xTaskGetTickCount(),
g_calendar_time.mon, g_calendar_time.date,
g_calendar_time.hour, g_calendar_time.min, g_calendar_time.sec, g_calendar_time.ms);
if(i == 3) t_data = i;
i++;
APP_LOG_INFO("print_test_task %x %x %x \r\n",(uint32_t)&t_data,(uint32_t)&test_data1,(uint32_t)&test_data2);
APP_LOG_INFO("test_data: %d,\r\n",t_data);
app_log_flush();
vTaskDelay(1000);
}
}
4.测试结果如下:
现场分析:
2.由于R14=FFFFFFFD,如图所知,需要查询PSP寄存器,得知PC = 0x0104AE74,LR = 0x010429FD
3.从PC地址,查找反汇编问题,可以得知,print_test_task函数是有改写该寄存器值,
STR r1,[r6,#0]
R6= R1; //jlink现场中,R6=00804454 ,查map文件可对应上 变量 i
ADDS r1,r1,#1
R1=R1+1; //变量 i +1
STRB r1,[r5,#0]
R5=R1 //将R1值赋给R5,R5寄存器为008044A0, 正是DWT所监控的寄存器,故触发了DWT中断。
打开微信,使用“扫一扫”即可关注