大家好,我在同一个地方多次在我的皮层m1上有HardFault异常。我已经实现了HardFault,我可以读取堆栈寄存器:
stacked_r0 unsigned int 0x4(Hex)
stacked_r1 unsigned int 0x60905f98(Hex)
stacked_r2 unsigned int 0x0(Hex)
stacked_r3 unsigned int 0x6092304b(十六进制)
stacked_r12 unsigned int 0x60922ff8(Hex)
stacked_lr unsigned int 0x60810be3(Hex)
stacked_pc unsigned int 0x60810ce2(Hex)
stacked_psr unsigned int 0x41000000(Hex)
堆叠式PC的操作是: 60810ce2:ldrsh r2,[r3,r2]
为什么会导致错误?
UPD 我已经重新安排了变量,现在它已经从freertos代码调用的memcpy中崩溃了
stacked_r0 unsigned int 0x6090c858(Hex)
stacked_r1 unsigned int 0x6091f8b4(Hex)
stacked_r2 unsigned int 0x3c(Hex)
stacked_r3 unsigned int 0x6091f8a4(Hex)
stacked_r12 unsigned int 0x280(Hex)
stacked_lr unsigned int 0x60827f89(Hex)
stacked_pc unsigned int 0x6082b0dc(Hex)
stacked_psr unsigned int 0x1000000(Hex)
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
答案 0 :(得分:1)
使用ldrsh生成对齐的编译器的简单示例:
short more_fun ( short );
short fun ( short a )
{
unsigned int ra;
short x[16];
for(ra=0;ra<16;ra++)
{
a+=more_fun(x[ra]);
}
return(a);
}
arm-none-eabi-gcc -mthumb -O2 -c so.c -o so.o -march = armv6-m arm-none-eabi-objdump -D so.o
00000000 <fun>:
0: b570 push {r4, r5, r6, lr}
2: b088 sub sp, #32
4: 0004 movs r4, r0
6: 466d mov r5, sp
8: ae08 add r6, sp, #32
a: 2300 movs r3, #0
c: 5ee8 ldrsh r0, [r5, r3]
e: f7ff fffe bl 0 <more_fun>
12: 3502 adds r5, #2
14: 1904 adds r4, r0, r4
16: b224 sxth r4, r4
18: 42b5 cmp r5, r6
1a: d1f6 bne.n a <fun+0xa>
1c: 0020 movs r0, r4
1e: b008 add sp, #32
20: bd70 pop {r4, r5, r6, pc}
22: 46c0 nop ; (mov r8, r8)
堆栈保持对齐,堆栈操作,推送,弹出和堆栈帧都是8个字节(两个字)的倍数。
数组在堆栈上,它们使用r5作为数组的索引,看起来像ldrsh需要两个寄存器,因此它们将r3设置为零,这样它们就可以有第二个寄存器。这里的关键是它们开始对齐,sp地址至少有低三位零,假设此代码之外的每个人都符合约定。然后代码每次通过循环向r5添加2,保持指向阵列的指针在半字边界上对齐,对于每次使用ldrsh,低位对于地址保持为零。没有对齐问题。
请提供类似的例子,可能是代码片段,但肯定是未对齐的ldrsh周围的相关片段。