关于调试STM32F030系列单片机遇到的硬件错误中断问题
一.问题环境
最近在调试STM32F030K6单片机,用的STM32F0xx_StdPeriph_Lib_V1.5.0标准外设固件库。搭建了BSP+SYSTEM+HARDWARE+APP框架,同样的框架在STM32F103单片机及其BSP下,APP正常流畅运行,可更换为配置好的STM32F030K6的BSP及单片机板后,总是出现各种各样的问题。具体问题如下:
二.问题现象
1.程序没有进入while循环就卡死,跑飞,进入硬件错误中断(HardFault_Handler)。
开启仿真调试,发现程序卡在含有结构体变量的初始化部分。结构体通过传递指针地址作为参数,并传递给HARDWARE层
在进入HARDWARE的函数后,将结构体指针的BSP配置部分继续传递给BSP的时候,还没有进入BSP层的函数的调用前,程序就跑飞了。进入了硬件错误中断。
单片机采用8MHz的外部晶振,并通过采用6倍频的方式,使时钟频率达到48MHz,并且配置FLASH_SetLatency(FLASH_Latency_1)仍没有效果。
2.将APP的结构体包含的成员结构体变量调下位置,可以运行到下一个语句,但仍然卡死。
三.原因分析
通过以上的结构体问题,我发现问题多半是由于结构体的大小不确定造成的。而结构体的大小通常由其对齐方式决定。
编译器通常对结构体按默认的4字节对齐,并填充相应的字节。
结构体的对齐是指在内存中为结构体的成员分配存储位置时,按照特定规则调整其地址,以确保每个成员都在满足其对齐要求的地址上。这种对齐要求通常基于数据类型的大小。例如:
char
类型的对齐为 1 字节short
类型的对齐为 2 字节int
和 float
类型的对齐为 4 字节double
类型的对齐为 8 字节为什么使用F0系列的单片机,需要对结构体进行单字节对齐
F0系列的单片机可能会对内存访问有更严格的对齐要求,尤其是在访问某些外设寄存器或特定内存区域时。如果结构体中的数据成员没有按照其对齐要求存放,可能会导致以下问题:
因此,在F0系列中,为了确保数据访问的正确性和高效性,通常需要对结构体进行单字节对齐。
F1系列的单片机对内存访问的要求可能较为宽松,允许未对齐访问,因此在相同的程序中,虽然结构体未严格遵循对齐规则,仍能正常运行。原因可能包括:
四.问题解决
对所有结构体进行单字节对齐。
结构体代码统一加入:
#pragma pack(1) //1字节对齐
#pragma anon_unions //开启匿名结构、联合
union Frame
{
uint32_t buf[FRAME_BUF_SIZE];
struct
{
uint8_t head;
uint8_t length;
uint8_t cmd;
uint8_t data[FRAME_BUF_SIZE - 4];
uint8_t check;
};
};
#pragma no_anon_unions //关闭匿名结构、联合
#pragma pack() //取消字节对齐
加入对齐后,程序稳定运行。
作者:fancyang