已阅读5页,还剩92页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章 ARM异常中断处理及编程,7.1 ARM异常中断处理概述 7.2 ARM体系异常中断种类 7.3 ARM应用系统中异常中断处理程序的安装 7.4 ARM的SWI异常中断处理程序设计 7.5 FIG和IRQ异常中断程序设计 7.6 基于ARM9芯片S3C2410异常中断程序设计,第7章 ARM异常中断处理及编程,本章的主要内容: ARM异常中断处理概述 异常中断的进入与退出 应用程序中异常中断处理程序的安装 SWI异常中断处理程序 FIQ和IRQ异常中断处理程序 复位异常中断处理程序 未定义异常中断 指令预取中止异常中断处理程序 数据访问中止异常中断处理程序,第7章 ARM异常中断处理及编程,7.1 ARM异常中断处理概述 ARM异常中断处理需要实现中断的响应、解析跳转和返回等操 作,以便支持上层应用程序的开发。 当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执行。 当异常中断处理程序执行完成后,程序返回到发生中断的指令的下一条指令处执行。 进入异常中断处理程序时,要保存被中断的程序的执行现 场。从异常中断处理程序退出时,要恢复被中断的程序的执行现场。 ARM体系中常在存储地址的低端固化了一个32字节的硬件中断向量表,用来指定各异常中断及其处理程序的对应关系。,第7章 ARM异常中断处理及编程,当一个异常出现后,ARM微处理器执行以下操作: (1)保存处理器当前状态、中断屏蔽位以及各条件标志位; (2)设置当前程序状态寄存器CPSR中相应的位; (3)将寄存器lr_mode设置成返回地址; (4)将程序计数器(PC)值设置成该异常中断的中断向量地址,从而跳转到相应的异常中断处理程序处执行。 接收到中断请求后,ARM处理器内核会自动执行以上四步,程序计数器PC总是跳转到相应的固定地址。 从异常中断处理程序中返回: (1)恢复被屏蔽的程序的处理器状态; (2)返回到发生异常中断的指令的下一条指令处继续执行。 当异常中断发生时,程序计数器PC所指的位置对于各种不同的异常中断是不同的,同样,返回地址对于各种不同的异常中断也是不同的。,第7章 ARM异常中断处理及编程,7.2 ARM体系异常中断种类 ARM处理器中主要有7个异常(2个中断异常) 复位(RESET) 未定义的指令 软件中断 指令与取终止(PrefechAbort) 数据访问终止(DATAABORT) 外部中断请求(IRQ) 快速中断请求(FIQ),第7章 ARM异常中断处理及编程,7.2.1异常中断向量表及异常中断优先级 在ARM体系中,异常中断向量表的大小为32字节,每异常中断占4个字节。 每个异常中断对应的中断向量表中的4个字节的空间中存放了一条跳转指令或者一条向PC寄存器中赋值的数据访问指令。,第7章 ARM异常中断处理及编程,第7章 ARM异常中断处理及编程,1复位异常 在以ARM为核的系统中,引起复位的原因有: 上电复位 复位引脚上的复位脉冲 对系统电源检测发现过压或欠压。 时钟异常复位。 ARM处理器复位后,将进行以下操作: 强制进入管理模式; 强制进入ARM状态; 跳转到绝对地址PC=0x00000000处执行; 禁止IRQ中断和FIQ中断。,第7章 ARM异常中断处理及编程,复位后,程序状态寄存器如下:,上电复位后,进入管理模式,执行操作系统程序,一般用做对系统初始化,例如开中断等;然后切换到用户模式,开始执行正常的用户程序。,第7章 ARM异常中断处理及编程,切换到用户模式可使用下列程序: MRS R0,CPSR ;读状态寄存器 BIC R0,R0,#03 ;把末两位清0 MSR CPRS_c,R0 ;把修改后的值加载给 ;状态寄存器,切换结束 ;用户程序,第7章 ARM异常中断处理及编程,2未定义指令异常 ARM的未定义指令异常有以下两种情况: (1)遇到一条没有定义指令; (2)执行一条对协处理器的操作指令没有应答。 未定义异常中断时,状态寄存器中的F位不变。 使用下列指令退出异常中断,返回原程序 。 把下一条指令的地址拷贝给LR; 把程序状态寄存器CPSR拷贝给SPSR_und; 强制进入未定义模式; 强制进入到ARM模式; 跳转到绝对地址PC=0x00000004处执行; 禁止IRQ中断。,第7章 ARM异常中断处理及编程,进入中断后,程序状态寄存器如下:,未定义异常中断返回时,使用下列指令返回到原中断处: MOVS PC,R14.,第7章 ARM异常中断处理及编程,3软件中断异常 是由指令SWI引起的。程序在执行这一指令后,进入异常中断。处理器响应中断,硬件执行如下的操作: 把下一条指令的地址拷贝给LR; 把程序状态寄存器CPSR拷贝给SPSR_svc; 强制进入管理模式; 强制进入到ARM状态; 跳转到绝对地址PC=0x00000008处执行; 禁止IRQ中断。,第7章 ARM异常中断处理及编程,进入中断后的程序状态寄存器如下:,软件中断处理程序完成后,使用下列指令返回到原中断处: MOVS PC,R14,第7章 ARM异常中断处理及编程,4预取指中止异常 程序存储器引起的中止异常叫做预取指中止异常;数据存储器引起的中止异常叫做数据中止异常。 有两种可能如下: 当执行这条指令前程序发生跳转,则这条无效指令不引起异常中断; 当执行到这条指令时,处理器会发生预取指中止异常,引起中断。,第7章 ARM异常中断处理及编程,当进入预取指异常中断时,处理器硬件响应中断,执行以下的操作: 把中断时PC的地址拷贝给LR; 把程序状态寄存器CPSR拷贝给SPSR_abt; 强制进入中止异常模式; 强制进入到ARM状态; 跳转到绝对地址PC=0x0000000C处执行; 禁止IRQ中断。,第7章 ARM异常中断处理及编程,进入中断后,程序状态寄存器如下:,预取指中止异常中断返回时,应该执行下列指令: SUBS PC,R14,#4.,第7章 ARM异常中断处理及编程,5数据中止异常 ARM处理器访问数据存储器时,在读取数据的同时数据存储器发出了中止信号,引起数据中止异常。 数据中止异常中断服务程序返回时,用下列指令: SUBS PC,R14,#8 上述指令是返回到中断时所执行的指令,目的是再一次从数据存储器中读取数据。如果不再一次读取数据,则执行下一条指令,此时使用下列指令返回: SUBS PC,R14,#4,第7章 ARM异常中断处理及编程,当进入数据中止异常中断时,处理器硬件响应中断,执行以下的操作: 把中断时的PC的地址拷贝给LR; 把程序状态寄存器CPSR拷贝给SPSR_abt; 强制进入中止异常模式; 强制进入到ARM状态; 跳转到绝对地址PC=0x00000010处执行; 禁止IRQ中断。,第7章 ARM异常中断处理及编程,进入中断后,程序状态寄存器如下:,第7章 ARM异常中断处理及编程,6中断请求(IRQ)异常 当I=1时。则屏蔽IRQ中断,当I=0时,则允许中断。处理器复位后置I为1,关闭中断。 ARM系统中外设通过该异常中断请求处理服务。 例如:定时器中断、串行口通讯中断、外部信号中断和A/D处理中断等。IRQ中断是可屏蔽的。在状态寄存器中的I位就是IRQ的屏蔽位。,第7章 ARM异常中断处理及编程,当发生IRQ中断时,处理器硬件响应中断,执行下列操作: 把中断时的PC的地址值拷贝给LR; 把程序状态寄存器CPSR拷贝给SPSR_irq; 强制进入IRQ异常模式; 强制进入到ARM状态; 跳转到绝对地址PC=0x00000018处执行; 禁止IRQ中断。,第7章 ARM异常中断处理及编程,进入中断后,程序状态寄存器如下:,完成中断处理后,程序执行下列返回原中断处: SUBS PC.R14,#4.,第7章 ARM异常中断处理及编程,7.2.2 支持中断跳转的解析程序 (1)解析程序的概念和作用 中断解析程序是为了使得上层应用程序与硬件中断跳转联系起来所编写一段中间的服务程序。 中断跳转流程图如图7.1所示。,第7章 ARM异常中断处理及编程,(2)解析过程 以一次IRQ跳转为例说明解析过程,假定中断向量表定义在0x00400000开始的外部RAM空间,中断解析示例流程如图7.2 所示。 图中实线表示的流程都用ARM汇编语言编写,一般作为boot代码的一部分放在系统的底层模块中。填写向量表的操作可以在上层应用程序中方便地实现,比如在C语言中: *( int *(0x00400018) = (int) ISR_IRQ;这样就将IRQ中断的服务程序入口地址(0x00300260)填写到中断向量表中的固定地址0x00400018开始的4字节空间了。 这样就可避免在应用程序中计算中断的跳转地址,并可很方便的选择不同的函数作为指定中断的服务程序。当然,在程序开发时要合理开辟好向量表,避免对向量表地址空间不必要的写操作。,第7章 ARM异常中断处理及编程,第7章 ARM异常中断处理及编程,(3)解析程序的扩展 在ARM处理器中会包含很多中断源,通常会在ARM内核外面扩展一个中断控制器来管理各种原因产生的中断。 如,三星公司的S3C4510B处理器中的IRQ/FIQ类型的中断源可以有21个 S3C44B0X有26个。 解析程序的扩展处理流程可用图7.3表示。,7.3 中断解析的扩展处理流程,第7章 ARM异常中断处理及编程,7.3 中断解析的扩展处理流程,第7章 ARM异常中断处理及编程,(4) 向量中断的处理 在设计外部扩展的中断控制器时提供了一种叫做“向量中断”的中断跳转机制。与前面叙述的扩展解析跳转流程有所不同,它不需要软件来识别具体的中断源,也就是不需要添加图7.3中的IRQ/FIQ服务程序,而完全由硬件自动跳转到对应的中断地址。其它跳转流程的原理都是一样的。这相当于扩展了ARM内核的硬件中断向量表,减小了中断响应延时。以S3C2410X处理器的外部中断0为例,需要在其对应的硬件固定跳转地址0x00000020处添加指令: ldr pc,=HandlerEINT,使得程序跳转到其服务程序HandlerEINT0处执行。向量中断的处理如图7.4所示。,第7章 ARM异常中断处理及编程,图7.4 向量中断的处理,第7章 ARM异常中断处理及编程,7.3 中断解析的扩展处理流程,7.3 ARM应用系统中异常中断处理程序的安装 在ARM应用程序中安装异常中断处理程序通常有下列两种方法。 使用跳转指令:可以在异常中断对应异常向量表中特定位置放置一条跳转指令,直接跳转到该异常中断的处理程序。但只能在32M空间范围内跳转。 使用数据读取指令LDR:使用数据读取指令LDR向程序计数器PC中直接赋值。这种方法分为两步:先将异常中断处理程序的绝对地址存放在距离向量表4KB范围内的一个存储单元中;再使用数据读取指令LDR将该单元的内容读取到程序计数器PC中。,第7章 ARM异常中断处理及编程,7.3 中断解析的扩展处理流程,7.3.1 在系统复位时安装异常中断处理程序 1地址0x00处为ROM的情况 当地址0x0处为ROM时: 在异常中断向量表中,可以使用数据读取指令LDR直接向程序计数器PC中赋值,也可以直接使用跳转指令跳转到异常中断处理程序。,第7章 ARM异常中断处理及编程,使用数据读取指令LDR的示例如下所示: Vector_Init_Block LDR PC, Reset_Addr LDR PC, Undefined_Addr LDR PC, SW_Addr LDR PC, Prefeth_Addr LDR PC, Abort_Addr NOP LDR PC, IRQ_Addr LDR PC, FIQ_Addr Reset_Addr DCD Start_Boot,第7章 ARM异常中断处理及编程,Undefined_Addr DCD Undefined_Handle SW_Addr DCD SWI_Handle Prefeth_Addr DCD Prefeth_Handle Abort_Addr DCD Abort_Handle DCD 0 IRQ_Addr DCD IRQ_Handle FIQ_Addr DCD FIQ_Handle,第7章 ARM异常中断处理及编程,使用跳转指令的示例如下所示: Vector_Init_Block BL Reset_Handle BL Undefined_Handle BL SWI_Handle BL Prefeth_Handle BL Abort_Handle NOP BL IRQ_Handle BL FIQ_Handle,第7章 ARM异常中断处理及编程,2. 地址0x00处为RAM的情况 当地址0x0处为RAM时,中断向量表必须使用数据读取指令直接指向PC中赋值的形式。而且,必须使用下面的代码把中断向量表从ROM中复制到RAM的地址0x00开始处的存储空间中。中断向量表从ROM中复制到RAM的,代码段如下: MOV r8,#0 ADR r9,Vector_Init_Block ;复制中断向量表(8字) LDMIA r9!,r0-r7 STMIA r8!,r0-r7 ;复制保存各中断处理函数地址的表(8 words) LDMIA r9!,r0-r7 STMIA r8!,r0-r7,第7章 ARM异常中断处理及编程,7.3.2 在C程序中安装异常中断处理程序 安装异常中断处理程序的方法。 1中断向量表中使用跳转指令的情况 当中断向量表中使用跳转指令时,在C 程序中安装异常中断处理程序的操作如下: (1)读取中断处理程序的地址。 (2)从上一步得到的地址中减去该异常中断对应的中断向量的地址。 (3)从上一步得到的地址中减去8,以允许指令预取。 (4)将上一步得到的地址右移 2位,得到以字(32位)为单位的偏移量。 (5)确保上一步得到的地址值高8位为0,因为跳转指令只允许24位的偏移量。 (6)将上一步得到的地址与数据0xea00 0000作逻辑或,从而得到将要写到中断向量表中的跳转指令的编码。,第7章 ARM异常中断处理及编程,例7.1 使用跳转指令的中断向量表 unsigned Install_Handler (unsigned routine, unsigned *vector) /*在中断向量表中vector处,添上合适的跳转指令*/ /*该跳转指令跳转到中断处理程序routine处。*/ /*程序返回原来的中断向量*/ unsigned vec, oldvec;,vec = (routine (unsigned)vector 0x8) 2); if (vec ,第7章 ARM异常中断处理及编程,2中断向量表中使用数据读取指令的情况 当中断向量表中使用数据读取指令时,在C 程序中安装异常中断处理程序的操作过程如下: (1)读取中断处理程序的地址。 (2)从上一步得到的地址中减去该异常中断对应的中断向量的地址。 (3)从上一步得到地址中减去8,以允许指令预取。 (4)将上一步得到地址与数据0xe59f f000作逻辑或,从而得到将要写到中断向量表中的数据读取指令的编码。 (5)将中断处理程序的地址放到相应的存储单元。,第7章 ARM异常中断处理及编程,例7.2 使用数据读取指令的中断向量表 unsigned Install_Handler (unsigned location, unsigned *vector) /*在中断向量表中vector处,添上合适的指令LDR pc, pc , #offset */ /*该指令跳转的目标地址存放在存储单元location中 */ /*函数返回原来的中断向量*/ unsigned vec, oldvec; vec = (unsigned)location (unsigned)vector 0x8) | 0xe59ff000 ; oldvec = * vector; *vector =vec ; return (oldvec); ,第7章 ARM异常中断处理及编程,用下面的语句调用例7.2的函数,实现用C语言程序完成中断处理程序的安装。 unsigned *irqvec = (unsigned *)0x18 ; Install_Handler (unsigned ) IRQHandler, irqvec ) ;,第7章 ARM异常中断处理及编程,7.4 ARM的SWI异常中断处理程序设计 通过SWI异常中断指令,用户模式下应用程序可以调用系统模式下的代码。在实时操作系统中,通常使用SWI异常中断为用户应用程序提供系统功能调用。 7.4.1 SWI异常中断处理程序的实现 在SWI指令中包括一个24位的立即数(中断调用号),该立即数指示了用户要请求的特定的调用功能,所以在SWI的异常中断中要读取这个中断调用号,然后根据中断号,来调用相应的处理程序。这个过程可以分两步:第1步是SWI中断处理程序为汇编,用于确定SWI指令中的24位的立即数;第2步是SWI异常中断处理的功能服务程序,是具体实现SWI的各个功能,它即可用汇编语言,也可用C语言编程。,第7章 ARM异常中断处理及编程,1. 第1步用汇编语言编写的SWI异常中断处理程序 由于是在底层操作,所以这个异常中断处理程序得用汇编语言编写,例7.3所示的SWI异常中断处理程序中的bl swi_service_func指令是调用第2步的SWI异常中断处理的功能服务程序,此函数是用于实现SWI的各个功能。,第7章 ARM异常中断处理及编程,例7.3 汇编语言编写的第1步SWI异常中断处理程序 area top_swi code readonly export swi_headler swi_headler stmfd sp!, r0-r12, lr ; 保存r0至r12,lr的寄存器值 ldr r0, lr, #-4 ; 从存储器中取得SWI指令的所在地址 bic r0, r0, #FF000000 ; 读取24位中断调用号 mov r1, sp ;= bl swi_service_func ; 调用功能服务函数,见下面 ; 中断调用号通过r0寄存器传入 ; 参数通过r1寄存器传入 ;= ldmfd sp!, r0-r12, pc ;恢复调用前r0至r12,退出 end,第7章 ARM异常中断处理及编程,2. SWI异常中断处理的中断服务程序 为了具体实现SWI的各个功能,需编写SWI异常中断处理的功能服务程序,它即可用汇编语言,也可用C语言编程。例7.4是用汇编语言编写的SWI异常中断处理的中断服务程序,例7.5是用C语言编写的SWI异常中断处理的中断服务程序。,第7章 ARM异常中断处理及编程,例7.4 汇编语言编写的SWI异常中断处理程序 area toplevelswi code readonly export swi_headler swi_headler stmfd sp!, r0-r12, lr;保存r0至r12,lr的寄存器值 ldr r0, lr, #-4 ; 从存储器中取得SWI指令的所在地址 bic r0, r0, #FF000000 ; 读取24位中断调用号 mov r1, sp ;判断立即数是否有效 cmp R0,#MaxOfSWI;判R0中数是否有效超过允许的最大值 ldrls pc,pc,r0,lsl #2 b OutOfSWIRange ;超出范围 JumpListofSWI ;SWI的跳转表 dcd SWIPro_0;SWI对应立即数0的中断处理程序入口地址 dcd SWIPro_1 ;SWI对应立即数1的中断处理程序入口地址,第7章 ARM异常中断处理及编程,;其他所有的软中断入口 SWIPro_0 ;进入SWI对应立即数0的中断处理程序 ;对应立即数0 的中断处理程序 b EndOfSWI SWIPro1 ;进入SWI对应立即数1的中断处理程序 ;对应立即数1 的中断处理程序 b EndOfSWI ;其他的SWI 处理程序 EndOfSWI ;结束SWI 中断处理程序 ldmfd sp!, r0-r12, pc ;恢复调用前的r0至r12,退出中断程序 end,第7章 ARM异常中断处理及编程,例7.5 用C语言编写的第2步SWI异常中断处理的中断服务程序 用C语言编写的第2步SWI异常中断处理的中断服务程序的函数原形如下: void swi_service_func(unsigned int number, unsigned int *reg) 其中:参数number是SWI的中断调用号,是利用从中断处理函数获得的中断调用号;参数reg是SWI异常中断第1步(例7.3)中断处理程序传递来的数据栈指针。在第1步的SWI异常中断处理程序调用第2步中断处理程序的操作如下所示: 设置C程序将使用的第二个参数,根据ATPCS第个参数保存在寄存器R1中,第7章 ARM异常中断处理及编程,mov r1, spbl swi_service_func ; 调用功能服务函数,见下面 ; 中断调用号通过r0寄存器传入 ; 参数通过r1寄存器传入 第2步SWI异常中断处理的中断服务程序代码如下: void swi_service_func(unsigned int number, unsigned int *reg) unsigned int reg1, reg2, reg3, reg4; /获取SWI前传入的参数 reg1 = reg0; reg2 = reg1; reg3 = reg2; reg4 = reg3;,第7章 ARM异常中断处理及编程,switch (number) case 0: / do something break; case 1: / do something break; case n: / do something break; default: / do something ,第7章 ARM异常中断处理及编程,/ 更新结果存入r0-r3 reg0 = updata_reg1; reg1 = updata_reg2; reg2 = updata_reg3; reg3 = updata_reg4; ,第7章 ARM异常中断处理及编程,7.4.2 SWI异常中断调用 1在特权模式下调用SWI 执行SWI指令后,系统将会把CPSR寄存器的内容保存到寄存器SPSR_svc中,将返回地址保存到寄存器LR_svc中。这样如果在执行SWI指令时,系统已经处于特权模式下,这时寄存器SPSR_svc和寄存器LR_svc中的内容就会被破坏。因此如果在特权模式下调用SWI功能(即执行SWI指令),比如在一个SWI异常中断处理程序中执行SWI指令,就必须将原始的寄存器SPSR_svc和寄存器LR_svc值保存在数据栈中。,第7章 ARM异常中断处理及编程,例如 7.6 在SWI中断程序处理程序中保存寄存器SPSR_svc和寄存器LR_svc值 area top_swi code readonly export swi_headler swi_headler stmfd sp!, r0-r3,12, lr ; 保存r0至r3,r12,lr的寄存器值 ;保存SPSR_svc mov r1,sp MRS r0,spsr stmfd sp!, r0 ;读取SWI指令 ldr r0, lr, #-4 ; 从存储器中取得SWI指令的所在地址 bic r0, r0, #FF000000 ; 读取24位中断调用号,并存入寄存器r0中,第7章 ARM异常中断处理及编程,;= bl swi_service_func ; 调用功能服务函数, ;见下面中断调用号通过r0寄存器 ;传入参数通过r1寄存器传入 ;= ldmfd sp!, r0 ;恢复调用前的r0 MSR spsr_cf,r0 ldmfd sp!, r0-r3,r12, pc ;恢复调用前的r0至r12,离开中断处理程序 end,第7章 ARM异常中断处理及编程,2. 从应用程序中调用SWI 可分两种情况从应用程序中调用特定的SWI功能:其一是使用汇编指令调用;其二是用C程序调用。 汇编指令调用特定的SWI功能只要将所需要的参数按ATPCS的要求放置在相应的寄存器中,然后在指令SWI中指定相应24位立即数(即待调用的SWI功能号)即可。,第7章 ARM异常中断处理及编程,例如7.7 下面的例子是用汇编指令实现SWI的调用。SWI中断处理程序所需的参数放在寄存器R0中,然后调用功能号为0x0的SWI功能调用。 MOV R0, #100 SWI 0x0,第7章 ARM异常中断处理及编程,例如7.8 下面是ARM公司的ADS 1.2中自带的一个完整的用C语言程序调用特定的SWI功能的例子,例子中提供了4个SWI功能调用,功能号分别为0x0、0x1、0x2和0x3。其中SWI 0x0和SWI 0x1使用两个整型的输入参数,并返回一个结果值;SWI 0x2使用4个输入参数,并返回一个结果值;SWI 0x3使用4个输入参数,并返回4个结果值。,第7章 ARM异常中断处理及编程,从C 程序中调用特定的SWI功能程序代码如下: /* 头文件swi.h */ _swi(0) int multiply_two(int, int); _swi(1) int add_two(int, int); _swi(2) int add_multiply_two(int, int, int, int); struct four_results int a; int b; int c; int d; ; _swi(3) _value_in_regs struct four_results many_operations(int, int, int, int);,第7章 ARM异常中断处理及编程,/* 主程序 main( ) */ #include #include “swi.h” unsigned *swi_vec = (unsigned *)0x08; extern void SWI_Handler(void); / *使用Install_Handler()安装SWI异常中断处理程序 */ unsigned Install_Handler (unsigned routine, unsigned *vector ) unsigned vec, old_vec; vec=(routine (unsigned)vector -8) 2; if (vec ,第7章 ARM异常中断处理及编程,vec = 0xea000000 | vec ; old_vec =* vector; *vector = vec; return (old_vec); int main(void) int result1 ,result2 ; struct four_results res_3 ; Install_Handler( (unsigned) SWI_Handler, swi_vec); printf (“result1 = multiply_two( 2, 4) = %dn”, result1=multiply_two(2,4); printf (“result2 = multiply_two( 3, 6) = %dn”,第7章 ARM异常中断处理及编程,result2=multiply_two(3,6); printf (“add_two(result1,result2) = %dn”, add_two(result1,result2); printf (“add_multiply_two(2,4,3,6) = %dn”, add_ multiply_two(2,4,3,6); res_3=many_operations( 12,4,3,1 ); printf (“ res_3.a = %dn”, res_3.a ); printf (“ res_3.b = %dn”, res_3.b ); printf (“ res_3.c = %dn”, res_3.c ); printf (“ res_3.d = %dn”, res_3.d ); return 0; ,第7章 ARM异常中断处理及编程,;第1步SWI异常中断处理程序SWI_Handler AREA SWI_Area, CODE, READONLY EXPORT C_SWI_Handler T_bit EQU 0x20 SWI_Handler STMFD sp!,r0-r3, r12, lr MOV r1,sp MRS r0,spsr STMFD sp!, r0 TST r0, #T_bit LDRNEH r0, lr,#-2 BICEN r0, r0, #0xff00 LDREQ r0, lr,#-4,第7章 ARM异常中断处理及编程,BICEQ r0, r0, #0xff000000 BL C_SWI_Handler LDMFD sp!, r0 MSR spsr_cf, r0 LDMFD sp!, r0, r3, r12, pc END ;第2步SWI异常中断处理程序void C_SWI_Handler( ) void C_SWI_Handler ( ) switch (swi_num) ,第7章 ARM异常中断处理及编程,case 0; /对应于SWI 0x0 regs0= regs0 * regs1; break; case 1; /对应于SWI 0x1 regs0= regs0 + regs1; break; case 2; /对应于SWI 0x2 regs0= (regs0 * regs1 ) + (regs2 * regs3 ); break; case 3; /对应于SWI 0x3 int w, x, y, z ;,第7章 ARM异常中断处理及编程,w = regs0 ; x = regs1 ; y = regs2 ; z = regs3 ; regs0 = w + x + y + z; regs1 = w - x - y - z; regs2 = w * x * y * z; regs3 = (w+ x) * ( y z) ; break ; ,第7章 ARM异常中断处理及编程,3. 从应用程序中动态调用SWI 动态调用SWI是指在应用程序的运行时调用SWI的功能号。有两种方法实现动态调用SWI功能号。 方法1:在运行时得到SWI功能号,然后构造出相应的SWI指令的编码,把这个指令的编码保存在某个存储单元中,执行该指令即可。 方法2:用一个通用的SWI异常中断处理程序,将运行时需要调用的SWI功能号作为参数传递给该通用的SWI异常中断处理程序。通用的SWI异常中断处理程序根据参数值调用相应的SWI处理程序完成需要操作。,第7章 ARM异常中断处理及编程,在汇编程序中常用第2种方法。在执行SWI指令之前先将需要调用的SWI功能号放在某个寄存器(R0R12都可以使用),在通用的SWI异常中断程序读取该寄存器值,决定需要执行的操作,但有些SWI处理程序需要SWI指令中的24位立即数,因而上述两种方法常常组合使用。 在操作系统中通常使用一个SWI功能号和一个寄存器来提供很多的SWI功能调用,这样可以将其他的SWI功能号留给用户使用。,第7章 ARM异常中断处理及编程,例7.9 在ARM体系中semihost的实现的一个实例,ARM程序使用SWI 0x123456来实现semihost功能调用;Thumb程序使用SWI 0xAB来实现semihost功能调用。此例中将子程序WRITEC(unsigned op, char *c )映射到somehost功能调用,具体semihost SWI的子功能号通过参数op传递。,第7章 ARM异常中断处理及编程,7.5 FIG和IRQ异常中断程序设计 IRQ和FIQ是ARM处理器的两种编程模式。IRQ是指中断模式,FIR是指快速中断模式。IRQ 可以被 FIQ 所中断,但 IRQ 不能中断 FIQ。为了使 FIQ 更快,所以这种模式有更多的影子寄存器。FIQ 不能调用 SWI(软件中断)。FIQ 还必须禁用中断。如果一个 FIQ 例程必须重新启用中断,则它太慢了,并应该是 IRQ 而不是 FIQ。 设置IRQ/FIQ中断,若是IRQ中断则可以设置为向量中断并分配中断优先级,否则为非向量IRQ。然后可以设置中断允许,以及向量中断对应地址或非向量中断默认地址。当有中断后,若是IRQ中断,则可以读取向量地址寄存器,然后跳转到相应的代码。当要退出中断时,对向量地址寄存器写0,通知VIC(中断向量控制器)中断结束。当发生中断时,处理器将会切换处理器模式,同时相关的寄存器也将会映射。,第7章 ARM异常中断处理及编程,IRQ(外部中断请求):当处理器的外部中断请求引脚有效,且CPSR中的I位为0时,产生IRQ异常。系统的外设可以该异常请求中断服务(异常向量:0x0000,0018); FIQ(快速中断请求):当处理器的快速中断请求引脚有效,且CPSR中的F位为0时,产生FIQ异常(异常向量:0x0000,001C)。 使用外部中断应注意把某个引脚设置为外部中断功能后,该引脚为输入模式,由于没有内部上拉电阻,所以必须外接一个上拉电阻,确保引脚不被悬空; 除了引脚连接模块的设置,还需要设置VIC模块,才能产生外部中断,否则外部中断只能反映在EXTINT寄存器中; 要使器件进入掉电模式并通过外部中断唤醒,软件应该正确设置引脚的外部中断功能,再进入掉电模式。,第7章 ARM异常中断处理及编程,7.5.1 IRQ和FIQ异常中断处理程序 1不可重入的IRQ/FIQ异常中断处理程序 在C语言中,不可重入的IRQ/FIQ异常中断处理程序可以使用关键词_irq来说明。关键词_irq可以实现下面的操作: 保存APCS规定的被破坏的寄存器。 保存其他中断处理程序中用到的寄存器。 同时将(LR-4)赋给程序计数器PC实现中断处理程序的返回,并且恢复CPSR寄存器的内容。 当IRQ/FIQ异常中断处理程序调用了子程序时,关键词_irq可以使IRQ/FIQ异常中断处理程序返回时从其数据栈中读取LR_irq值,并通过 SUBS PC,LR,#4;实现返回。,第7章 ARM异常中断处理及编程,例7.10的程序中说明了关键词_irq的作用。在例中的两个C语言程序中,第1个使用了关键词_irq的声明,第2个没有使用关键词_irq的声明。 例7.10 关键词_irq的作用 /* 第1个程序使用关键词_irq声明 */ _irq void IRQHandler (void) volatile unsigned int *base = (unsigned int *) 0x80000000; if (*base = 1) C_int_handler ( ); /调用相应的C语言处理程序 *(base+1) = 0; /清除中断标志 ,第7章 ARM异常中断处理及编程,;第1个C语言程序对应的汇编程序 IRQHandler PROC STMFD sp!,r0-r4.r12,lr MOV r4,#0x80000000 LDR r0,r4,#0 SUB sp,sp,#4 CMP r0,#1 BLEQ C_int_handler MOV r0,#0 STR r0,r4,#4 ADD sp,sp,#4 LDMFD sp!,r0-r4,r12,lr SUBS pc,lr,#4 ENDP,第7章 ARM异常中断处理及编程,EXPORT IRQHandler /* 第2个程序没有使用关键词_irq声明 */ irq void IRQHandler (void) volatile unsigned int *base = (unsigned int *) 0x80000000; if (*base = 1) C_int_handler ( ); /调用相应的C语言处理程序 *(base+1) = 0; /清除中断标志 ,第7章 ARM异常中断处理及编程,;第1个C语言程序对应的汇编程序 IRQHandler PROC STMFD sp!,r4.lr MOV r4,#0x80000000 LDR r0,r4,#0 CMP r0,#1 BLEQ C_int_handler MOV r0,#0 STR r0,r4,#4 LDMFD sp!,r4,pc ENDP,第7章 ARM异常中断处理及编程,2可重入的IRQ/FIQ异常中断处理程序 在可重入的IRQ/FIQ异常中断处理程序中调用子程序,子程序的返回地址是保存在寄存器LR_irq中,若这时又发生了IRQ/FIQ异常中断,则这个寄存器LR_irq中的值将会被破坏,那么被调用的子程序将不能正确返回。因此,对于可重入IRQ/FIQ异常中断处理程序需要做一些特殊的操作。,第7章 ARM异常中断处理及编程,第1步中断处理程序需完成下列操作(注:这一级不能用C语言编程): 将返回地址保存到IRQ的数据栈中。 保存工作寄存器和SPSR_irq。 清除中断标志。 将处理器切换到系统模式,重新使能(IRQ/FIQ)。 保存用户模式LR寄存器和被调用者不保存的寄存器。 调用C语言IRQ/FIQ异常中断处理程序。 当C语言的IRQ/FIQ异常中断处理程序返回后,恢复用户模式的寄存器,并禁止中断(IRQ/FIQ)。 切换到IRQ模式,禁止中断。 恢复工组寄存器和寄存器LR_irq。 从IRQ异常中断处理程序中返回。,第7章 ARM异常中断处理及编程,例7.11 可重入的IRQ/FIQ异常中断处理程序 AREA INTERRUPT,CODE,READONLY IMPORT C_irq_handler ;引入C语言的IRQ中断处理程序C_irq_handler IRQ SUB lr,lr,#4 STMFD sp!,lr ;保存返回IRQ处理程序地址 MRS r14,SPSR STMFD sp!,r12,r14 ;保存SPSR_irq,及其他工作寄存器,第7章 ARM异常中断处理及编程,; 在这里添加指令,清除中断标志位 ;添加指令重新使能中断 MSR CPSR_c,#0x1F ;切换到系统模式,并使能中断 STMFD sp!,r0-r3,lr ;保存用户模式的LR_usr及被调用者不保存的寄存器 BL C_irq_handler ;跳转到C语言的中断处理程序 LDMFD sp!,r0-r3,lr ;恢复用户模式的寄存器 MSR CPSR_c,#0x92 ;切换到IRQ模式,禁止IRQ中断,FIQ中断仍允许 LDMFD sp!,r12,r14 ;恢复工作寄存器和SPSR_irq LDMFD sp!,pc ;从IRQ处理程序返回 END,第7章 ARM异常中断处理及编程,7.5.2 多中断源的IRQ异常中断处理程序 下面通过一多中断源的IRQ异常中断处理程序来说明ARM中断的使用。例中是32个中断源,每个中断源对应一个单独的优先级值,优先级的取值范围为031。假设系统中的中断控制器的基地址为IntBase,存放中断优先级值的寄存器的偏移地址为IntLevel。寄存器R13指向一个FD类型的数据栈。 例7.12 多中断源的IRQ异常中断处理程序 SUB lr,lr,#4 STMFD sp!,lr ;保存返回IRQ处理程序地址 MRS r14,SPSR STMFD sp!,r12,r14 ;保存SPSR,及R12寄存器 MOV r12,#IntBase ;读取中断控制器的地址 LDR r12,r12,#IntLevel ;读取优先级最高的中断源的优先级值 ;使能中断,第7章 ARM异常中断处理及编程,MSR r14.CPSR BIC r14,r14,#0x80 MSR CPSR_c,r14 LDR PC,PC,r12,LSL #2 ;跳转到优先级最高的中断对应的中断处理程序 NOP ;中断处理程序地址表 DCD Priority0Handler;优先级为0的中断对应中断处理程序地址 DCD Priority1Handler;优先级为1的中断对应中断处理程序地址 DCD Priority2Handler;优先级为2的中断对应中断处理程序地址 DCD Priority3Handler ;优先级为3的中断对应中断处理程序地址 ;优先级为0的中断对应的中断处理程序 Priority0Handler STMFD sp!,r0-r11 ;保存工作寄存器,第7章 ARM异常中断处理及编程,;这里为中断程序的程序体 LDMFD sp!,r0-r11 ;恢复工作寄存器 MRS r12,CPSR ORR r12,r12 MSR CPSR_c,r12 ;禁止中断 LDMFD sp!,r12,r14 ;恢复SPSR及寄存器r12 MSR SPSR_csxf,r14;从优先级为0的中断处理程序返回 LDMFD sp!,pc ;从IRQ处理程序返回 ;优先级为1的中断对应的中断处理程序 Priority1Handler,第7章 ARM异常中断处理及编程,7.6 基于ARM9芯片S3C2410异常中断程序设计 7.6.1 异常中断响应和返回 系统运行时,异常可能会随时发生。当一个异常出现以后,ARM微处理器会执行以下几步操作: (1) 将下一条指令地址存入相应连接寄存器LR,以便程序在处理异常返回时能从正确位置重新开始执行。 (2) 将CPSR复制到相应的SPSR中。 (3) 根据异常类型,强制设置CPSR的运行模式位。 (4) 强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相应的异常处理程序处。,第7章 ARM异常中断处理及编程,异常处理完毕之后,ARM微处理器会执行以下几步操作从异常返回: (1) 将
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 服务定金协议书范本
- 代理公司续约协议书
- 柜子合同协议书范本
- 惠州市公路管理局下属事业单位2025年下半年招考工作人员易考易错模拟试题(共500题)试卷后附参考答案
- 南昌就业见习协议书
- 养蚕大棚收租协议书
- 广东清远连平县元善镇应急救援中队招录应急队员25人易考易错模拟试题(共500题)试卷后附参考答案
- 个人集资协议书模板
- 服装企业拆迁协议书
- 安阳市林州市农林畜产品质量安全检验检测中心招考专业技术人员易考易错模拟试题(共500题)试卷后附参考答案
- 水果代加工加工合同范本
- 软件基础知识培训班课件
- 2025至2030中国教育装备行业项目调研及市场前景预测评估报告
- 2025年物业项目经理竞聘考试试题及解析
- 电线路的构成及巡视课件
- 志愿服务条例知识培训课件
- 民族苗族介绍课件
- 2024年高速道路清障与协作交通顺畅人员安全技能知识试题库及答案
- 2026年中考英语作文复习话题范文以及重点句型归纳
- 2025年国家电投招聘考试(笔试)历年参考题库含答案详解(5卷)
- 2025年军队专业技能岗位文职人员招聘考试(仓储/仓库保管员)历年参考题库含答案详解(5套)
评论
0/150
提交评论