博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Cortex-M3开发经验(二):确定发生HardFault的地方
阅读量:4586 次
发布时间:2019-06-09

本文共 1607 字,大约阅读时间需要 5 分钟。

Cortex-M3开发经验(二):确定发生HardFault的地方

我们在调试时,最害怕就是出现HardFault错误了。因为我们不知道是从哪个地方跳到这里的?单步调试起来太过于麻烦,特别在代码量大的时候,更是费时间。

那么有没有一种方法,可以快速定位到发生HardFault错误的代码位置(函数)呢?

Cortex-M3中断/异常的响应过程

我们知道,HardFault实质上是一个中断,中断的过程如下图:

FUNC1->IRQ_Handler:发生中断Note right of IRQ_Handler:中断处理函数IRQ_Handler->FUNC1:中断返回

在这里我就有一个疑问了:既然FUNC1和IRQ_Handler之间不存在调用关系,那IRQ_Handler运行完之后怎么返回到FUNC1中去的呢?

中断/异常响应原理:当Cortex-M3响应一个中断时,会在它体内奔涌起三股暗流:

1.入栈:吧8个寄存器(R0~R3,R12,LR,PC,xPSR)的值压入栈中;

2.取向量:从向量表中找出对应的中断服务程序入口地址(函数指针的原理);

3.更新PC指针,堆栈指针SP,连接寄存器LR的值。

摘自《ARM Cortex M3权威指南》

明白原理后,就好办了。那么我们在HardFault函数中打一個断点,在他刚进入中断时,内核寄存器的值,就是保存发生中断那一刻的值。我们就可以通过这些值,得到发送错误的位置。

下图是出现错误时状态:

975656-20190613164028419-352315229.png

我们关注SP寄存器的值:0x2000FFAC,我们再查看SP地址附近所对应的值。

address value
0x2000FFAC 0x2000FFD0
0x2000FFB0 0x0000000D
0x2000FFB4 0x00000000
0x2000FFB8 0x00000000
0x2000FFBC 0x0001F204
0x2000FFC0 0xA5A5A5A5
0x2000FFC4 0x0001F239
0x2000FFC8 0x0001F204
0x2000FFCC 0x00000000
0x2000FFD0 0x8000000C

我们需要的是PC和LR的值,因为这两个寄存器代表的是:PC代表当前执行位置,LR代表返回地址。

从栈空间我们可以得知:PC的值为0x0001F204, LR的值为0x1F239。

怎么找的?

很简单,我们知道进入中断处理函数后,内核依次将xPSR,PC,LR,R12,R3,R2,R1,R0的顺序入栈。(至于为什么是这个顺序,请看Cortex-M3权威指南)。然后我们需要知道栈的操作方式(满减,空减,满增,空增),而Cortex-M3属于满减栈,就是堆栈指针指向最后一个被压入堆栈的32位数值;PUSH压栈时,SP先自减4,再存入新值,POP出栈时相反,先从SP指针处读出上次被压入堆栈的值,SP再自增4。

所以我们要从0x2000FFD0开始看起,PC跟LR是第二跟第三入栈的。所以就是0x2000FFC8和0x2000FFC4对应的值。

发生HardFault时,PC正在执行0x1F204地址的指令,LR是准备返回的地址0x1F239。

怎么看这两个地址所在的函数?

有两个方法:

1.看编译器生成的map文件。

2.使用编译工具链的addr2line,如下:

arm-none-eabi-addr2line 1f204 -f -e xxxx.elf    (烧录文件)>fp_test    (函数名)>..../main.c:129    (对应文件及行号)arm-none-eabi-addr2line 1f239 -f -e xxxx.elf>test>..../main.c:142

转载于:https://www.cnblogs.com/Oushangrong/p/11017474.html

你可能感兴趣的文章
c#函数中处理对象的问题
查看>>
转 top、postop、scrolltop、offsetTop、scrollHeight、offsetHeight、clientHeight
查看>>
2017-12-27练习
查看>>
NET设计规范(二) 命名规范
查看>>
VMware 9.0.1安装Mac OS X Mountain Lion 10.8.2
查看>>
SSL延迟
查看>>
android新手关于左右滑动的问题,布局把<android.support.v4.view.ViewPager/><ImageView/> 放在上面就不行了。...
查看>>
python第二十一天---昨天没写完作业
查看>>
爬虫基础--IO多路复用单线程异步非阻塞
查看>>
Johnny Solving CodeForces - 1103C (构造,图论)
查看>>
oracle数据库自学笔记(持续更新中……)
查看>>
BZOJ3685: 普通van Emde Boas树
查看>>
Jquery 操作Cookie
查看>>
nginx
查看>>
递归和非递归的二分查找
查看>>
JSP自定义标签
查看>>
项目测试流程
查看>>
《代码大全》学习之--使用变量的一般事项
查看>>
JS位操作符
查看>>
mongodb
查看>>