新闻中心

EEPW首页>嵌入式系统>设计应用> ARM微处理器的编程模型之:异常中断处理

ARM微处理器的编程模型之:异常中断处理

作者: 时间:2013-09-13 来源:网络 收藏

本文引用地址://m.amcfsurvey.com/article/257085.htm

有些情况下,系统0x0地址不一定是ROM。如果0x0地址为RAM,那么就系统将中断向量表从ROM复制RAM,下面的例子显示了这样一个过程。

MOV R8, #0

ADR R9, Vector_Init_Block

LDMIA R9!,{r0-r7} ;复制中断向量表 (8 words)

STMIA R8!,{r0-r7}

LDMIA R9!,{r0-r7} ;复制由伪操作 DCD定义的地址

STMIA R8!,{r0-r7}

注意

可以使用Scatter文件定义加载向量表的地址,这样上述代码的拷贝工作由C库函数完成。

2.使用C语言安装异常处理程序

程序中有时需要在main()函数中使用C语言安装中断向量表。这就要求指令经编译后的解码能安装在内存的正确位置。

(1)向量表中使用跳转指令的情况

如果在向量表中使用跳转指令,使用下面的步骤完成向量表的安装。

① 读取异常处理程序的地址。

② 从异常处理程序地址中减去向量表中的偏移。

③ 为适应指令流水线,将上一步得到的地址减8。

④ 将得到的结果右移2位,得到以字为单位的地址偏移量。

⑤ 将结果的高8位清零,得到跳转指令的24位偏移量。

⑥ 将上一步得到的结果和0xea000000(无条件跳转指令编码)做逻辑与操作,从而得到要写到向量表中的跳转指令的正确编码。

下面的例子显示了这样一个标准过程。

unsigned Install_Handler (unsigned routine, unsigned *vector)

{ unsigned vec, oldvec;

vec = ((routine - (unsigned)vector - 0x8)>>2);

if ((vec 0xFF000000))

{

/* diagnose the fault */

prinf (Installation of Handler failed);

exit (1);

}

vec = 0xEA000000 | vec;

oldvec = *vector;

*vector = vec;

return (oldvec);

}

(2)在向量表中使用加载PC指令

在向量表中使用加载PC指令,按照下面的步骤完成。

① 读取异常处理程序地址。

② 从异常处理程序地址中减去向量表中的偏移。

③ 为适应指令流水线,将上一步得到的地址减8。

④ 保留结果的后12位。

⑤ 将结果与0xe59ff000(LDR PC, [PC,#offset])做逻辑或操作,从而得到要写到向量表中的跳转指令的正确编码。

⑥ 将异常处理程序的地址放到相应的存储单元。

下面的例子显示了一个标准的C语言过程。

unsigned Install_Handler (unsigned location, unsigned *vector)

{ unsigned vec, oldvec;

vec = ((unsigned)location - (unsigned)vector - 0x8) | 0xe59ff000;

oldvec = *vector;

*vector = vec;

return (oldvec);

}

3.4.7 FIQ和IRQ中断处理函数的设计

1.中断分支

内核只有两个外部中断输入信号nFIQ和nIRQ。但对于一个系统来说,中断源可能多达几十个。为此,在系统集成的时候,一般都会有一个异常控制器来处理异常信号,如图3.8所示。

图3.8 中断系统

这时候用户程序可能存在多个IRQ/FIQ的中断处理函数。为了使从向量表开始的跳转始终能找到正确的处理函数入口,需要设置一套处理机制和方法。

多数情况下是由软件来处理异常分支的,因为软件可以通过读取中断控制器来获得中断源的信息,如图3.9所示。

有些芯片可能支持特殊的硬件分支功能,这需要查看具体的芯片说明。

因为软件的灵活性,可以设计出比图3.9更好的流程控制方法,如图3.10所示。

Int_vector_table是用户自己开辟的一块存储器空间,里面按次序存放异常处理函数的地址。IRQ_Handler()从中断控制器获取中断源信息,然后再从Int_vector_table中的对应地址单元得到异常处理函数的入口地址,完成一次异常响应的跳转。这种方法的好处是用户程序在运行过程中,能够很方便地动态改变异常服务内容。

图3.9 软件控制中断分支

图3.10 灵活的软件分支设计

进入异常处理程序后,用户可以完全按照自己的意愿来进行程序设计,包括调用Thumb状态的函数等。但对于绝大多数的系统来说,有两个步骤必须处理,一是现场保护,二是要把中断控制器中对应的中断状态标识清除,表明该中断请求已经得到响应,否则,中断函数退出以后,又会被再一次触发,从而进入周而复始的死循环。



评论


相关推荐

技术专区

关闭