CortexM0 +来自LDRH指令的故障

时间:2014-02-09 15:41:30

标签: c gcc embedded fault cortex-m

我有一个在M3架构上运行良好的代码库,并将一些代码移植到M0 +。我遇到了错误,我无法弄明白为什么。我所使用的确切微型是KL36Z128(飞思卡尔)。我正在使用ARM-GCC-2013-Q3发布我的工具链。

所以这里是C代码(它用于解析数据包,因为一旦我获得足够的数据,我就开始挑选我需要填写的命令结构):

state-> cmd = *((U16 *)& din [15]); //代码库具有“遗留”类型定义

生成的程序集是:

0x4250< + 0x0014>添加r1,#15

0x4252< + 0x0016> ldrh r1,[r1,#0]< ---错误指令!

0x4254< + 0x0018> strh r1,[r0,#2]

故障发生时的寄存器值为:

r0 = 0x1ffff2cc r1 = 0x1ffffad8

我不知道这里发生了什么 - 这看起来非常简单。寻址似乎没问题。飞思卡尔数据表说,RAM存储有2个部分:

SRAM_L:(0x20000000-1KB)到0x20000000(因此它的下半部分是总SRAM的1/4)

SRAM_H:0x20000000到(0x20000000 + 3KB)

我原本以为可能有些东西在生成代码时会出错,而且可以使用哪些指令来访问不同银行的内存 - 但我空洞了。

此外,'din'值在函数参数列表中定义为:const U8 * din

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

state->cmd = *((U16*)&din[15]);

*操作执行未对齐的访问,因为din[15]元素的类型为uint8_t,但是作为uint16_t(或U16)对象进行访问。 Cortex-M0 / M0 +不支持未对齐访问,任何执行未对齐访问的尝试都会引发HardFault。

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/BABFAIGG.html

要修复您的计划,请将din个元素作为uint8_t个对象访问:

 state->cmd = (din[16] << 8) | din[15];