基于RT-thread,STM32硬件平台。在项目开发过程中遇到了程序进入hard fault的异常,通过查看pc寄存器和lr寄存器快速定位到出问题位置(函数)。
STM32出现硬件错误可能有以下原因:
1.内存溢出,访问越界;
2.堆栈溢出;
3.中断处理错误;
-
中断服务中禁止有阻塞或耗时操作
-
锁尽量使用带超时时间
-
注意死锁、互锁
-
临界区互斥访问
-
未初始化使用
-
内存访问越界
-
堆栈溢出
-
非法指针
-
内存泄漏
在RTT系统中,当系统出现hard fault异常时,程序会进入RTT提供的下面这个接口
void rt_hw_hard_fault_exception(struct exception_info *exception_info)
struct exception_stack_frame
{
rt_uint32_t r0;
rt_uint32_t r1;
rt_uint32_t r2;
rt_uint32_t r3;
rt_uint32_t r12;
rt_uint32_t lr;
rt_uint32_t pc;
rt_uint32_t psr;
};
通过将LR寄存器和PC寄存器打印出来,拿到当前PC地址,知道当前程序执行到了哪个地址。LR寄存器是连接寄存器,在执行子函数前,LR会保存执行完子函数后,应该回到哪个地方。
通过LR和PC值可快速定位在进入异常处理前最后一个调用的函数,在本次调试中可定位到
unsigned char CRC8_Table(unsigned char *p, int cnt)
进一步推测可能是数组越界或函数指针越界,我们将每次调用该函数传入参数cnt打印出来,发现cnt在某次传入时被赋给了很大的值,导致p++越界。
总结:指针和数组的使用需要是十分谨慎,最好能对传入的参数进行合法性检查,避免出现访问越界的问题。假如出现hard fault问题,可通过此方法快速定位到问题点。