微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 异常中断处理程序

异常中断处理程序

时间:11-21 来源:互联网 点击:
6.2.1 异常中断处理程序的方法种类及其介绍

1.SWI 异常中断处理程序的实现

在 SWI 指令中包括一个 24 位的立即数,该立即数指示了用户请求的特定的 SWI 功能。在

SWI 异常中断处理程序要读取该 24 位的立即数,这涉及到 SWI异常模式下对寄存器 LR的读

取,并且要从存储器读取该 SWI 指令。这样需要使用汇编程序来实现。通常 SWI异常中断处

理程序分为两级:第 1 级 SWI 异常中断处理程序为汇编,用于确定 SWI 指令中的 24 位的立

即数;第 2级 SWI 异常中断处理程序具体实现 SWI 的各个功能,它可以是汇编程序,也可以

时 C 程序,下面我们分别介绍这两级。

● SWI 异常中断调用

① 在特权模式下调用 SWI

执行 SWI 指令后,系统将会把 CPSR 寄存器的内容保存到寄存器 SPSR_SVC 中,

将返回地址保存到寄存器 LR_svc 中。这样如果执行 SWI 指令时,系统已经处于

特权模式下,这时寄存器 SPSR_svc 和寄存器 LR_svc 中的内容就会被破坏。因

此如果在特权模式下调用 SWI 功能,比如在一个 SWI 异常中断处理程序中执行

SWI指令,就必须将原始的寄存器SPSR_svc和寄存器LR_svc值保存在数据栈中。

程序6.1说明在SWI中断处理程序中如何保存寄存器SPSR_svc和寄存器LR_svc

值。

程序 6.1 在SWI 中断处理程序中保存寄存器 SPSR_svc 和寄存器 LR_svc 值

;保存寄存器,包括寄存器 lr_svc

STMFD sp!(r0-r3,r12,lr)

;保存 SPSR_svc

MOV r1,sp

MRS r0,spsr

STMFD sp!,(r0)

;读取SWI指令

LDR r0,(lr,#4)

;计算其中的 24 位立即数,并将其放入寄存器 R0 中

BIC r0,r0.#0xff000000

;调用C_SWI_Handler 完成相应的 SWI 功能

BL C_SWI_Handler

;恢复SPSR_svc 的值

LDMFD sp!,(r0)

MSB spsr_cf,r0

;恢复其他寄存器,包括寄存器 LR_svc

LDMFD sp!,(r0-r3,r12,pc)^

② 从应用程序中调用 SWI

这里分两种情况考虑从应用程序中调用特定的 SWI 功能:一种考虑使用汇编指

令调用特定的 SWI 功能;一种考虑从 C 语言程序中调用特定的 SWI 功能。

使用汇编指令调用特定的 SWI 功能比较简单,将需要的参数按照 ATPCS 的要求

放在相应的寄存器中,然后在指令 SWI 中指定相应 24 位立即数即可。下面的例

子中,SWI 中断处理程序需要的参数放在寄存器 R0 中,这里该参数为 100,然

后调用功能号为 0x0 的SWI 功能调用。

MOV R0,#100

SWI 0x0

从 C 语言程序中调用特定的 SWI 功能比较复杂,因为这时需要将一个 C 程序的

子程序调用映射到一个 SWI 异常中断处理程序。这些被映射的 C 语言子程序使

用编译器伪操作__SWI 来声明。如果该子程序需要的参数和返回的结果只使用寄

存器 R0~R3,则该 SWI 可以被编译成 inline 的,不需要使用子程序调用过程。

否则必须告诉编译器通过结构数据类型来返回参数,这时需要使用编译器伪操

作_value_in_reg 声明该C 语言子程序。

下面通过一个完整的例子来说明如何从 C 程序中调用特定的 SWI 功能,该例子

是 ARM 公司的 ADS1.2 中所带的。该例子提供的 4 个SWI 功能调用,功能号分别

为 0x0,0x1,0x2,0x3。其中 SWI 0x0及 SWI 0x1 使用两个整形的输入参数,并返

回一个结果值,SWI 0x2使用 4 个输入参数,并返回一个结果值;SWI 0x3 使用

4 个输入参数,并返回 4个结果值。

整个 SWI 异常中断处理程序分为两级结构。第 1 级的 SWI 异常中断处理程序是

汇编程序 SWI_HANDLER,它读取 SWI 指令中的 24 位立即数,然后调用第 2 个级

SWI 异常中断处理程序 C_SWI_HANDLER来实现具体的 SWI 功能。第 2 级SWI异常

中谷底你处理程序 C_SWI_HANDLER 为 C 语言程序。其中实现了功能号分别为

0x0,0x1,0x2,0x3的 SWI功能调用。

主程序中的子程序 multiply_two()对应着 SWI 0x0;add_two()对应着

0x1;add_multiply_two()对应着 0x2;many_operations()对应着 SWI 0x3。

Many_operations()返回 4 个结果,使用编译器伪操作_valuc_in_reg 声明。4

个子程序都使用编译器伪操作__SWI来声明。主程序使用 lnstall_Handler()来

安装该 SWI异常中断处理程序,lnstall_Handler()在前面已经有详细的介绍。

整个代码如程序 6.2 所示。

程序 6.2 从C 程序中调用特定的 SWI功能

__swi(0) int multiply_two (int,int);

__swi(1) int add_two (int,int);

__swi(2) int add_multiply_two (int ,int ,int ,int );

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top