完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在移植一个某个程序时,以前平台(arm Cortex-M3)运行得很好的程序,突然到新的平台(arm Cortex-M7)突然出现hard fault 了 FPU active! usage fault: SCB_CFSR_UFSR:0x100 UNALIGNED 这种错误,我通过cpu pc寄存器值和map文件定位到了在 memcpy 函数中,猜测应该是复制数据时地址未对齐引起的。 我开始以为 memcpy 就是 rt_memcpy ,所以把 rt_memcpy 函数的4字节对齐复制变成单字节复制,发现问题依然存在。 然后我通过搜索map文件发现,很多软件包并没有使用rt_memcpy ,而是使用编译器提供的 memcpy 。即使 我通过下面这样的代码,想把memcpy重定向到 rt_memcpy依然没有丝毫效果。 void *memset(void *src, int c, size_t n) { return rt_memset(src, c, n); } void *memcpy(void *dest, const void *src, size_t n) { return rt_memcpy(dest, src, n); } 然后我在map文件中发现一些函数,部分map文件内容 ntp.o(i.ntp_get_time) refers to rt_memcpy_w.o(.text) for __aeabi_memcpy4 ntp.o(i.ntp_get_time) refers to rt_memclr_w.o(.text) for __aeabi_memclr4 rt_memcpy_v6.o(.text) refers to rt_memcpy_w.o(.text) for __aeabi_memcpy4 rt_memmove_v6.o(.text) refers to rt_memcpy_v6.o(.text) for __aeabi_memcpy rt_memmove_v6.o(.text) refers to rt_memmove_w.o(.text) for __memmove_aligned aeabi_memset.o(.text) refers to rt_memclr.o(.text) for _memset rt_memclr.o(.text) refers to rt_memclr_w.o(.text) for _memset_w strncpy.o(.text) refers to rt_memclr.o(.text) for __aeabi_memclr 我才发现原来memcpy并不是直接使用调用的,编译器还分了单字节复制和4字节复制的方式 rt_memcpy_v6 rt_memcpy_w aeabi_memcpy aeabi_memcpy4 然后我再次重新定义 void __aeabi_memcpy(void *dest, const void *src, size_t n) { rt_memcpy(dest, src, n); } void __aeabi_memcpy4(void *dest, const void *src, size_t n) { rt_memcpy(dest, src, n); } 再一编译发现问题消失了。 也有查找网上资料说 使用 #pragma pack(1) 将变量设置成单字节对齐,这样使用memcpy时就会调用__aeabi_memcpy4而是使用 __aeabi_memcpy函数 不知道大家有没有更好的办法,能使memcpy完全使用rt_memcpy |
|
相关推荐
4个回答
|
|
千万别乱用memcpy,这玩意是上来就四字节拷贝的,不判断内存对齐,平时没啥事,一旦死机哭都没有地方哭。rt_memcpy 是安全的。 可以用全局宏来进行替换
|
|
|
|
没有太好的办法。
为了性能,编译器提供的方案稍微激进了一些,本来是没问题的,只要不任意强转就不会有事。(这本身就是错误的用法) 但是有些代码违规强转,就会引发异常。 比如void*你强转成int *,编译器就认为你是4字节对齐了,就可以使用更高效的对齐拷贝。 如果你转成double,就更不得了,直接就使用多字拷贝了。 毕竟性能有几十倍的差距。 或是外扩的RAM并不支持非对齐访问,或是多字连续访问。也会出现问题。 常见的有MCU级别的外扩SDRAM,很多不支持多字访问。 SPI接口的PSRAM映射的外扩内存也是重灾区。 都不用行不行?程序员觉得可以,BOSS说不行,比如同样的芯片跑UI,别人跑几十帧,你跑几帧,你选择哪个呢? 但问题又客观存在。 如果想稳妥,只能像你这样修改。 或是对目标地址对齐,或是地址范围,做个判断。 我的想法是, 通用的API还是不必全部修改。总归改不完。 然后默认可以把工具链相对激进的memcpy优化给拦截掉。 有性能要求的项目,可以根据源地址和目标地址是否对齐,以及本项目芯片外扩RAM是否支持对齐多字访问。自动调用不同的实现。 |
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
788 浏览 0 评论
4271 浏览 0 评论
如何使用python调起UDE STK5.2进行下载自动化下载呢?
2529 浏览 0 评论
开启全新AI时代 智能嵌入式系统快速发展——“第六届国产嵌入式操作系统技术与产业发展论坛”圆满结束
2929 浏览 0 评论
获奖公布!2024 RT-Thread全球巡回线下培训火热来袭!报名提问有奖!
31479 浏览 11 评论
72920 浏览 21 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 16:04 , Processed in 0.513526 second(s), Total 48, Slave 41 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号