STM32F407因为结构体字节对齐导致的HardFault_Handler异常

STM32因为结构体字节对齐导致的HardFault_Handler异常
该问题遇到了好多次,前几次都因为赶,没有深究,前几天刚好空闲下来便排查了下。 
现象是这样的:我使用到stm32的can通信,代码本来是运行正常的。后来添加了一个9字节的结构体变量,编译后下载到目标板子运行,发现只要一接收can消息,就会进入HardFault_Handler异常,在网上查找解决方法,发现进入HardFault_Handler异常有以下一些情况:

STM32出现硬件错误可能有以下原因: 
数组越界操作; 
(2)内存溢出,访问越界; 
(3)堆栈溢出,程序跑飞; 
(4)中断处理错误; 
此部分原来博客地址:https://blog.csdn.net/electrocrazy/article/details/78173558 

按上面说的情况一一排查,(1)(3)(4)都排除了,只剩(2)内存问题,因为赶时间同时对内存没有把握,采用了最笨的方法,把后面加的代码注释掉,编译后下载到目标板子运行,一切正常。 
一次无意间发现,把原来定义的出问题的变量注释掉,重新在后面的位置定义该变量,程序也能正常运行,不会进入HardFault_Handler异常 情况如下图 
 
当然,问题实际上并没有解决,这只是胡乱弄暂时程序能运行,不会进入HardFault_Handler异常。接下来就继续忙别的,没有深究。 
后来有同事在原来的代码上把一个32个元素的数组扩展到33个字节时,程序又出现进入HardFault_Handler异常,趁有时间开始仿真查一查,按照上面链接所说的方法,在硬件中断函数HardFault_Handler里面的while(1)处打断点 
 
用工具发送can消息让程序进入中断,打开keil中View->Call Stack Window弹出Call Stack + Locals窗口,发现进入中断出错前调用的是_rt_memcpy_w函数, 
 
选中_rt_memcpy_w右键选择Show Caller Code,可以看到,程序是在执行这一行代码的时候进入了硬件异常 
 
查看汇编代码 
 
可以看到实际上调用的__aeabi_memcpy4这个函数,这个函数的作用跟ANSI C memcpy一样,只是这个函数要求的是指针是要4字节对齐的,打开工程的map文件,查找Can1RecBuf这个变量的指针,从下图可以看出,该指针不是四字节对齐的,所以程序进入了HardFault_Handler异常, 
 
接下来我把之前数组扩展到36个字节,从下图可以看出,Can1RecBuf这个变量的指针已经变成4字节对齐了 
 
编译下载后,程序正常运行。后面添加变量或是扩展数组全部四字节对齐,就不会再进入HardFault_Handler异常。

程序里有很多地方都用到了memcpy功能,在map文件查找时发现只有这个地方实际上使用的是 __aeabi_memcpy4这个函数,其他地方使用memcpy功能时使用的都是__aeabi_memcpy这个函数,(__aeabi_memcpy这个函数的作用跟ANSI C memcpy一样,只不过__aeabi_memcpy返回值为void),程序定位到使用memcp功能的变量定义处,发现,在map文件中显示调用__aeabi_memcpy函数的地方所使用的变量前面都有使用 #pragma pack(1) (#pragma pack(1)的用途可以自行百度下)让变量以一字节对齐,而在map文件中显示调用__aeabi_memcpy4这个函数的地方使用的变量前面没有全部使用#pragma pack(1)让变量以一字节对齐 ,我把原来有使用#pragma pack(1) 限定的变量前面的#pragma pack(1) 注释掉,发现原来调用_aeabi_memcpy函数的地方也变成调用_aeabi_memcpy4这个函数。定位下图代码的变量 
 
发现变量cmd的结构体前面没有使用#pragma pack(1) 限定,加上之后重新编译程序,可以看到,复制函数已经有__aeabi_memcpy4变成了__aeabi_memcpy 


总结上面的所说,要使程序不进入HardFault_Handler异常,目前我发现的有两种做法: 
1、在定义全局变量的时候全部使用4字节对齐,这样会浪费一些内存空间; 
2、在声明结构体的时在结构体的前面加上#pragma pack(1)让其以一字节对齐,这样在使用memcpy的时候就不会调用 
__aeabi_memcpy4这个函数,而是使用__aeabi_memcpy这个函数
原文:https://blog.csdn.net/u013312012/article/details/82192226 

你可能感兴趣的:(bug库)