KEIL工程调整一下project窗口中加载的文件顺序,编译运行直接进Hardfault

2019-03-23 14:46发布



自己的一个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整除?编译文件顺序会影响数组申请地址吗?

以上四个问题,请大牛们帮忙解释下,谢谢。  

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
18条回答
wjroy11
1楼-- · 2019-03-24 10:05


就是把工程里的 C文件调了顺序?


对,就是工程里两个文件调换一下顺序,编译也能通过,只是运行时,调换后的工程就Hardfault。我用的c++,调换的是两个cpp文件。

ddllxxrr
2楼-- · 2019-03-24 18:03


顺序不一样时有时硬件未初始化就先进入某个中断当然死机了。


严重同意

tiankai001
3楼-- · 2019-03-24 20:02


我的理解顺序不一样,只是编译的时候顺序不同,但是最终链接的hex或者bin文件应该没差别才对。按您说的硬 ...


我觉得跟文件顺序无关,因为编译的时候编译器会自动把个个函数按照程序流程编译,最主要的原因可能是有个函数出了问题,而之前运行的时候,没有运行到这个函数,所以问题没有暴露,

freebsder
4楼-- · 2019-03-25 01:07
 精彩回答 2  元偷偷看……
wjroy11
5楼-- · 2019-03-25 04:50


AB两个文件里面有什么全局的东西是一样的?是AB两个文件交换才出问题,还是任意两个文件交换都会出问题?


只是AB两文件交换才有问题,其他文件没影响

wjroy11
6楼-- · 2019-03-25 09:12


我觉得跟文件顺序无关,因为编译的时候编译器会自动把个个函数按照程序流程编译,最主要的原因可能是有个 ...


工程用了很久也没发现有什么大的bug,所以感觉应该不会存在某个函数运行不到的情况

一周热门 更多>