Arm memcpy()文件名为M4
我正在为STM32F4控制器(Cortex M4)开发一些软件。 前几天,我将我的代码移植到一个新的硬件平台,从而在“STM32系统工作台”IDE中创建了一个新项目 当我尝试运行新项目时,发现memcpy()导致UsageFault,这是由32位宽的加载/存储访问不均匀地址引起的 然后,我发现旧的工作代码与“-specs=nano”关联,而崩溃代码则不是,因此问题可以很容易解决。我检查了memcpy()的反汇编,发现Nano库实际上有一个与标准(?)libc非常不同的实现 然而,我很困惑!为什么memcpy()的实现不支持字节对齐的地址?这将是一个相当小的错误。一定还有更多吗?!有人知道吗 当我尝试运行新项目时,发现memcpy()导致UsageFault,这是由32位宽的加载/存储访问不均匀地址引起的 您确定它是32位访问而不是64位访问(LDRD/STD指令)吗?前者应该不会在Cortex-M4上崩溃,除非MCU被明确设置为这样做 所有Armv7-M(包括除Cortex-M0之外的所有Cortex-M)都支持具有奇数内存地址的LDR和STR指令。默认情况下,只有64位变体LDRD/STD在未对准时崩溃 不幸的是,当未对齐时,FPU加载和存储也会在-M4F上崩溃。这让我在移植旧的8位东西时遇到了几次麻烦 为什么memcpy()的实现不支持字节对齐的地址 现代GCC可以使用内置的Arm memcpy()文件名为M4,arm,memcpy,libc,cortex-m,Arm,Memcpy,Libc,Cortex M,我正在为STM32F4控制器(Cortex M4)开发一些软件。 前几天,我将我的代码移植到一个新的硬件平台,从而在“STM32系统工作台”IDE中创建了一个新项目 当我尝试运行新项目时,发现memcpy()导致UsageFault,这是由32位宽的加载/存储访问不均匀地址引起的 然后,我发现旧的工作代码与“-specs=nano”关联,而崩溃代码则不是,因此问题可以很容易解决。我检查了memcpy()的反汇编,发现Nano库实际上有一个与标准(?)libc非常不同的实现 然而,我很困惑!为什么
memcpy()
,特别是固定的传输大小和指向大于一个字节的类型的指针(比如uint32*
或float*
)。Nanomemcpy()
您还可以尝试将指针强制转换回字节大小的类型:
uint32_t *pa,*pb;
memcpy((uint8_t*)pa,(uint8_t*)pb, MEMCPY_SIZE);
这将提示编译器不要使用alignmnent敏感的内置函数
当我尝试运行新项目时,发现memcpy()导致UsageFault,这是由32位宽的加载/存储访问不均匀地址引起的
您确定它是32位访问而不是64位访问(LDRD/STD指令)吗?前者应该不会在Cortex-M4上崩溃,除非MCU被明确设置为这样做
所有Armv7-M(包括除Cortex-M0之外的所有Cortex-M)都支持具有奇数内存地址的LDR和STR指令。默认情况下,只有64位变体LDRD/STD在未对准时崩溃
不幸的是,当未对齐时,FPU加载和存储也会在-M4F上崩溃。这让我在移植旧的8位东西时遇到了几次麻烦
为什么memcpy()的实现不支持字节对齐的地址
现代GCC可以使用内置的memcpy()
,特别是固定的传输大小和指向大于一个字节的类型的指针(比如uint32*
或float*
)。Nanomemcpy()
您还可以尝试将指针强制转换回字节大小的类型:
uint32_t *pa,*pb;
memcpy((uint8_t*)pa,(uint8_t*)pb, MEMCPY_SIZE);
这将提示编译器不要使用alignmnent敏感的内置程序。非常感谢您的回复。恐怕是我自己的错。我确实启用了不结盟陷阱,并完全忘记了它。。。我还忘了你可以关闭不对齐检查。当我读到“除非MCU被明确设置为这样做”,我感到好奇和。。。好。。。发现了我自己的代码。再次感谢。LDM
和STM
也需要对齐的地址,这些和LDRD
和STRD
将导致cortex M4出现使用故障。非常感谢您的回复。恐怕是我自己的错。我确实启用了不结盟陷阱,并完全忘记了它。。。我还忘了你可以关闭不对齐检查。当我读到“除非MCU被明确设置为这样做”,我感到好奇和。。。好。。。发现了我自己的代码。再次感谢。LDM
和STM
也需要对齐的地址,这些和LDRD
和STRD
将导致cortex M4出现使用故障。