自己的一个KEIL工程,编译后运行,正常;
调整一下project窗口中加载的文件顺序,编译运行,直接进Hardfault。
按理说文件编译顺序不会影响最终生成的目标文件才对,不应该有不一样的运行结果啊。不明白问题出在哪里。
通过对比发现两种情况编译后生成的map文件是不一样的。别的都一样。
不知道大家有没有遇到过这个问题。求指教。
找到问题原因了,是字节对齐的问题。
工程里定义了两个比较大的数组,如下:__attribute__((aligned(4)))
uint8_t MMU_US_Data_Memory[US_CAPACITY];
uint8_t MMU_SD_Data_Memory[UD_CAPACITY];
对这两个数组的内容进行处理的时候用到了memcpy,调试发现经常在memcpy的地方进入Hardfault。调试看以上两个数组的首地址MMU_US_Data_Memory和MMU_SD_Data_Memory都不是4字节对齐的,所以讲两个数组定义改成:
__attribute__((aligned(4))) uint8_t US_Data_Memory[US_CAPACITY]; __attribute__((aligned(4))) uint8_t SD_Data_Memory[UD_CAPACITY];
在memcpy处打断点,两个数组的首地址4字节对齐了,继续运行,没出现Hardfault。
那么基本上就断定是字节对齐的问题导致的Hardfault。
有几个不明白的地方请教下:
1、为什么不加__attribute__((aligned(4))) ,申请的数组就不是字节对齐的呢?我申请数组大小是16K,跟我申请空间过大有关系吗?
2、数组字节对齐后,我试着做了这个测试:
memcpy(US_Data_Memory+1,arrytest,100);
也就是说在字节对齐的US_Data_Memory数组地址基础上加了偏移量1,那么数据拷入的地址肯定就不是字节对齐了,这个时候代码是不报错的,为什么呢?
3、在调试状态下,看Disassembly窗口的汇编代码,memcpy函数对应的是:__aeabi_memcpy(),在网上查了下,这个意思是不用字节对齐的拷贝函数,如果要4字节对齐,对应的函数是__aeabi_memcpy4(),可是在汇编窗口并没有看到这个函数。不太理解。
4、为什么交换两个文件顺序之后,两个数组的首地址就会被4整除?编译文件顺序会影响数组申请地址吗?
以上四个问题,请大牛们帮忙解释下,谢谢。
严重同意
一周热门 更多>