社区导航

 

搜索
查看: 352|回复: 31

[求助] KEIL工程编译时的一个奇怪问题

  [复制链接]

53

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-1-23 17:09 | 显示全部楼层 |阅读模式
本帖最后由 wjroy11 于 2019-1-24 18:05 编辑

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

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


此帖出自stm32/stm8论坛


回复

使用道具 举报

46

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-1-23 17:13 | 显示全部楼层
多打几个断点,调试一下。看看程序运行到哪里出错的。找找问题。

点评

感谢,基本定位问题是字节对齐的事情。还有几个疑问看能否帮忙解答下: 找到问题原因了,是字节对齐的问题。 工程里定义了两个比较大的数组,如下:__attribute__((aligned(4))) uint8_t MMU_US_Data_Memo  详情 回复 发表于 2019-1-24 18:02


回复

使用道具 举报

254

TA的帖子

2

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-1-23 17:13 | 显示全部楼层
顺序不一样时有时硬件未初始化就先进入某个中断当然死机了。

点评

严重同意  详情 回复 发表于 2019-1-23 17:52
我的理解顺序不一样,只是编译的时候顺序不同,但是最终链接的hex或者bin文件应该没差别才对。按您说的硬件未初始化这个说法不太合适,比如写代码时,谁也不会刻意把初始化的文件放在最上面吧。  详情 回复 发表于 2019-1-23 17:21


回复

使用道具 举报

6948

TA的帖子

193

TA的资源

五彩晶圆(高级)

Rank: 9Rank: 9Rank: 9

测评达人

发表于 2019-1-23 17:16 | 显示全部楼层
具体例子拿出来看看呢

点评

工程太大了,也不适合发出来,所以只是描述一下问题表象,看大家有没有思路提供  详情 回复 发表于 2019-1-23 17:22


回复

使用道具 举报

53

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-23 17:21 | 显示全部楼层
wenyangzeng 发表于 2019-1-23 17:13
顺序不一样时有时硬件未初始化就先进入某个中断当然死机了。

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

点评

我觉得跟文件顺序无关,因为编译的时候编译器会自动把个个函数按照程序流程编译,最主要的原因可能是有个函数出了问题,而之前运行的时候,没有运行到这个函数,所以问题没有暴露,  详情 回复 发表于 2019-1-23 22:34


回复

使用道具 举报

53

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-23 17:22 | 显示全部楼层
常见泽1 发表于 2019-1-23 17:16
具体例子拿出来看看呢

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

点评

就是把工程里的 C文件调了顺序?  详情 回复 发表于 2019-1-23 17:25


回复

使用道具 举报

6948

TA的帖子

193

TA的资源

五彩晶圆(高级)

Rank: 9Rank: 9Rank: 9

测评达人

发表于 2019-1-23 17:25 | 显示全部楼层
wjroy11 发表于 2019-1-23 17:22
工程太大了,也不适合发出来,所以只是描述一下问题表象,看大家有没有思路提供

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

点评

对,就是工程里两个文件调换一下顺序,编译也能通过,只是运行时,调换后的工程就Hardfault。我用的c++,调换的是两个cpp文件。  详情 回复 发表于 2019-1-23 17:27


回复

使用道具 举报

53

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-23 17:27 | 显示全部楼层
常见泽1 发表于 2019-1-23 17:25
就是把工程里的 C文件调了顺序?

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


回复

使用道具 举报

53

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-23 17:29 | 显示全部楼层
另外一个论坛里找到一个类似的情况,跟我遇到的很像,不知道是不是同一个问题,我在研究一下。连接这个
  http://bbs.21ic.com/icview-1197474-1-1.html


回复

使用道具 举报

1万

TA的帖子

15

TA的资源

版主

Rank: 6Rank: 6

发表于 2019-1-23 17:52 | 显示全部楼层
wenyangzeng 发表于 2019-1-23 17:13
顺序不一样时有时硬件未初始化就先进入某个中断当然死机了。

严重同意
http://shop34182318.taobao.com/


回复

使用道具 举报

7324

TA的帖子

4951

TA的资源

博客管理员

Rank: 6Rank: 6

资源大师勋章

发表于 2019-1-23 22:34 | 显示全部楼层
wjroy11 发表于 2019-1-23 17:21
我的理解顺序不一样,只是编译的时候顺序不同,但是最终链接的hex或者bin文件应该没差别才对。按您说的硬 ...

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

点评

工程用了很久也没发现有什么大的bug,所以感觉应该不会存在某个函数运行不到的情况  详情 回复 发表于 2019-1-24 09:12


