我有一个在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
有什么想法吗?
答案 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];