基于GR5515移植DWT_Point

本文背景:

在分析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工程测试如下:

  1. 创建 test_all_monitors 函数,监控t_data 实现如下:
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++;
	printf("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.测试结果如下:

现场分析:

  1. 连接jlink,并获取现场

  1. 由于R14=FFFFFFFD,如图所知,需要查询PSP寄存器,得知PC = 0x0104AE74,LR = 0x010429FD

  1. 从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中断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: DWT是数字小波变换(Discrete Wavelet Transform)的缩写,Read-Carrier-Integrator是一种数字信号处理技术,常用于数字通信中的解调和解码。dwt_readcarrierintegrator则是将数字小波变换和Read-Carrier-Integrator技术结合起来,用于数字信号的解调、解码和调制识别等领域。 在数字通信中,常用一些数字调制技术对信号进行编码传输,如BPSK、QPSK、16QAM、64QAM等。在接收端,需要使用解调器对信号进行解调和解码。而dwt_readcarrierintegrator则可以帮助解调器识别数字调制方式,进而正确解调信号,并实现数字信号的解码。 具体来说,dwt_readcarrierintegrator算法先将接收到的信号通过数字小波变换转换成小波系数,然后利用Read-Carrier-Integrator技术进行载波恢复,最后使用调制识别算法判断数字调制方式。这一过程中,需要根据具体的信道特性和小波变换参数进行调整,以获得较好的解调效果和调制识别准确度。 总之,dwt_readcarrierintegrator技术是数字信号处理领域中的一种重要解调和解码算法,可以有效地应用于数字通信、无线电通信、卫星通信等领域。 ### 回答2: dwt_readcarrierintegrator是指在基于离散小波变换的无线通信系统中,用于解调接收信号的载波积分器读取函数。 在无线通信过程中,接收信号会受到多种干扰影响,其中最主要的是由于信道的衰落导致的多径效应。为了抑制这种干扰,无线通信系统采用了载波调制技术。在接收端,需要将接收信号与已知的本地载波信号进行混合,以便提取出数据信息。而这个过程就是利用载波积分器实现的。 dwt_readcarrierintegrator的作用是读取载波积分器内部的状态,以便实现接收信号的解调。这个函数主要应用于采用基于小波变换的调制解调技术的无线通信系统中,如OFDM系统等。 需要注意的是,dwt_readcarrierintegrator只是载波积分器的读取函数,其本身并不能完成信号的解调。要实现解调,还需要结合其他相关的函数共同实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值