【发布时间】:2016-12-18 09:02:56
【问题描述】:
大家好,我的 cortex m1 在同一个地方多次出现 HardFault 异常。我有 HardFault 实现,我可以读取堆栈寄存器:
stacked_r0 unsigned int 0x4(十六进制)
堆叠 r1 无符号整数 0x60905f98(十六进制)
堆叠 r2 无符号整数 0x0(十六进制)
堆叠 r3 无符号整数 0x6092304b(十六进制)
stack_r12 unsigned int 0x60922ff8(十六进制)
stack_lr unsigned int 0x60810be3(十六进制)
stack_pc unsigned int 0x60810ce2(十六进制)
stack_psr unsigned int 0x41000000(十六进制)
在堆叠 PC 上的操作是: 60810ce2:ldrsh r2,[r3,r2]
为什么会导致故障?
更新 我已经重新排列了变量,现在它已经在从 freertos 代码调用的 memcpy 中崩溃了
stacked_r0 unsigned int 0x6090c858(十六进制)
堆叠 r1 无符号整数 0x6091f8b4(十六进制)
堆叠 r2 无符号整数 0x3c(十六进制)
堆叠 r3 无符号整数 0x6091f8a4(十六进制)
堆叠 r12 无符号整数 0x280(十六进制)
stack_lr unsigned int 0x60827f89(十六进制)
stack_pc unsigned int 0x6082b0dc(十六进制)
stack_psr unsigned int 0x1000000 (十六进制)
6082b0ba: bne.n 0x6082b120
6082b0bc:添加 r5、r2、#0
6082b0be: 添加 r4, r0, #0
6082b0c0: subs r5, #16
6082b0c2: lsrs r5, r5, #4
6082b0c4:添加 r5,#1
6082b0c6: lsls r5, r5, #4
6082b0c8:添加 r1、r1、r5
6082b0ca: ldr r6, [r3, #0]
6082b0cc: str r6, [r4, #0]
6082b0ce: ldr r6, [r3, #4]
6082b0d0: str r6, [r4, #4]
6082b0d2: ldr r6, [r3, #8]
6082b0d4: str r6, [r4, #8]
6082b0d6: ldr r6, [r3, #12]
6082b0d8:添加 r3,#16
6082b0da: str r6, [r4, #12]
6082b0dc:添加 r4,#16
【问题讨论】:
-
这是一个未对齐的访问。
-
好的,但是为什么呢? r3 指向堆栈
-
堆栈是 ram,堆栈与它有什么关系 ldrsh 或 ldrh 的低位为 0xB 或 1011 ldr 的低位必须为零,低两位必须为零ldrd 后三个必须为零。您正在尝试进行未对齐的半字访问,而处理器正确地阻止了您这样做。
-
正确。我正在使用 freertos 和 GCC。看起来它生成的代码不会将堆栈地址操作 8 个字节?
-
如果您想了解编译器正在做什么,您必须提供一个简单的示例函数、编译器和选项,以及输出并从那里开始。不知道为什么 gcc 会使用 r3 或 r2 来访问堆栈,加载与堆栈的对齐无关。