我使用IAR编译例程,但在ARM A7上运行错误;当我打开IAR生成的 .lst 文件时,我得到了以下问题。
它是ISR
,第一个push {r3, r4, r5, lr}
,但POP {r0, r4, r5, lr}
返回时,R0
值在推送前更改为R3
的值。因此R0
从irqHandler
返回时出错,导致后续例程出错。
为什么?
void irqHandler(void)
{
878: e92d4038 push {r3, r4, r5, lr}
volatile u32 *pt = (u32 *)AM_INTC_BASE;
87c: e3a044b0 mov r4, #176, 8 ; 0xb0000000
u32 id_spin;
id_spin = *(pt+0x200c/4) & 0x3ff;
880: e302000c movw r0, #8204 ; 0x200c
884: e7900004 ldr r0, [r0, r4]
888: e1b00b00 lsls r0, r0, #22
88c: e1b00b20 lsrs r0, r0, #22
890: e1b05000 movs r5, r0
if(id_spin<32)
894: e3550020 cmp r5, #32
898: 2a000000 bcs 8a0 <irqHandler+0x28>
{
#ifdef WHOLECHIPSIM
print("id_spid<32 error...\r\n",0);
#endif
while(1);
89c: eafffffe b 89c <irqHandler+0x24>
}
else
{
(pFuncIrq[id_spin-32])();
8a0: e59f0010 ldr r0, [pc, #16] ; 8b8 <.text_8>
8a4: e1b01105 lsls r1, r5, #2
8a8: e0910000 adds r0, r1, r0
8ac: e5100080 ldr r0, [r0, #-128] ; 0x80
8b0: e12fff30 blx r0
}
}
8b4: e8bd8031 pop {r0, r4, r5, pc}
答案 0 :(得分:0)
当硬件调用中断向量例程时,R0-R3,R12,LR,PC,xPSR自动保存在堆栈中无关紧要。调用bx
,ldm
,pop
或ldr
并调用PC
时,硬件执行中断例程退出弹出这些寄存器。
不要检查您的编译器。它知道它的作用。检查错误的逻辑 - 特别是在中断处理程序中打印字符串。
答案 1 :(得分:0)
abi需要一个64位对齐的堆栈,因此r3的推送简单地促进了这一点。可以选择任何尚未指定的寄存器。同样在pop上他们需要清理堆栈,函数原型为void,所以返回(r0)是不关心的,r0-r3不会被保留,所以没有理由匹配每一端的r3也不匹配每端都是r0。
如果他们在推送时选择了编号高于r3(例如r6)的寄存器,则需要在pop上进行匹配。否则,pop必须是r0-r3之一才能不丢弃非易失性寄存器。 (无法推动r3然后弹出r6会破坏r6)答案 2 :(得分:0)
使用关键字__irq __arm汇编代码如下:
__irq __arm void irqHandler(void)
{
878: e24ee004 sub lr, lr, #4
87c: e92d503f push {r0, r1, r2, r3, r4, r5, ip, lr}
volatile u32 *pt = (u32 *)AM_INTC_BASE;
880: e3a044b0 mov r4, #176, 8 ; 0xb0000000
u32 id_spin;
id_spin = *(pt+0x200c/4) & 0x3ff;
884: e302000c movw r0, #8204 ; 0x200c
888: e7900004 ldr r0, [r0, r4]
88c: e1b00b00 lsls r0, r0, #22
890: e1b00b20 lsrs r0, r0, #22
894: e1b05000 movs r5, r0
if(id_spin<32)
898: e3550020 cmp r5, #32
89c: 2a000000 bcs 8a4 <irqHandler+0x2c>
{
#ifdef WHOLECHIPSIM
print("id_spid<32 error...\r\n",0);
#endif
while(1);
8a0: eafffffe b 8a0 <irqHandler+0x28>
}
else
{
(pFuncIrq[id_spin-32])();
8a4: e59f0010 ldr r0, [pc, #16] ; 8bc <.text_8>
8a8: e1b01105 lsls r1, r5, #2
8ac: e0910000 adds r0, r1, r0
8b0: e5100080 ldr r0, [r0, #-128] ; 0x80
8b4: e12fff30 blx r0
}
}
8b8: e8fd903f ldm sp!, {r0, r1, r2, r3, r4, r5, ip, pc}^
答案 3 :(得分:0)
Cortex A7 PUSH日志,它只需按7个寄存器,所以32位对齐就好了
关注链接是日志信息: