cortex m0 数据对齐与非对齐访问引起的硬件错误中断 __attribute__ ((aligned (n)))
1、M0内核数据对齐
cortex m0内核的MCU就不能进行非对齐的联合体/结构体定义,因为cortex m0所使用的arm v6M架构不支持内存的非对齐访问,如果强制进行内存的非对齐访问,会产生`硬件错误中断`。
cortex m0内核权威指南是这样描述的:
2、非对齐访问的测试
最近在m0平台上测试一个程序的时候,发现了这个问题,程序内容如下:
uint8_t readbuffer[2];
void flash_read(uint32_t *pBuffer,uint16_t NumToWrite);
void main()
{
/* …… */
flash_read((uint32_t *)readbuffer,2);
/* …… */
}
void flash_read(uint32_t *pBuffer,uint16_t NumToWrite)
{
uint32_t flashdata;
uint16_t Counter_Num = 0;
uint32_t readtemp;
for (Counter_Num = 0; Counter_Num < NumToWrite; Counter_Num ++)
{
pBuffer[Counter_Num] =(*(__IO uint32_t*)(FLASH_WRITE_START_ADDR + Counter_Num*4));
}
}
程序功能很简单,其实就是读取片内FLSH的内容。
但是运行的时候碰到了问题,一运行到pBuffer赋值的位置,就进入硬件错误中断
!!!。
百思不得其解,想到了m0非对齐访问的情况。
于是在map文件中查看了readbuffer的地址。
发现readbuffer的地址不是4的整数倍,这就是所谓的非对齐访问引起的错误异常
。
3、如何使得变量地址进行’字’对齐?
变量地址进行’字’对齐(4字节对齐)后,就可以通过指针放心访问了。
很简单,在定义变量的时候进行关键字字节对齐的设置就可以了。
uint8_t __attribute__ ((aligned (4))) readbuffer[2];
__attribute__
和((aligned (n)))
都是是C语言的修饰关键词。
__attribute__
用于修饰属性。((aligned (n)))
用于规定变量或者结构体的最小对齐格式。
组合起来就是以N字节对齐的方式分配一个变量。
进行’字’对齐后,变量分配地址如下所示:
此时程序运行也不会进入硬件错误中断了。