打印
[应用相关]

stm32 HardFault错误调试记录

[复制链接]
455|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
labasi|  楼主 | 2021-6-3 16:00 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 labasi 于 2021-6-3 16:04 编辑

当程序报错时候 我们要定位到出错位置 才能更快的解决问题。
当程序进入hardfault中断算是一个比较麻烦的bug吧。本文把当程序进入硬错误中断时候的调试方式做个记录。
先说第一种方式,第一种方式比较简单,可以直接在hardfault中断中打个断点,当程序进入hardfault中断后,查看当前的栈调用情况。进而确定出错的函数,然后查看相应函数中错误。
模拟错误
这里我直接访问一个不存在地址让程序报个中断。

int main(void)
{
        int i = 0;
        for(i = 0; i < 100; i++)
        {
                *((unsigned int *)0x08100004) = 0x1;
        }
    while(1)
        {
        }        
}


我用的是STM32F103VG的芯片,1MFlash,最大地址也就是0x08100000,所以当调试这段代码是,程序会进HardFault中断。







使用特权

评论回复
沙发
labasi|  楼主 | 2021-6-3 16:02 | 只看该作者
解决bug
简单方式
我们直接在HardFault_Handler打个断点。当全速运行后程序会进入这个中断,然后再找个断点停下,此时我们去看stackcall使用情况。如下图,通过栈情况我们可以看到程序是从main进入错误中断的,所以此时我们只需要进入main函数排查错误即可。



使用特权

评论回复
板凳
labasi|  楼主 | 2021-6-3 16:04 | 只看该作者
终极手段
第一种方式有时候并不合适,比如函数内代码量较多,或者程序开了优化,以上方式就不太合适了。此时可以这样做。
第一步还是一样,在HardFault_Handler打断点。
停在断点后,去查看Fault report。打开方式如图:


打开fault reports问题就一目了然了,可以看到Hard Faults的FORCED位和Bus Faults的IMPRECISERR位被置位了。我们错误代码也确实是访问一个不存在地址,所以报了总线错误。
这里为什么总线错误而触发的是Hard Fault中断呢,

查文档可以得知,所有被除能的 fault,都将“上访”(escalation) 成 硬 fault。这里就可以理解了。
进入中断之前,芯片会有压栈操作,进入错误中断也不例外,我们可以根据自己程序是使用MSP还是PSP,找到进中断之前的栈情况。

此处为什么是xSP-24,这里简单说一下,这里需要查一下stm32的自动入栈顺序。

N-32-(N-8) = N-24

此处还要注意一点,虽然是减24,但栈是向下增长的,所以实际计算应该是加地址。



查看寄存器可以看到,现在MSP值为0x20000528,然后在Memory窗口查看这个地址的代码,因为地址是32位的。所以以unsigned long格式查看,这样方便等会复制地址。上文可知要加24,24/4=6,地址加6也就是0x0800047D,然后去看汇编窗口对应地址代码


通过这种方式可以看到,定位到了相关错误代码位置,然后剩下的事情就简单多了。

总结
总的来说出现硬错误还是一件比较恶心的事情,平时编码养成好习惯,指针切记初始化,参数做范围判断,通讯尽可能考虑全出错处理。



使用特权

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

本版积分规则

51

主题

3372

帖子

2

粉丝