




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章ARM异常中断处理及编程
7.1ARM异常中断处理概述7.2ARM体系异常中断种类7.3ARM应用系统中异常中断处理程序的安装7.4ARM的SWI异常中断处理程序设计7.5FIG和IRQ异常中断程序设计7.6基于ARM9芯片S3C2410异常中断程序设计第7章ARM异常中断处理及编程7.1ARM异常中断处1第7章ARM异常中断处理及编程
本章的主要内容:●ARM异常中断处理概述●异常中断的进入与退出●应用程序中异常中断处理程序的安装●SWI异常中断处理程序●FIQ和IRQ异常中断处理程序●复位异常中断处理程序●未定义异常中断●指令预取中止异常中断处理程序●数据访问中止异常中断处理程序第7章ARM异常中断处理及编程本章的主要内容:2第7章ARM异常中断处理及编程
7.1ARM异常中断处理概述ARM异常中断处理需要实现中断的响应、解析跳转和返回等操作,以便支持上层应用程序的开发。当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执行。当异常中断处理程序执行完成后,程序返回到发生中断的指令的下一条指令处执行。进入异常中断处理程序时,要保存被中断的程序的执行现场。从异常中断处理程序退出时,要恢复被中断的程序的执行现场。ARM体系中常在存储地址的低端固化了一个32字节的硬件中断向量表,用来指定各异常中断及其处理程序的对应关系。第7章ARM异常中断处理及编程7.1ARM异常中断处3第7章ARM异常中断处理及编程
当一个异常出现后,ARM微处理器执行以下操作:
(1)保存处理器当前状态、中断屏蔽位以及各条件标志位;(2)设置当前程序状态寄存器CPSR中相应的位;(3)将寄存器lr_mode设置成返回地址;(4)将程序计数器(PC)值设置成该异常中断的中断向量地址,从而跳转到相应的异常中断处理程序处执行。接收到中断请求后,ARM处理器内核会自动执行以上四步,程序计数器PC总是跳转到相应的固定地址。
从异常中断处理程序中返回:(1)恢复被屏蔽的程序的处理器状态;(2)返回到发生异常中断的指令的下一条指令处继续执行。当异常中断发生时,程序计数器PC所指的位置对于各种不同的异常中断是不同的,同样,返回地址对于各种不同的异常中断也是不同的。第7章ARM异常中断处理及编程当一个异常出现后,ARM微4第7章ARM异常中断处理及编程
7.2ARM体系异常中断种类
ARM处理器中主要有7个异常(2个中断异常)●复位(RESET)●未定义的指令
●软件中断
●指令与取终止(PrefechAbort)
●数据访问终止(DATAABORT)
●外部中断请求(IRQ)
●快速中断请求(FIQ)
第7章ARM异常中断处理及编程7.2ARM体系异常中5第7章ARM异常中断处理及编程
7.2.1异常中断向量表及异常中断优先级
在ARM体系中,异常中断向量表的大小为32字节,每异常中断占4个字节。每个异常中断对应的中断向量表中的4个字节的空间中存放了一条跳转指令或者一条向PC寄存器中赋值的数据访问指令。第7章ARM异常中断处理及编程7.2.1异常中断向量表及6第7章ARM异常中断处理及编程
第7章ARM异常中断处理及编程7第7章ARM异常中断处理及编程
1.复位异常在以ARM为核的系统中,引起复位的原因有:
●上电复位●复位引脚上的复位脉冲●对系统电源检测发现过压或欠压。●时钟异常复位。
ARM处理器复位后,将进行以下操作:
●强制进入管理模式;●强制进入ARM状态;●跳转到绝对地址PC=0x00000000处执行;●禁止IRQ中断和FIQ中断。第7章ARM异常中断处理及编程
1.复位异常8第7章ARM异常中断处理及编程
复位后,程序状态寄存器如下:......IFTM4M3M2M1M0
11010011上电复位后,进入管理模式,执行操作系统程序,一般用做对系统初始化,例如开中断等;然后切换到用户模式,开始执行正常的用户程序。第7章ARM异常中断处理及编程复位后,程序状态寄存器如下9第7章ARM异常中断处理及编程
切换到用户模式可使用下列程序:
MRSR0,CPSR
;读状态寄存器
BICR0,R0,#03
;把末两位清0MSRCPRS_c,R0
;把修改后的值加载给;状态寄存器,切换结束
......
;用户程序第7章ARM异常中断处理及编程
切换到用户模式可使用下列10第7章ARM异常中断处理及编程
2.未定义指令异常
ARM的未定义指令异常有以下两种情况:(1)遇到一条没有定义指令;(2)执行一条对协处理器的操作指令没有应答。
未定义异常中断时,状态寄存器中的F位不变。使用下列指令退出异常中断,返回原程序。●把下一条指令的地址拷贝给LR;●把程序状态寄存器CPSR拷贝给SPSR_und;●强制进入未定义模式;●强制进入到ARM模式;●跳转到绝对地址PC=0x00000004处执行;●禁止IRQ中断。第7章ARM异常中断处理及编程
2.未定义指令异常11第7章ARM异常中断处理及编程
进入中断后,程序状态寄存器如下:......IFTM4M3M2M1M0
1x011011
未定义异常中断返回时,使用下列指令返回到原中断处:MOVSPC,R14. 第7章ARM异常中断处理及编程
进入中断后,程序状态寄12第7章ARM异常中断处理及编程
3.软件中断异常
是由指令SWI引起的。程序在执行这一指令后,进入异常中断。处理器响应中断,硬件执行如下的操作:●把下一条指令的地址拷贝给LR;●把程序状态寄存器CPSR拷贝给SPSR_svc;●强制进入管理模式;●强制进入到ARM状态;●跳转到绝对地址PC=0x00000008处执行;●禁止IRQ中断。第7章ARM异常中断处理及编程
3.软件中断异常13第7章ARM异常中断处理及编程
进入中断后的程序状态寄存器如下:......IFTM4M3M2M1M0
1x010011软件中断处理程序完成后,使用下列指令返回到原中断处:MOVSPC,R14第7章ARM异常中断处理及编程
进入中断后的程序状态寄存14第7章ARM异常中断处理及编程
4.预取指中止异常程序存储器引起的中止异常叫做预取指中止异常;数据存储器引起的中止异常叫做数据中止异常。
有两种可能如下:
●当执行这条指令前程序发生跳转,则这条无效指令不引起异常中断;●当执行到这条指令时,处理器会发生预取指中止异常,引起中断。第7章ARM异常中断处理及编程
4.预取指中止异常15第7章ARM异常中断处理及编程
当进入预取指异常中断时,处理器硬件响应中断,执行以下的操作:●把中断时PC的地址拷贝给LR;●把程序状态寄存器CPSR拷贝给SPSR_abt;●强制进入中止异常模式;●强制进入到ARM状态;●跳转到绝对地址PC=0x0000000C处执行;●禁止IRQ中断。第7章ARM异常中断处理及编程当进入预取指异常中断时,处16第7章ARM异常中断处理及编程
进入中断后,程序状态寄存器如下:......IFTM4M3M2M1M0
1x010111预取指中止异常中断返回时,应该执行下列指令:SUBSPC,R14,#4.第7章ARM异常中断处理及编程进入中断后,程序状态寄存器17第7章ARM异常中断处理及编程
5.数据中止异常ARM处理器访问数据存储器时,在读取数据的同时数据存储器发出了中止信号,引起数据中止异常。数据中止异常中断服务程序返回时,用下列指令:
SUBSPC,R14,#8
上述指令是返回到中断时所执行的指令,目的是再一次从数据存储器中读取数据。如果不再一次读取数据,则执行下一条指令,此时使用下列指令返回:
SUBSPC,R14,#4第7章ARM异常中断处理及编程5.数据中止异常18第7章ARM异常中断处理及编程
当进入数据中止异常中断时,处理器硬件响应中断,执行以下的操作:●把中断时的PC的地址拷贝给LR;●把程序状态寄存器CPSR拷贝给SPSR_abt;●强制进入中止异常模式;●强制进入到ARM状态;●跳转到绝对地址PC=0x00000010处执行;●禁止IRQ中断。第7章ARM异常中断处理及编程当进入数据中止异常中断19第7章ARM异常中断处理及编程
进入中断后,程序状态寄存器如下:......IFTM4M3M2M1M0
1x010111第7章ARM异常中断处理及编程
进入中断后,程序状态寄20第7章ARM异常中断处理及编程
6.中断请求(IRQ)异常当I=1时。则屏蔽IRQ中断,当I=0时,则允许中断。处理器复位后置I为1,关闭中断。ARM系统中外设通过该异常中断请求处理服务。
例如:定时器中断、串行口通讯中断、外部信号中断和A/D处理中断等。IRQ中断是可屏蔽的。在状态寄存器中的I位就是IRQ的屏蔽位。第7章ARM异常中断处理及编程6.中断请求(IRQ)异常21第7章ARM异常中断处理及编程
当发生IRQ中断时,处理器硬件响应中断,执行下列操作:
●把中断时的PC的地址值拷贝给LR;●把程序状态寄存器CPSR拷贝给SPSR_irq;●强制进入IRQ异常模式;●强制进入到ARM状态;●跳转到绝对地址PC=0x00000018处执行;●禁止IRQ中断。第7章ARM异常中断处理及编程当发生IRQ中断时,22第7章ARM异常中断处理及编程
进入中断后,程序状态寄存器如下:......IFTM4M3M2M1M0
1x010010
完成中断处理后,程序执行下列返回原中断处:SUBSPC.R14,#4.第7章ARM异常中断处理及编程进入中断后,程序状态寄存器23第7章ARM异常中断处理及编程
7.2.2支持中断跳转的解析程序(1)解析程序的概念和作用中断解析程序是为了使得上层应用程序与硬件中断跳转联系起来所编写一段中间的服务程序。中断跳转流程图如图7.1所示。第7章ARM异常中断处理及编程7.2.2支持中断跳转的24第7章ARM异常中断处理及编程
(2)解析过程以一次IRQ跳转为例说明解析过程,假定中断向量表定义在0x00400000开始的外部RAM空间,中断解析示例流程如图7.2所示。图中实线表示的流程都用ARM汇编语言编写,一般作为boot代码的一部分放在系统的底层模块中。填写向量表的操作可以在上层应用程序中方便地实现,比如在C语言中:*(int*(0x00400018))=(int)ISR_IRQ;这样就将IRQ中断的服务程序入口地址(0x00300260)填写到中断向量表中的固定地址0x00400018开始的4字节空间了。这样就可避免在应用程序中计算中断的跳转地址,并可很方便的选择不同的函数作为指定中断的服务程序。当然,在程序开发时要合理开辟好向量表,避免对向量表地址空间不必要的写操作。第7章ARM异常中断处理及编程(2)解析过程25第7章ARM异常中断处理及编程
第7章ARM异常中断处理及编程26第7章ARM异常中断处理及编程
(3)解析程序的扩展
在ARM处理器中会包含很多中断源,通常会在ARM内核外面扩展一个中断控制器来管理各种原因产生的中断。如,三星公司的S3C4510B处理器中的IRQ/FIQ类型的中断源可以有21个S3C44B0X有26个。解析程序的扩展处理流程可用图7.3表示。7.3中断解析的扩展处理流程第7章ARM异常中断处理及编程(3)解析程序的扩展7.327第7章ARM异常中断处理及编程
7.3中断解析的扩展处理流程第7章ARM异常中断处理及编程7.3中断解析的扩展处理28第7章ARM异常中断处理及编程
(4)向量中断的处理在设计外部扩展的中断控制器时提供了一种叫做“向量中断”的中断跳转机制。与前面叙述的扩展解析跳转流程有所不同,它不需要软件来识别具体的中断源,也就是不需要添加图7.3中的IRQ/FIQ服务程序,而完全由硬件自动跳转到对应的中断地址。其它跳转流程的原理都是一样的。这相当于扩展了ARM内核的硬件中断向量表,减小了中断响应延时。以S3C2410X处理器的外部中断0为例,需要在其对应的硬件固定跳转地址0x00000020处添加指令:ldrpc,=HandlerEINT,使得程序跳转到其服务程序HandlerEINT0处执行。向量中断的处理如图7.4所示。第7章ARM异常中断处理及编程(4)向量中断的处理29第7章ARM异常中断处理及编程
图7.4向量中断的处理第7章ARM异常中断处理及编程图7.4向量中断的处理30第7章ARM异常中断处理及编程
7.3中断解析的扩展处理流程7.3ARM应用系统中异常中断处理程序的安装在ARM应用程序中安装异常中断处理程序通常有下列两种方法。●使用跳转指令:可以在异常中断对应异常向量表中特定位置放置一条跳转指令,直接跳转到该异常中断的处理程序。但只能在32M空间范围内跳转。●使用数据读取指令LDR:使用数据读取指令LDR向程序计数器PC中直接赋值。这种方法分为两步:先将异常中断处理程序的绝对地址存放在距离向量表4KB范围内的一个存储单元中;再使用数据读取指令LDR将该单元的内容读取到程序计数器PC中。第7章ARM异常中断处理及编程7.3中断解析的扩展处理31第7章ARM异常中断处理及编程
7.3中断解析的扩展处理流程7.3.1在系统复位时安装异常中断处理程序
1.地址0x00处为ROM的情况
当地址0x0处为ROM时:在异常中断向量表中,可以使用数据读取指令LDR直接向程序计数器PC中赋值,也可以直接使用跳转指令跳转到异常中断处理程序。第7章ARM异常中断处理及编程7.3中断解析的扩展处理32第7章ARM异常中断处理及编程
使用数据读取指令LDR的示例如下所示:Vector_Init_BlockLDRPC,Reset_AddrLDRPC,Undefined_AddrLDRPC,SW_AddrLDRPC,Prefeth_AddrLDRPC,Abort_AddrNOPLDRPC,IRQ_AddrLDRPC,FIQ_AddrReset_Addr
DCDStart_Boot第7章ARM异常中断处理及编程使用数据读取指令LDR的示33第7章ARM异常中断处理及编程
Undefined_AddrDCDUndefined_HandleSW_Addr
DCDSWI_HandlePrefeth_Addr
DCDPrefeth_HandleAbort_AddrDCDAbort_HandleDCD0IRQ_Addr
DCDIRQ_HandleFIQ_Addr
DCDFIQ_Handle第7章ARM异常中断处理及编程Undefined_Add34第7章ARM异常中断处理及编程
使用跳转指令的示例如下所示:Vector_Init_BlockBLReset_HandleBLUndefined_HandleBLSWI_HandleBLPrefeth_HandleBLAbort_HandleNOPBLIRQ_HandleBLFIQ_Handle第7章ARM异常中断处理及编程使用跳转指令的示例如下所示35第7章ARM异常中断处理及编程
2.地址0x00处为RAM的情况
当地址0x0处为RAM时,中断向量表必须使用数据读取指令直接指向PC中赋值的形式。而且,必须使用下面的代码把中断向量表从ROM中复制到RAM的地址0x00开始处的存储空间中。中断向量表从ROM中复制到RAM的代码段如下:MOVr8,#0ADRr9,Vector_Init_Block;复制中断向量表(8字)LDMIAr9!,{r0-r7}STMIAr8!,{r0-r7};复制保存各中断处理函数地址的表(8words)LDMIAr9!,{r0-r7}STMIAr8!,{r0-r7}第7章ARM异常中断处理及编程2.地址0x00处为RA36第7章ARM异常中断处理及编程
7.3.2在C程序中安装异常中断处理程序安装异常中断处理程序的方法。1.中断向量表中使用跳转指令的情况当中断向量表中使用跳转指令时,在C程序中安装异常中断处理程序的操作如下:(1)读取中断处理程序的地址。(2)从上一步得到的地址中减去该异常中断对应的中断向量的地址。(3)从上一步得到的地址中减去8,以允许指令预取。(4)将上一步得到的地址右移 2位,得到以字(32位)为单位的偏移量。(5)确保上一步得到的地址值高8位为0,因为跳转指令只允许24位的偏移量。(6)将上一步得到的地址与数据0xea000000作逻辑或,从而得到将要写到中断向量表中的跳转指令的编码。第7章ARM异常中断处理及编程7.3.2在C程序中安装37第7章ARM异常中断处理及编程
例7.1使用跳转指令的中断向量表unsignedInstall_Handler(unsignedroutine,unsigned*vector)/*在中断向量表中vector处,添上合适的跳转指令*//*该跳转指令跳转到中断处理程序routine处。*//*程序返回原来的中断向量*/{unsignedvec,oldvec;vec=((routine–(unsigned)vector–0x8)>>2);if(vec&oxff000000){printf(“InstallationofHandlerfailed“);exit(1);}vec=oxea000000|vec;oldvec=*vector;*vector=vec;return(oldvec);}第7章ARM异常中断处理及编程例7.1使用跳转指令的中38第7章ARM异常中断处理及编程
2.中断向量表中使用数据读取指令的情况当中断向量表中使用数据读取指令时,在C程序中安装异常中断处理程序的操作过程如下:(1)读取中断处理程序的地址。(2)从上一步得到的地址中减去该异常中断对应的中断向量的地址。(3)从上一步得到地址中减去8,以允许指令预取。(4)将上一步得到地址与数据0xe59ff000作逻辑或,从而得到将要写到中断向量表中的数据读取指令的编码。(5)将中断处理程序的地址放到相应的存储单元。第7章ARM异常中断处理及编程2.中断向量表中使用39第7章ARM异常中断处理及编程
例7.2使用数据读取指令的中断向量表unsignedInstall_Handler(unsignedlocation,unsigned*vector)/*在中断向量表中vector处,添上合适的指令LDRpc,[pc,#offset]*//*该指令跳转的目标地址存放在存储单元‘location’中*//*函数返回原来的中断向量*/{unsignedvec,oldvec;vec=((unsigned)location–(unsigned)vector–0x8)|0xe59ff000;oldvec=*vector;*vector=vec;return(oldvec);}第7章ARM异常中断处理及编程例7.2使用数据读取指令40第7章ARM异常中断处理及编程
用下面的语句调用例7.2的函数,实现用C语言程序完成中断处理程序的安装。unsigned*irqvec=(unsigned*)0x18;Install_Handler((unsigned)IRQHandler,irqvec);第7章ARM异常中断处理及编程用下面的语句调41第7章ARM异常中断处理及编程
7.4ARM的SWI异常中断处理程序设计
通过SWI异常中断指令,用户模式下应用程序可以调用系统模式下的代码。在实时操作系统中,通常使用SWI异常中断为用户应用程序提供系统功能调用。7.4.1SWI异常中断处理程序的实现在SWI指令中包括一个24位的立即数(中断调用号),该立即数指示了用户要请求的特定的调用功能,所以在SWI的异常中断中要读取这个中断调用号,然后根据中断号,来调用相应的处理程序。这个过程可以分两步:第1步是SWI中断处理程序为汇编,用于确定SWI指令中的24位的立即数;第2步是SWI异常中断处理的功能服务程序,是具体实现SWI的各个功能,它即可用汇编语言,也可用C语言编程。第7章ARM异常中断处理及编程7.4ARM的SWI异42第7章ARM异常中断处理及编程
1.第1步用汇编语言编写的SWI异常中断处理程序
由于是在底层操作,所以这个异常中断处理程序得用汇编语言编写,例7.3所示的SWI异常中断处理程序中的blswi_service_func指令是调用第2步的SWI异常中断处理的功能服务程序,此函数是用于实现SWI的各个功能。第7章ARM异常中断处理及编程1.第1步用汇编语言编写43第7章ARM异常中断处理及编程
例7.3汇编语言编写的第1步SWI异常中断处理程序areatop_swicodereadonlyexportswi_headlerswi_headlerstmfdsp!,{r0-r12,lr}
;保存r0至r12,lr的寄存器值ldrr0,[lr,#-4]
;从存储器中取得SWI指令的所在地址bicr0,r0,#FF000000
;读取24位中断调用号movr1,sp;=============================blswi_service_func
;调用功能服务函数,见下面
;中断调用号通过r0寄存器传入
;参数通过r1寄存器传入;==============================ldmfdsp!,{r0-r12,pc}^
;恢复调用前r0至r12,退出end第7章ARM异常中断处理及编程例7.3汇编语言编写的44第7章ARM异常中断处理及编程
2.SWI异常中断处理的中断服务程序
为了具体实现SWI的各个功能,需编写SWI异常中断处理的功能服务程序,它即可用汇编语言,也可用C语言编程。例7.4是用汇编语言编写的SWI异常中断处理的中断服务程序,例7.5是用C语言编写的SWI异常中断处理的中断服务程序。第7章ARM异常中断处理及编程2.SWI异常中断处理的45第7章ARM异常中断处理及编程
例7.4汇编语言编写的SWI异常中断处理程序areatoplevelswicodereadonlyexportswi_headlerswi_headlerstmfdsp!,{r0-r12,lr};保存r0至r12,lr的寄存器值ldrr0,[lr,#-4]
;从存储器中取得SWI指令的所在地址bicr0,r0,#FF000000
;读取24位中断调用号movr1,sp;判断立即数是否有效cmpR0,#MaxOfSWI;判R0中数是否有效超过允许的最大值ldrlspc,[pc,r0,lsl#2]bOutOfSWIRange;超出范围JumpListofSWI;SWI的跳转表dcdSWIPro_0;SWI对应立即数0的中断处理程序入口地址dcdSWIPro_1;SWI对应立即数1的中断处理程序入口地址第7章ARM异常中断处理及编程例7.4汇编语言编写的S46第7章ARM异常中断处理及编程
;其他所有的软中断入口SWIPro_0;进入SWI对应立即数0的中断处理程序;对应立即数0的中断处理程序bEndOfSWISWIPro1;进入SWI对应立即数1的中断处理程序;对应立即数1的中断处理程序bEndOfSWI;其他的SWI处理程序EndOfSWI;结束SWI中断处理程序ldmfdsp!,{r0-r12,pc}^
;恢复调用前的r0至r12,退出中断程序end第7章ARM异常中断处理及编程47第7章ARM异常中断处理及编程
例7.5用C语言编写的第2步SWI异常中断处理的中断服务程序
用C语言编写的第2步SWI异常中断处理的中断服务程序的函数原形如下:voidswi_service_func(unsignedintnumber,unsignedint*reg)
其中:参数number是SWI的中断调用号,是利用从中断处理函数获得的中断调用号;参数reg是SWI异常中断第1步(例7.3)中断处理程序传递来的数据栈指针。在第1步的SWI异常中断处理程序调用第2步中断处理程序的操作如下所示:
设置C程序将使用的第二个参数,根据ATPCS第个参数保存在寄存器R1中第7章ARM异常中断处理及编程例7.5用C语言编写的第48第7章ARM异常中断处理及编程
movr1,spblswi_service_func
;调用功能服务函数,见下面
;中断调用号通过r0寄存器传入
;参数通过r1寄存器传入第2步SWI异常中断处理的中断服务程序代码如下:voidswi_service_func(unsignedintnumber,unsignedint*reg){
unsignedintreg1,reg2,reg3,reg4;
//获取SWI前传入的参数
reg1=reg[0];
reg2=reg[1];
reg3=reg[2];
reg4=reg[3];
第7章ARM异常中断处理及编程movr1,spbl49第7章ARM异常中断处理及编程
switch(number){
case0:
//dosomething
break;
case1:
//dosomething
break;
casen:
//dosomething
break;
default:
//dosomething
}
}
第7章ARM异常中断处理及编程
switch(n50第7章ARM异常中断处理及编程
//更新结果存入r0-r3
reg[0]=updata_reg1;
reg[1]=updata_reg2;
reg[2]=updata_reg3;
reg[3]=updata_reg4;}第7章ARM异常中断处理及编程
//更新结果存入51第7章ARM异常中断处理及编程
7.4.2SWI异常中断调用
1.在特权模式下调用SWI执行SWI指令后,系统将会把CPSR寄存器的内容保存到寄存器SPSR_svc中,将返回地址保存到寄存器LR_svc中。这样如果在执行SWI指令时,系统已经处于特权模式下,这时寄存器SPSR_svc和寄存器LR_svc中的内容就会被破坏。因此如果在特权模式下调用SWI功能(即执行SWI指令),比如在一个SWI异常中断处理程序中执行SWI指令,就必须将原始的寄存器SPSR_svc和寄存器LR_svc值保存在数据栈中。第7章ARM异常中断处理及编程7.4.2SWI异常中52第7章ARM异常中断处理及编程
例如7.6在SWI中断程序处理程序中保存寄存器SPSR_svc和寄存器LR_svc值areatop_swicodereadonlyexportswi_headlerswi_headlerstmfdsp!,{r0-r3,12,lr}
;保存r0至r3,r12,lr的寄存器值;保存SPSR_svcmovr1,spMRSr0,spsrstmfdsp!,{r0}
;读取SWI指令ldrr0,[lr,#-4]
;从存储器中取得SWI指令的所在地址bicr0,r0,#FF000000
;读取24位中断调用号,并存入寄存器r0中第7章ARM异常中断处理及编程例如7.6在SWI中断53第7章ARM异常中断处理及编程
;========================blswi_service_func
;调用功能服务函数,;见下面中断调用号通过r0寄存器;传入参数通过r1寄存器传入;==========================ldmfdsp!,{r0}
;恢复调用前的r0MSRspsr_cf,r0ldmfdsp!,{r0-r3,r12,pc}^
;恢复调用前的r0至r12,离开中断处理程序end第7章ARM异常中断处理及编程;============54第7章ARM异常中断处理及编程
2.从应用程序中调用SWI
可分两种情况从应用程序中调用特定的SWI功能:其一是使用汇编指令调用;其二是用C程序调用。汇编指令调用特定的SWI功能只要将所需要的参数按ATPCS的要求放置在相应的寄存器中,然后在指令SWI中指定相应24位立即数(即待调用的SWI功能号)即可。第7章ARM异常中断处理及编程2.从应用程序中调用SW55第7章ARM异常中断处理及编程
例如7.7
下面的例子是用汇编指令实现SWI的调用。SWI中断处理程序所需的参数放在寄存器R0中,然后调用功能号为0x0的SWI功能调用。MOVR0,#100SWI0x0第7章ARM异常中断处理及编程例如7.756第7章ARM异常中断处理及编程
例如7.8
下面是ARM公司的ADS1.2中自带的一个完整的用C语言程序调用特定的SWI功能的例子,例子中提供了4个SWI功能调用,功能号分别为0x0、0x1、0x2和0x3。其中SWI0x0和SWI0x1使用两个整型的输入参数,并返回一个结果值;SWI0x2使用4个输入参数,并返回一个结果值;SWI0x3使用4个输入参数,并返回4个结果值。第7章ARM异常中断处理及编程例如7.857第7章ARM异常中断处理及编程
从C程序中调用特定的SWI功能程序代码如下:/*头文件—swi.h*/__swi(0)intmultiply_two(int,int);__swi(1)intadd_two(int,int);__swi(2)intadd_multiply_two(int,int,int,int);structfour_results{inta;intb;intc;intd;};__swi(3)__value_in_regsstructfour_resultsmany_operations(int,int,int,int);第7章ARM异常中断处理及编程从C程序中调用特定的SW58第7章ARM异常中断处理及编程
/*主程序——main()*/#include<stdio.h>#include“swi.h”unsigned*swi_vec=(unsigned*)0x08;externvoidSWI_Handler(void);/*使用Install_Handler()安装SWI异常中断处理程序*/unsignedInstall_Handler(unsignedroutine,unsigned*vector){unsignedvec,old_vec;vec=(routine–(unsigned)vector-8)>>2;if(vec&0xff000000){printf(“Handlergreaterthan32Mbytesfromvector“);}第7章ARM异常中断处理及编程/*主程序——main59第7章ARM异常中断处理及编程
vec=0xea000000|vec;old_vec=*vector;*vector=vec;return(old_vec);}intmain(void){intresult1,result2;structfour_resultsres_3;Install_Handler((unsigned)SWI_Handler,swi_vec);printf(“result1=multiply_two(2,4)=%d\n”,result1=multiply_two(2,4));printf(“result2=multiply_two(3,6)=%d\n”,第7章ARM异常中断处理及编程vec=0xea00060第7章ARM异常中断处理及编程
result2=multiply_two(3,6));printf(“add_two(result1,result2)=%d\n”,add_two(result1,result2));printf(“add_multiply_two(2,4,3,6)=%d\n”,add_multiply_two(2,4,3,6));res_3=many_operations(12,4,3,1);printf(“res_3.a=%d\n”,res_3.a);printf(“res_3.b=%d\n”,res_3.b);printf(“res_3.c=%d\n”,res_3.c);printf(“res_3.d=%d\n”,res_3.d);return0;}第7章ARM异常中断处理及编程result2=multi61第7章ARM异常中断处理及编程
;第1步SWI异常中断处理程序SWI_HandlerAREASWI_Area,CODE,READONLYEXPORTC_SWI_HandlerT_bitEQU0x20SWI_HandlerSTMFDsp!,{r0-r3,r12,lr}MOVr1,spMRSr0,spsrSTMFDsp!,{r0}TSTr0,#T_bitLDRNEHr0,[lr,#-2]BICENr0,r0,#0xff00LDREQr0,[lr,#-4]第7章ARM异常中断处理及编程;第1步SWI异常中断处理62第7章ARM异常中断处理及编程
BICEQr0,r0,#0xff000000BLC_SWI_HandlerLDMFDsp!,{r0}MSRspsr_cf,r0LDMFDsp!,{r0,r3,r12,pc}^END;第2步SWI异常中断处理程序voidC_SWI_Handler()voidC_SWI_Handler(){switch(swi_num){
第7章ARM异常中断处理及编程BICEQr0,63第7章ARM异常中断处理及编程
case0;//对应于SWI0x0regs[0]=regs[0]*regs[1];break;case1;//对应于SWI0x1regs[0]=regs[0]+regs[1];break;case2;//对应于SWI0x2regs[0]=(regs[0]*regs[1])+(regs[2]*regs[3]);break;case3;//对应于SWI0x3{intw,x,y,z;第7章ARM异常中断处理及编程case0;//对64第7章ARM异常中断处理及编程
w=regs[0];x=regs[1];y=regs[2];z=regs[3];regs[0]=w+x+y+z;regs[1]=w-x-y-z;regs[2]=w*x*y*z;regs[3]=(w+x)*(y–z);}break
;}}第7章ARM异常中断处理及编程w=regs[0];65第7章ARM异常中断处理及编程
3.从应用程序中动态调用SWI动态调用SWI是指在应用程序的运行时调用SWI的功能号。有两种方法实现动态调用SWI功能号。方法1:在运行时得到SWI功能号,然后构造出相应的SWI指令的编码,把这个指令的编码保存在某个存储单元中,执行该指令即可。方法2:用一个通用的SWI异常中断处理程序,将运行时需要调用的SWI功能号作为参数传递给该通用的SWI异常中断处理程序。通用的SWI异常中断处理程序根据参数值调用相应的SWI处理程序完成需要操作。第7章ARM异常中断处理及编程3.从应用程序中动态调用66第7章ARM异常中断处理及编程
在汇编程序中常用第2种方法。在执行SWI指令之前先将需要调用的SWI功能号放在某个寄存器(R0~R12都可以使用),在通用的SWI异常中断程序读取该寄存器值,决定需要执行的操作,但有些SWI处理程序需要SWI指令中的24位立即数,因而上述两种方法常常组合使用。在操作系统中通常使用一个SWI功能号和一个寄存器来提供很多的SWI功能调用,这样可以将其他的SWI功能号留给用户使用。第7章ARM异常中断处理及编程在汇编程序中常用第2种67第7章ARM异常中断处理及编程
例7.9在ARM体系中semihost的实现的一个实例,ARM程序使用SWI0x123456来实现semihost功能调用;Thumb程序使用SWI0xAB来实现semihost功能调用。此例中将子程序WRITEC(unsignedop,char*c)映射到somehost功能调用,具体semihostSWI的子功能号通过参数op传递。第7章ARM异常中断处理及编程例7.968第7章ARM异常中断处理及编程
7.5FIG和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异常中断处理及编程7.5FIG和IRQ异常69第7章ARM异常中断处理及编程
IRQ(外部中断请求):当处理器的外部中断请求引脚有效,且CPSR中的I位为0时,产生IRQ异常。系统的外设可以该异常请求中断服务(异常向量:0x0000,0018);FIQ(快速中断请求):当处理器的快速中断请求引脚有效,且CPSR中的F位为0时,产生FIQ异常(异常向量:0x0000,001C)。使用外部中断应注意把某个引脚设置为外部中断功能后,该引脚为输入模式,由于没有内部上拉电阻,所以必须外接一个上拉电阻,确保引脚不被悬空;除了引脚连接模块的设置,还需要设置VIC模块,才能产生外部中断,否则外部中断只能反映在EXTINT寄存器中;要使器件进入掉电模式并通过外部中断唤醒,软件应该正确设置引脚的外部中断功能,再进入掉电模式。第7章ARM异常中断处理及编程IRQ(外部中断70第7章ARM异常中断处理及编程
7.5.1IRQ和FIQ异常中断处理程序1.不可重入的IRQ/FIQ异常中断处理程序在C语言中,不可重入的IRQ/FIQ异常中断处理程序可以使用关键词_irq来说明。关键词_irq可以实现下面的操作:●保存APCS规定的被破坏的寄存器。●保存其他中断处理程序中用到的寄存器。●同时将(LR-4)赋给程序计数器PC实现中断处理程序的返回,并且恢复CPSR寄存器的内容。当IRQ/FIQ异常中断处理程序调用了子程序时,关键词_irq可以使IRQ/FIQ异常中断处理程序返回时从其数据栈中读取LR_irq值,并通过SUBSPC,LR,#4;实现返回。第7章ARM异常中断处理及编程7.5.1I71第7章ARM异常中断处理及编程
例7.10的程序中说明了关键词_irq的作用。在例中的两个C语言程序中,第1个使用了关键词_irq的声明,第2个没有使用关键词_irq的声明。例7.10关键词_irq的作用/*第1个程序使用关键词_irq声明*/_irqvoidIRQHandler(void){volatileunsignedint*base=(unsignedint*)0x80000000;if(*base==1){C_int_handler();//调用相应的C语言处理程序}*(base+1)=0;//清除中断标志}第7章ARM异常中断处理及编程例7.10的程序中说明了关72第7章ARM异常中断处理及编程
;第1个C语言程序对应的汇编程序IRQHandlerPROCSTMFDsp!,{r0-r4.r12,lr}MOVr4,#0x80000000LDRr0,[r4,#0]SUBsp,sp,#4CMPr0,#1BLEQC_int_handlerMOVr0,#0STRr0,[r4,#4]ADDsp,sp,#4LDMFDsp!,{r0-r4,r12,lr}SUBSpc,lr,#4ENDP第7章ARM异常中断处理及编程;第1个C语言程序对应的汇73第7章ARM异常中断处理及编程
EXPORTIRQHandler/*第2个程序没有使用关键词_irq声明*/irqvoidIRQHandler(void){volatileunsignedint*base=(unsignedint*)0x80000000;if(*base==1){C_int_handler();//调用相应的C语言处理程序}*(base+1)=0;//清除中断标志}第7章ARM异常中断处理及编程EXPORTIRQHan74第7章ARM异常中断处理及编程
;第1个C语言程序对应的汇编程序IRQHandlerPROCSTMFDsp!,{r4.lr}MOVr4,#0x80000000LDRr0,[r4,#0]CMPr0,#1BLEQC_int_handlerMOVr0,#0STRr0,[r4,#4]LDMFDsp!,{r4,pc}ENDP第7章ARM异常中断处理及编程;第1个C语言程序对应的汇75第7章ARM异常中断处理及编程
2.可重入的IRQ/FIQ异常中断处理程序在可重入的IRQ/FIQ异常中断处理程序中调用子程序,子程序的返回地址是保存在寄存器LR_irq中,若这时又发生了IRQ/FIQ异常中断,则这个寄存器LR_irq中的值将会被破坏,那么被调用的子程序将不能正确返回。因此,对于可重入IRQ/FIQ异常中断处理程序需要做一些特殊的操作。第7章ARM异常中断处理及编程2.可重入的IRQ/FIQ76第7章ARM异常中断处理及编程
第1步中断处理程序需完成下列操作(注:这一级不能用C语言编程):●将返回地址保存到IRQ的数据栈中。●保存工作寄存器和SPSR_irq。●清除中断标志。●将处理器切换到系统模式,重新使能(IRQ/FIQ)。●保存用户模式LR寄存器和被调用者不保存的寄存器。●调用C语言IRQ/FIQ异常中断处理程序。●当C语言的IRQ/FIQ异常中断处理程序返回后,恢复用户模式的寄存器,并禁止中断(IRQ/FIQ)。●切换到IRQ模式,禁止中断。●恢复工组寄存器和寄存器LR_irq。●从IRQ异常中断处理程序中返回。第7章ARM异常中断处理及编程第1步中断处理程77第7章ARM异常中断处理及编程
例7.11可重入的IRQ/FIQ异常中断处理程序AREAINTERRUPT,CODE,READONLYIMPORTC_irq_handler;引入C语言的IRQ中断处理程序C_irq_handlerIRQSUBlr,lr,#4STMFDsp!,{lr};保存返回IRQ处理程序地址MRSr14,SPSRSTMFDsp!,{r12,r14};保存SPSR_irq,及其他工作寄存器第7章ARM异常中断处理及编程例7.11可重入的IR78第7章ARM异常中断处理及编程
;在这里添加指令,清除中断标志位;添加指令重新使能中断MSRCPSR_c,#0x1F;切换到系统模式,并使能中断STMFDsp!,{r0-r3,lr};保存用户模式的LR_usr及被调用者不保存的寄存器BLC_irq_handler;跳转到C语言的中断处理程序LDMFDsp!,{r0-r3,lr};恢复用户模式的寄存器MSRCPSR_c,#0x92;切换到IRQ模式,禁止IRQ中断,FIQ中断仍允许LDMFDsp!,{r12,r14};恢复工作寄存器和SPSR_irqLDMFDsp!,{pc}^;从IRQ处理程序返回END第7章ARM异常中断处理及编程;在这里添加指令,清除中79第7章ARM异常中断处理及编程
7.5.2多中断源的IRQ异常中断处理程序下面通过一多中断源的IRQ异常中断处理程序来说明ARM中断的使用。例中是32个中断源,每个中断源对应一个单独的优先级值,优先级的取值范围为0~31。假设系统中的中断控制器的基地址为IntBase,存放中断优先级值的寄存器的偏移地址为IntLevel。寄存器R13指向一个FD类型的数据栈。例7.12多中断源的IRQ异常中断处理程序SUBlr,lr,#4STMFDsp!,{lr};保存返回IRQ处理程序地址MRSr14,SPSRSTMFDsp!,{r12,r14};保存SPSR,及R12寄存器MOVr12,#IntBase;读取中断控制器的地址LDRr12,[r12,#IntLevel];读取优先级最高的中断源的优先级值;使能中断第7章ARM异常中断处理及编程7.5.2多中断源的I80第7章ARM异常中断处理及编程
MSRr14.CPSRBICr14,r14,#0x80MSRCPSR_c,r14LDRPC,[PC,r12,LSL#2];跳转到优先级最高的中断对应的中断处理程序NOP;中断处理程序地址表DCDPriority0Handler;优先级为0的中断对应中断处理程序地址DCDPriority1Handler;优先级为1的中断对应中断处理程序地址DCDPriority2Handler;优先级为2的中断对应中断处理程序地址DCDPriority3Handler;优先级为3的中断对应中断处理程序地址……;优先级为0的中断对应的中断处理程序Priority0HandlerSTMFDsp!,{r0-r11};保存工作寄存器第7章ARM异常中断处理及编程MSRr14.CPSR81第7章ARM异常中断处理及编程
;这里为中断程序的程序体LDMFDsp!,{r0-r11};恢复工作寄存器
MRSr12,CPSRORRr12,r12MSRCPSR_c,r12;禁止中断LDMFDsp!,{r12,r14};恢复SPSR及寄存器r12MSRSPSR_csxf,r14;从优先级为0的中断处理程序返回LDMFDsp!,{pc}^;从IRQ处理程序返回;优先级为1的中断对应的中断处理程序Priority1Handler第7章ARM异常中断处理及编程;这里为中断程序的82第7章ARM异常中断处理及编程
7.6基于ARM9芯片S3C2410异常中断程序设计
7.6.1异常中断响应和返回系统运行时,异常可能会随时发生。当一个异常出现以后,ARM微处理器会执行以下几步操作:(1)
将下一条指令地址存入相应连接寄存器LR,以便程序在处理异常返回时能从正确位置重新开始执行。(2)
将CPSR复制到相应的SPSR中。(3)
根据异常类型,强制设置CPSR的运行模式位。(4)
强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相应的异常处理程序处。
第7章ARM异常中断处理及编程7.6基于ARM9芯片83第7章ARM异常中断处理及编程
异常处理完毕之后,ARM微处理器会执行以下几步操作从异常返回:(1)
将连接寄存器LR的值减去相应的偏移量后送到PC中。(2)
将SPSR复制回CPSR中。(3)
若在进入异常处理时设置了中断禁止位,要在此清除。
这些工作必须由用户在中断处理函数中实现。为保证在ARM处理器发生异常时不至于处于未知状态,在应用程序的设计中,首先要进行异常处理。采用的方式是在异常向量表中的特定位置放置一条跳转指令,跳转到异常处理程序处执行程序。第7章ARM异常中断处理及编程异常处理完毕之后84第7章ARM异常中断处理及编程
7.6.2异常处理程序设计7.6.2.1
异常响应流程
由于向量表的限制,只能有一条指令B完成32MB范围内的跳转,并不能保证所有的异常处理函数都位于32MB范围内。为了扩展跳转范围,需要二次跳转才能把异常处理函数的地址传送给PC。异常处理调用关系如图7.5所示。三星公司网站提供了test2410_r11软件包,其中2410init.s有如下代码:HandlerXXXsub
sp,sp,#4
;减少sp,保存跳转地址stmfd
sp!,{r0}
;将工作寄存器压入堆栈ldr
r0,=HandleXXX;将HandleXXX地址放入r0ldr
r0,[r0]
;将中断程序入口地址放入r0str
r0,[sp,#4];将中断程序入口地址压入堆栈ldmfd
sp!,{r0,pc}
;将工作寄存器和中断程序入口地址弹出到r0和PC第7章ARM异常中断处理及编程7.6.2异常处理程序85第7章ARM异常中断处理及编程
图7.5异常处理调用第7章ARM异常中断处理及编程图7.5异常处理调用86第7章ARM异常中断处理及编程
并且在RAM中定义了存有中断程序入口地址表_ISR_STARTADDRESS:AREARamData,DATA,READWRITE^
_ISR_STARTADDRESSHandleReset
#
4HandleUndef
#
4HandleSWI
#
4HandlePabort
#
4HandleDabort
#
4HandleReserved
#
4HandleIRQ
#
4HandleFIQ
#
4第7章ARM异常中断处理及编程并且在RAM中定义了存87第7章ARM异常中断处理及编程
通常HandlerXXX位于程序入口地址32MB范围内,HandleXXX是以_ISR_STARTADDRESS为基地址的RAM中地址。该代码主要实现跳转功能,把异常处理程序地址HandleXXX送到PC中。例如产生IRQ中断时,PC会被强制设置为0x18,执行指令:b
HandlerIRQ在HandlerIRQ程序段内,处理器做一些必要的处理,就会将_ISR_STARTADDRESS表中存放的IRQ入口地址送入PC,然后开始执行相关中断程序。由于_ISR_STARTADDRESS表存放在RAM中,后面的C语言程序可以方便地更改相关中断服务程序的内容。第7章ARM异常中断处理及编程通常HandlerXX88第7章ARM异常中断处理及编程
7.6.2.2
异常分支系统可能存在多个IRQ/FIQ的中断处理程序。为了从向量表入口处的跳转最终能找到正确的中断处理程序,需要设计一套处理机制和方法来实现。可以在ARM的异常向量表之外,增加一张关联中断控制器的向量表,向量表中的内容对应每个具体的中断源,可以协助跳转到不同的中断处理程序。当响应外设的一个中断请求时,首先触发ARM核的中断,进人中断程序,再通过中断控制器识别中断源,使PC能够自动获得中断处理程序的地址。有的芯片支持特殊的硬件分支功能,依据中断源自动跳转到向量表的相应地址,多数情况下是用软件来处理异常分支。第7章ARM异常中断处理及编程7.6.2.289第7章ARM异常中断处理及编程
在S3C2410体系中,中断的调用可以看成是经历了2次“中断向量表”的查询。2410init.s中的以下代码完成功能就是查询中断偏移寄存器INTOFFSET,得到当前中断的中断号,并根据中断号再调用相关的中断服务程序。第7章ARM异常中断处理及编程在S3C2410体系中,90第7章ARM异常中断处理及编程
IsrIRQ
sub
sp,sp,#4
stmfd
sp!,{r8-r9}
ldr
r9,=INTOFFSET
ldr
r9,[r9]
ldr
r8,=HandleEINT0
add
r8,r8,r9,lsl#2
ldr
r8,[r8]
str
r8,[sp,#8]
ldmfd
sp!,{r8-r9,pc}为了方便C程序使用中断,将IsrIRQ设为IRQ的中断服务程序。
ldr
r0,=HandleIRQ
ldr
r1,=IsrIRQ
str
r1,[r0]第7章ARM异常中断处理及编程IsrIRQ91第7章ARM异常中断处理及编程
7.6.2.3
中断函数设计标准的ARM指令编译器提供了一个用来声明中断处理函数的关键字irq,编译后的代码在处理异常事件前保存现场信息,处理异常事件后对现场信息进行恢复。中断函数设计如下:staticvoid__irqEint3Int(void){
ClearPending(BIT_EINT3);Uart_Printf("EINT3interruptisoccurred.\n");
num_int=3;//设置标志位}定义中断处理程序入口地址可用下面的语句实现:#definepISR_EINT3
(*(unsigned*)(_ISR_STARTADDRESS+0x2c))在初始化程序,引用代码pISR_EINT3=(U32)Eint3Int,即可定义地址_ISR_STARTADDRESS+0x2c内容是Eint3Int的地址,外部中断3产生请求时即可调用中断处理函数Eint3Int。第7章ARM异常中断处理及编程7.6.2.3
中断函92第7章ARM异常中断处理及编程
7.6.3外中断初始化程序设计S3C2410X的中断控制寄存器能接收来自56个中断源的请求。内部的外围模块和外部管脚产生的多个中断请求通过中断控制器冲裁后,向ARM920T核发出FIQ或者IRQ中断。ARM内核只有2个外部中断输入信号nIRQ和nFIQ,在具体嵌入式系统中,需要用中断控制器管理多个外部中断源,选择其中一个中断,通过nIRQ或nFIQ向ARM内核发出中断请求,如图7.6所示。第7章ARM异常中断处理及编程7.6.3外中断初始化93第7章ARM异常中断处理及编程
图7.6FIQ/IRQ中断处理过程第7章ARM异常中断处理及编程图7.6FIQ/IRQ94第7章ARM异常中断处理及编程
ARM920T内核可以识别正常中断请求和快速中断请求两种类型的外部中断,中断的行为模式由中断控制器来设置。S3C2410X的中断控制器包括6类寄存器:中断源状态寄存器、中断模式寄存器、中断屏蔽寄存器、优先级寄存器、中断状态寄存器,以及中断偏移寄存器。在初始化程序中,需要选择相应管脚的功能,在此定义GPF3为EINT3模式,通过外部中断控制寄存器EXTINT0设定EINT3是下降沿触发方式,通过设置中断源悬挂寄存器SRCPND、中断悬挂寄存器INTPND和中断屏蔽寄存器INTMSK开启EINT3。中断模式寄存器和中断优先级寄存器采用系统默认方式。
第7章ARM异常中断处理及编程ARM920T内核可以95第7章ARM异常中断处理及编程
具体代码实现如下:voidEint_Init(void){rGPFCON=(rGPFCON&0x3f0c)|(1<<7);rEXTINT0=(rEXTINT0&~(0x7<<12))|0x2<<12;
pISR_EINT3=(U32)Eint3Int;
rSRCPND=BIT_EINT3;rINTPND=BIT_EINT3;rINTMSK=~(BIT_EINT3);}
如果采用EINT4~EINT23之间的中断源,还需要设置外部中断悬挂寄存器EINTPEND和外部中断掩码寄存器EINTMASK的相关位。第7章ARM异常中断处理及编程具体代码实现如下:96第7章ARM异常中断处理及编程
在C语言的Main()程序中调用Eint_Init()函数,即可完成中断处理的初始化操作。
若外部下降沿信号接到GPF3管脚,就可以调用Eint3Int中断处理函数。第7章ARM异常中断处理及编程在C语言的Main(97第7章ARM异常中断处理及编程
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 简易车辆维修合同协议书
- 2025年大数据在旅游行业精准营销中的应用策略报告
- 2025年自动驾驶卡车在物流运输中的智能驾驶辅助系统报告
- 债权转让协议合同协议书
- 道路垃圾清理合同协议
- 送人东西协议书范本
- 族谱印刷协议书
- 辅导班协议合同
- 牧户入股协议书
- 保险合同协议书
- 园林绿化工程监理实施细则(完整版)
- 规章制度文件评审表
- 草坪学实习报告模板-Copy
- K-H-V行星齿轮减速器 瞿鸿鹏
- 事业单位节能减排工作实施方案
- sales-contract(中英文详版)
- 住宅楼消防工程施工组织设计方案(DOC39页)
- 欧科变频器说明书文档
- 2-1春风带我去散步
- 郑州印象城市介绍旅游推介专题讲授PPT课件
- 三相四线及三相三线错误接线向量图分析及更正
评论
0/150
提交评论