嵌入式技术论坛
直播中

张伟

8年用户 1728经验值
私信 关注
[问答]

怎样去解决memcpy aeabi_memcpy aeabi_memcpy4问题呢?

在移植一个某个程序时,以前平台(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

回帖(3)

王伟

2023-2-8 11:20:59
要想把memcpy替换成rt_memcpy可以尝试下在GCC链接阶段动手脚。
举报

刘满贵

2023-2-8 11:21:10
千万别乱用memcpy,这玩意是上来就四字节拷贝的,不判断内存对齐,平时没啥事,一旦死机哭都没有地方哭。rt_memcpy 是安全的。 可以用全局宏来进行替换
举报

张伟

2023-2-8 11:21:17
可是有些软件包并没有使用rt_memcpy ,没办法通过全局宏定义替换。我发现lwip里面都有 直接使用 memcpy的例子。所以感觉我直接重写 __aeabi_memcpy4函数比较好些,但是不知道这个办法在gcc上有没有用
举报

更多回帖

发帖
×
20
完善资料,
赚取积分