我正在为STM32F4控制器(Cortex M4)开发一些软件。 前几天,我将代码移植到新的硬件平台,从而在“ STM32的系统工作台” IDE中创建了一个新项目。
当我尝试运行新项目时,我发现memcpy()引起了UsageFault,这是由32位宽的加载/存储访问不均匀的地址引起的。
然后,我发现旧的工作代码已与“ -specs = nano”链接,而崩溃代码未链接,因此可以轻松解决此问题。我检查了memcpy()的反汇编,发现Nano库实际上具有与标准(?)libc完全不同的实现。
尽管如此,我还是很困惑!为什么memcpy()的实现不支持字节对齐的地址?那将是一个相当琐碎的错误。还有更多吗?!有人知道吗?
答案 0 :(得分:2)
当我尝试运行新项目时,我发现memcpy()引起了UsageFault,这是由32位宽的加载/存储访问不均匀的地址引起的。
您确定它是32位访问而不是64位访问(LDRD / STRD指令)吗?除非明确设置了MCU,否则前者完全不会在Cortex-M4上崩溃。
所有Armv7-M(包括除Cortex-M0以外的所有Cortex-M)都支持具有奇数存储地址的LDR和STR指令。默认情况下,只有64位变体LDRD / STRD会因未对齐而崩溃。
不幸的是,如果未对齐,FPU的加载和存储也会在-M4F上崩溃。移植旧的8位内容时,这让我几次。
为什么memcpy()的实现不支持字节对齐的地址?
现代GCC可以为memcpy()
使用内置程序,尤其是固定传输大小和指向大于一个字节的类型(例如uint32_t*
或float*
)的指针。 Nano memcpy()
是最小的实现,可以逐字节缓慢复制。
您还可以尝试将指针转换回字节大小的类型:
uint32_t *pa,*pb;
memcpy((uint8_t*)pa,(uint8_t*)pb, MEMCPY_SIZE);
这应该提示编译器不使用对齐敏感的内置程序。