memcpy() crashes Cortex M4



我正在为STM32F4控制器(Cortex M4(开发一些软件。 前几天,我将代码移植到一个新的硬件平台,从而在"STM32系统工作台"IDE中创建了一个新项目。

当我尝试运行新项目时,我发现 memcpy(( 导致 UsageFault,这是由 32 位宽的加载/存储访问不均匀的地址引起的。

然后我发现旧的工作代码已经与"-specs=nano"链接,而崩溃的代码没有,所以这个问题可以很容易地解决。我检查了 memcpy(( 的反汇编,发现 Nano 库实际上与标准 (?( libc 的实现非常不同。

不过,我很困惑!为什么 memcpy(( 的实现不支持字节对齐的地址?这将是一个相当微不足道的错误。还得更多吧?!有人知道吗?

当我尝试运行新项目时,我发现 memcpy(( 导致 UsageFault,这是由 32 位宽的 Load/Store 访问不均匀的地址引起的。

您确定它是 32 位访问而不是 64 位访问(LDRD/STRD 指令(吗?前者根本不应该在Cortex-M4上崩溃,除非MCU明确设置这样做。

所有 Armv7-M(包括所有 Cortex-M 但 Cortex-M0(都支持具有奇数内存地址的 LDR 和 STR 指令。默认情况下,只有 64 位变体 LDRD/STRD 在未对齐时崩溃。

不幸的是,当未对齐时,FPU的负载和存储也会在-M4F上崩溃。这让我在移植旧的 8 位东西时有几次。

为什么 memcpy(( 的实现不支持字节对齐的地址?

现代GCC可以使用内置的memcpy(),特别是固定的传输大小和指向大于一个字节的类型(例如uint32_t*float*(的指针。Nanomemcpy()是一个最小的实现,可以逐字节缓慢复制。

您也可以尝试将指针转换回字节大小的类型:

uint32_t *pa,*pb;
memcpy((uint8_t*)pa,(uint8_t*)pb, MEMCPY_SIZE);

这应该提示编译器不使用对齐敏感的内置。

最新更新