我有一个在M3架构上运行良好的代码库,正在将一些代码移植到M0+。我有毛病,我不知道为什么。我使用的是KL36Z128(自由刻度)。我正在为我的工具链使用ARM-GCC-2013-Q3版本。
这是C代码(它用于在数据包进入时对其进行解析,因此一旦获得足够的数据,我就开始挑选需要填写的命令结构):
state->cmd=*((U16*)&din[15]);//codebase有“legacy”类型定义
生成的程序集是:
0x4250添加r1,#15
0x4252ldrh r1,[r1,#0]0x4254右侧r1,[r0,#2]
故障发生时的寄存器值为:
r0=0x1fff2cc
r1=0x1fffad8
我不知道这里发生了什么-这似乎是非常简单的组装。地址看起来还可以。Freescale的数据表显示RAM有两个部分:
SRAM_L:(0x20000000-1KB)到0x20000000(所以它的下段是整个SRAM的1/4)
SRAM U H:0x20000000至(0x20000000+3KB)
我原本以为可能是代码生成出了问题,什么指令可以用来访问不同银行的内存,但是我发现了一个空的。
此外,“din”值在函数参数列表中定义为:const U8*din
有什么想法吗?

最佳答案

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

*操作执行未对齐的访问,因为din[15]元素属于uint8_t类型,但作为uint16_t(或U16)对象访问。Cortex-M0/M0+不支持未对齐访问,任何尝试执行未对齐访问都会引发硬故障。
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/BABFAIGG.html
要修复程序,请将din元素访问为uint8_t对象:
 state->cmd = (din[16] << 8) | din[15];

07-27 20:06