0%

一种在 ARM968E-S 上重定向中断向量表的方法

ARM968E-S 架构非常古老,不支持中断向量重定向,所以此功能需要用户自己在代码中实现,也即在固定的中断向量函数内跳转到 RAM 那的用户向量地址。

由于此架构不会在中断时自动保存寄存器,所以必须由用户手动把寄存器入栈出栈。但是从 RAM 中取值需要用到寄存器 Rn,把这个值赋给 PC 也需要寄存器 Rn,所以就无法避免的会修改到 Rn 的值。

之前的做法是在进 boot 中断后先把 Rn 入栈,跳转到 APP 中断后再把 Rn 出栈,但这样用户的中断处理程序就比较奇怪(一开始就要把 Rn 出栈)并且不注意就容易出错。

1
2
3
4
5
6
7
8
9
10
11
12
// Bootloader
boot_iqr:
PUSH {R0}
LDR R0,=0x400018
LDR R0, [R0]
LDR PC, R0

//Application
app_irq:
POP {R0}
user process

其实给 PC 赋值除了LDR PC, Rn之外,还可以使用 POP 指令POP {PC}把栈内的值弹到 PC 中来变相实现跳转。

先把中断地址从 RAM 中 LOAD 到当前栈内,并把 SP 递增,然后使用POP {PC}来跳转。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Bootloader
boot_iqr:
SUB SP, SP, #4
PUSH {R0}
LDR R0, = 0x400018
LDR R0, [R0]
ADD SP, SP, #8
PUSH {R0}
SUB SP, SP, #4
POP {R0}
POP {PC}

//Application
app_irq:
user process

流程图如下

坚持原创技术分享,您的支持将鼓励我继续创作!