打印
[其他ST产品]

(GCC)STM32进阶详解之栈回溯

[复制链接]
楼主: 大鹏2365
手机看帖
扫描二维码
随时随地手机跟帖
21
大鹏2365|  楼主 | 2023-1-15 17:36 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
可以看到,根据上文的分析,LR和R4已经被压栈,此时栈顶已经变成了0x20000558,我们继续向下推进, 这次把断点打在fault_test_by_div0函数一开始的位置:

使用特权

评论回复
22
大鹏2365|  楼主 | 2023-1-15 17:39 | 只看该作者

使用特权

评论回复
23
大鹏2365|  楼主 | 2023-1-15 17:40 | 只看该作者
继续把断点打在出错的那一行函数,继续运行分析:

使用特权

评论回复
24
大鹏2365|  楼主 | 2023-1-15 17:40 | 只看该作者
对比上面两张图可以看到,栈内数据和我们分析的一模一样,现在我们即将运行错误代码,我们知道,Cortex-M系列的MCU出现错误会跳往编号为3的中断:

使用特权

评论回复
25
大鹏2365|  楼主 | 2023-1-15 17:43 | 只看该作者

使用特权

评论回复
26
大鹏2365|  楼主 | 2023-1-15 17:44 | 只看该作者
这里我们找到中断表,最后可以查到跳转到了HardFault_Handler函数,我们把下个断点打在这里:

使用特权

评论回复
27
大鹏2365|  楼主 | 2023-1-15 17:44 | 只看该作者

使用特权

评论回复
28
大鹏2365|  楼主 | 2023-1-15 17:45 | 只看该作者
可以看到,出现错误后和我们预期一样,注意两个地方:

使用特权

评论回复
29
大鹏2365|  楼主 | 2023-1-15 19:04 | 只看该作者
1.进入中断后,LR的值会被自动更新为特殊的EXC_RETURN,这个值的含义如下:

使用特权

评论回复
30
大鹏2365|  楼主 | 2023-1-15 19:08 | 只看该作者
也就是它告诉了我们,这个中断执行完后,我们返回时该使用何种模式,和使用哪个堆栈指针。

使用特权

评论回复
31
大鹏2365|  楼主 | 2023-1-15 19:09 | 只看该作者
2.正因为LR因为上述原因被占用了,导致我们没有办法再直接通过LR返回到中断被调用前的位置,所以进入中断后,一部分寄存器是硬件自动入栈的:

使用特权

评论回复
32
大鹏2365|  楼主 | 2023-1-15 19:10 | 只看该作者

使用特权

评论回复
33
大鹏2365|  楼主 | 2023-1-15 19:11 | 只看该作者
由进入HardFault_Handler后的现场图也可以看到,压栈的内容与寄存器是一一对应的。也就是说硬件替我们保存了一部分现场,你可能会问了,为何还有一部分寄存器没有被保存,万一在进入中断前我使用过它们比如R5,中断中被破坏了,代码从中断中出来后,再回去执行不是一样会出错吗?这在上一章有讲过,函数调用原则里有分哪些寄存器是需要调用者保护,哪些寄存器是需要被调用者保护的,这里除了硬件压栈的那部分,剩余的都应该由被调用者保护。

使用特权

评论回复
34
大鹏2365|  楼主 | 2023-1-15 19:13 | 只看该作者
这样是不是一切都明了了?思考这样一个问题:

如果此时让你在HardFault_Handler中写一个函数,用它去寻找是由哪条指令执行后,导致进入了HardFault_Handler,而那个指令所在的函数又是被哪里所调用,你会写吗?

使用特权

评论回复
35
大鹏2365|  楼主 | 2023-1-15 19:15 | 只看该作者
一切一切的关键又回到了那三个地址:

使用特权

评论回复
36
大鹏2365|  楼主 | 2023-1-15 19:16 | 只看该作者

使用特权

评论回复
37
大鹏2365|  楼主 | 2023-1-15 19:17 | 只看该作者
对,就是如何从栈中找到这三个地址!

至于为什么可以打印出错误类型是除0,那很简单,即使你没有移植任何代码,在keil中HardFault_Handler打上断点,进入后,查看:

使用特权

评论回复
38
大鹏2365|  楼主 | 2023-1-15 19:18 | 只看该作者

使用特权

评论回复
39
大鹏2365|  楼主 | 2023-1-15 19:21 | 只看该作者

使用特权

评论回复
40
大鹏2365|  楼主 | 2023-1-15 19:22 | 只看该作者
简单来说就是Cortex-M内核提供了一些寄存器,它们保存出错时,错误的大概类型。只需在进入错误中断后查询相关寄存器即可。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则