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条回答
zhuzd
1楼-- · 2019-03-23 17:12

多打几个断点,调试一下。看看程序运行到哪里出错的。找找问题。

wenyangzeng
2楼-- · 2019-03-23 21:50
 精彩回答 2  元偷偷看……
常见泽1
3楼-- · 2019-03-23 22:48
具体例子拿出来看看呢
wjroy11
4楼-- · 2019-03-24 02:32


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


我的理解顺序不一样,只是编译的时候顺序不同,但是最终链接的hex或者bin文件应该没差别才对。按您说的硬件未初始化这个说法不太合适,比如写代码时,谁也不会刻意把初始化的文件放在最上面吧。

wjroy11
5楼-- · 2019-03-24 06:15
 精彩回答 2  元偷偷看……
常见泽1
6楼-- · 2019-03-24 08:38


工程太大了,也不适合发出来,所以只是描述一下问题表象,看大家有没有思路提供


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

一周热门 更多>