回复

使用道具 举报

1536

TA的帖子

1

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

发表于 2019-1-24 00:10 | 显示全部楼层
AB两个文件里面有什么全局的东西是一样的?是AB两个文件交换才出问题,还是任意两个文件交换都会出问题?

点评

只是AB两文件交换才有问题,其他文件没影响  详情 回复 发表于 2019-1-24 09:11
人已离开,无事别找,找也找不到。


回复

使用道具 举报

53

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-24 09:11 | 显示全部楼层
freebsder 发表于 2019-1-24 00:10
AB两个文件里面有什么全局的东西是一样的?是AB两个文件交换才出问题,还是任意两个文件交换都会出问题?

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

点评

可以的话可以把这两个文件发来看看。  详情 回复 发表于 2019-1-24 09:21


回复

使用道具 举报

53

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

 楼主| 发表于 2019-1-24 09:12 | 显示全部楼层
tiankai001 发表于 2019-1-23 22:34
我觉得跟文件顺序无关,因为编译的时候编译器会自动把个个函数按照程序流程编译,最主要的原因可能是有个 ...

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


回复

使用道具 举报

1536

TA的帖子

1

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

发表于 2019-1-24 09:21 | 显示全部楼层
wjroy11 发表于 2019-1-24 09:11
只是AB两文件交换才有问题,其他文件没影响

可以的话可以把这两个文件发来看看。
人已离开,无事别找,找也找不到。


回复

使用道具 举报

1318

TA的帖子

4

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

发表于 2019-1-24 09:27 | 显示全部楼层
C++的话,可能涉及到构造函数的执行顺序吧。。构造函数的执行顺序不同,硬件初始化的就有先后了。。

比如全局的对象,初始化对象的时候,调用的构造函数顺序可能会不一样的。。

可以最先初始化一个串口,用来跟踪每个对象的构造函数调用情况,就知道顺序有没有差异了。。

评分

1

查看全部评分

坐而言不如起而行


回复

使用道具 举报

1318

TA的帖子

4

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

发表于 2019-1-24 09:33 | 显示全部楼层
单纯说现象,不一定一下子就定位到,具体和工程,代码有关,,

提供不了,大家就只有一个思路了,你自己去看看,,

很大可能就是和构造函数执行顺序有关了,,这个需要你自己判断两个文件用到对象是不是需要保证一定的顺序,

点评

嗯,非常感谢提供这么多的思路,我根据大家的意见再自己调试一下,  详情 回复 发表于 2019-1-24 10:03
感觉你的分析很合理  详情 回复 发表于 2019-1-24 09:40
坐而言不如起而行


回复

使用道具 举报

7324

TA的帖子

4951

TA的资源

博客管理员

Rank: 6Rank: 6

资源大师勋章

发表于 2019-1-24 09:40 | 显示全部楼层
wsmysyn 发表于 2019-1-24 09:33
单纯说现象,不一定一下子就定位到,具体和工程,代码有关,,

提供不了,大家就只有一个思路了,你自己 ...

感觉你的分析很合理

点评

他说的这个问题我之前遇到类似的。。 刚看的时候,感觉C语言的可能行不大,觉得应该是C++。下边他确实说的是C++ 我之前搞过一次,类代码不变,对象初始化的位置不一样,会有问题。  详情 回复 发表于 2019-1-24 09:51


回复

使用道具 举报

237

TA的帖子

1

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2019-1-24 09:45 | 显示全部楼层
有没有clean了后再编译试试

点评

这个试过,没有用。  详情 回复 发表于 2019-1-24 11:40
模电临时工


回复

使用道具 举报

1318

TA的帖子

4

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

发表于 2019-1-24 09:51 | 显示全部楼层
tiankai001 发表于 2019-1-24 09:40
感觉你的分析很合理

他说的这个问题我之前遇到类似的。。

刚看的时候,感觉C语言的可能行不大,觉得应该是C++。下边他确实说的是C++

我之前搞过一次,类代码不变,对象初始化的位置不一样,会有问题。

点评

感谢,基本定位问题是字节对齐的事情。还有几个疑问看能否帮忙解答下: 找到问题原因了,是字节对齐的问题。 工程里定义了两个比较大的数组,如下:__attribute__((aligned(4))) uint8_t MMU_US_Data_Memo  详情 回复 发表于 2019-1-24 18:04
坐而言不如起而行


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2019-2-23 01:23 , Processed in 0.515307 second(s), 16 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表