上面是一个硬错误问题,关于硬错误到现在我已经遇到了不少,见多了也就没有刚开始的那种迷茫了。上面的错误原因是因为我误删了一些代码,关于硬错误我觉得除了栈溢出,其他的通过查看C语言代码就能找到一些蛛丝马迹。
先贴一些会用到的资料:
先介绍发声异常时的相关动作:
发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。
由于异常发生时,内核将R0~R3、R12、Return address、PSR、LR寄存器依次入栈,其中Return address即为发生异常前PC将要执行的下一条指令地址,因此在堆栈中反数第三个字即为出错位置。 DEBUG如下图 SP值为0x20008560,查看堆栈里面的值依次为R0~R3、R12、Returnaddress、PSR、LR, 例如R0(10 27 00 00), 显然堆栈后第21个字节到24字节即为Returnaddress,该地址0x08001FFD即为异常前PC将要执行的下一条指令地址(即StackFlow()后面的语句处RCC->CR &= (uint32_t)0xFFFBFFFF)
注意:寄存器均是32位,且STM32是小端模式。(参考Cortex-M3权威) 下面有一个我追着硬错误的例子和方法
具体步骤如下: 在启动文件中硬错误中断函数处添加如下代码: HardFault_Handler TSTLR, #4 ;20140105liyang add ITEEQ ;20140105liyangadd MRSEQR0, MSP ;20140105liyang add MRSNER0, PSP ;20140105liyang add BHardFault_Handler 然后把硬错误中断函数中的语句都屏蔽只留while(1){}语句。 void HardFault_Handler(void) { while(1){} } 在while 处设置断点。 下图可知从CPU的寄存器窗口和Memery都可以看到,入栈时R0-R3、R12、LR的值,根据LR(当时PC的值)的值就可以找到相应中断前执行的那条语句。关于程序用的那个栈也能从图中看出:R13(SP)的值和R13_main(MSP)的值相同,所以用的是MSP栈(这种判断方式待验证,以后用系统的时候试试)
如图蓝框中00009d5d 即为入栈的PC 的值。
这是在反汇编窗口查到的。 实际在C 语句中跟踪的时候出问题的是执行这条语句的时候:
。 以上说明:从仿真的寄存器查找异常地址这种方法是可以使用的。但是找硬错误很多时候都是通过逻辑分析和单步跟踪,这种方法还不能精确定位错误。只能是帮助缩小问题范围。
|