ARM的SWI异常中断处理程序设计
单片机的中断与异常处理方法

单片机的中断与异常处理方法在单片机的工作过程中,中断和异常处理是非常重要的概念和方法。
它们能够有效地提高单片机的响应能力和灵活性,使其能够应对各种不同的工作需求和问题。
本文将介绍单片机中断的概念、中断的种类以及针对不同中断的处理方法,同时也会探讨单片机异常处理的原理和方法。
一、中断的概念和种类中断是指在一个程序执行的过程中,由于某种特殊的事件发生,导致程序的正常执行被打断,转而去执行一个与当前任务无关的子程序,完成该事件的相应处理。
中断可以分为外部中断和内部中断两种。
1. 外部中断外部中断是指当单片机外部引脚的电平或信号发生变化时,引发中断事件,使单片机停止当前任务的执行,去处理由该外部事件引发的中断服务程序(ISR)。
外部中断常用于与外部设备的交互,如按键输入、传感器检测等。
在编程中,我们可以通过设置中断触发条件和编写相应的中断服务程序来实现对外部中断的处理。
2. 内部中断内部中断是指当单片机内部某个特定的事件发生时,由硬件或软件触发中断请求,并且将控制权交给中断服务程序进行相应的处理。
内部中断的发生可以是由于某个特定条件的满足,如定时器溢出中断、串口接收中断等;也可以是由软件的运行结果触发,如除法溢出中断、地址错误中断等。
不同的内部中断需要通过编程实现相应的中断服务程序。
二、中断的处理方法中断处理是指在中断发生时,单片机通过中断向量表找到相应的中断服务程序,并对中断事件进行处理的过程。
下面将介绍两种常用的中断处理方法。
1. 优先级中断处理优先级中断处理是指对多个中断源按照优先级进行划分和处理的方法。
在单片机的中断系统中,每个中断源都被赋予了一个优先级,高优先级的中断可以打断当前正在执行的低优先级中断,从而增加了中断的响应速度和灵活性。
优先级中断处理需要在编程时设置中断的优先级,并根据不同的中断事件编写相应的中断服务程序。
2. 嵌套中断处理嵌套中断处理是指当一个中断正在执行的过程中,又发生了另一个中断时,将当前中断挂起,转而处理新发生的中断,并在处理完毕后返回原中断继续执行的方法。
__swi软中断分析

一.软中断SWI(software interrupt)软件中断,由用户定义的中断指令.可以用于用户模式下的程序调用特权操作指令.在实时操作系统中可以通过该机制实现系统调用.一个SWI 所做的一切就是把模式改变成超级用户并设置PC 来执行在地址&08 处的下一个指令!编程异常通常叫做软中断.软中断是通讯进程之间用来模拟硬中断的一种信号通讯方式。
中断源发中断请求或软中断信号后,CPU或接收进程在适当的时机自动进行中断处理或完成软中断信号对应的功能.软中断是软件实现的中断,也就是程序运行时其他程序对它的中断;而硬中断是硬件实现的中断,是程序运行时设备对它的中断。
1.软中断发生的时间是由程序控制的,而硬中断发生的时间是随机的。
2.软中断是由程序调用发生的,而硬中断是由外设引发的。
3.硬件中断处理程序要确保它能快速地完成它的任务,这样程序执行时才不会等待较长时间。
二.swi的使用1.SWI指令SWI{cond} immed_24其中,immed_24位24位立即数2.ADS编译器中软中断的规定ADS编译器规定,用户可使用关键字__swi作为前缀来声明一个利用软中断的调用,其格式如下:__swi(功能号) 返回值类型名称(参数列表);其中关键字__swi后面的括号中的字段叫做软中断的功能编号。
系统是根据这个编号在软中断服务程序户中来确定应执行的程序段的。
用户可以在用户程序中像调用一个普通函数那样实现软中断的调用。
只是该“函数”没有普通函数那样明显的函数实现体。
至于软件中断具体的函数实体后面会讲到。
利用软中断服务程序可以规避由于ARM处在不同工作模式时所造成的访问限制(如资源的访问限制)。
3 在Uc/OS-II中软中断来实现的函数的声明函数注册软中断号__swi(0x00) void OS_TASK_SW(void);__swi(0x01) void __OSStartHighRdy(void);__swi(0x02) void OS_ENTER_CRITICAL(void);__swi(0x03) void OS_EXIT_CRITICAL(void);__swi(0x40) void *GetOSFunctionAddr(int Index);__swi(0x41) void *GetUsrFunctionAddr(int Index);__swi(0x42) void OSISRBegin(void);__swi(0x43) int OSISRNeedSwap(void);__swi(0x80) void ChangeToSYSMode(void);__swi(0x81) void ChangeToUSRMode(void);__swi(0x82) void TaskIsARM(INT8U prio);__swi(0x83) void TaskIsTHUMB(INT8U prio);这些函数不是通常意义上的函数,只是可以让用户在应用程序中使用这些“函数名”去引发一个携带功能号的软中断SWI,即ADS编译器在编译这些函数时,把他们编译成SWI指令的二进制代码。
swi 详解

SWI 0x123456
SWI 指令编码格式
30 28 27 26 25 24 23 0
| cond | 1 1 1 1 | Immed_24 |
__________________________________________
arm软件中断的方法
《一》SWI指令介绍
swi--software inturrupt
SWI{cond} immed_24
where:
cond is an optional condition code (see Conditional execution on page 4-4).
Usage
The BL instruction copies the address of the next instruction into r14 (lr, the link register), and causes a branch to label.
The machine-level instruction cannot branch to an address outside ±4Mb of the current instruction. When necessary, the ARM linker inserts code (a veneer) to allow longer branches (see The ARM linker chapter in ADS Linker and Utilities Guide).
300001dc [0x00007ff4] dcd 0x00007ff4 ....
...
following programe to get :
使用软中断,keil

使用软中断,首先要有硬件指令的支持.ARM有条指令是SWI.SWI 指令的格式为:SWI {条件} 24 位的立即数SWI 指令用于产生软件中断,以便用户程序能调用操作系统的系统例程。
操作系统在 SWI 的异常处理程序中提供相应的系统服务,指令中 24 位的立即数指定用户程序调用系统例程的类型,相关参数通过通用寄存器传递,当指令中 24 位的立即数被忽略时,用户程序调用系统例程的类型由通用寄存器 R0 的内容决定,同时,参数通过其他通用寄存器传递。
指令示例:SWI 0x02 ;该指令调用操作系统编号位02的系统例程。
在keil MDK中,关键字__svc可以产生硬件SWI指令,使得处理器能响应软件中断.关键字__svc,keil MDK帮助文件中这样描述:__svc 关键字声明超级用户调用 (SVC) 函数,该函数最多使用四个类似于整数的参数,并通过 value_in_regs 结构最多返回四个结果。
__svc 是一个函数限定符。
它影响函数的类型。
语法__svc(int svc_num) return-type function-name([argument-list]);其中:svc_num 是在 SVC 指令中使用的立即值。
它是一个表达式,其计算结果为以下范围内的整数:• 在 ARM 指令中为 0 到 224–1 (24 位值)• 在 16 位 Thumb 指令中为 0-255 (8 位值)。
要在keil MDK中使用软件中断,要做好两件事:第一件,更改启动文件,编写软件中断的汇编入口.在这个汇编入口中主要根据软件中断命令号进行相应的函数跳转.第二件,编写相应命令号的C语言服务函数.下面举例怎么样用软件中断实现开中断和关中断.第一步:更改启动代码keil MDK自带的启动代码有类似下面的语句:Vectors LDR PC, Reset_AddrLDR PC, Undef_AddrLDR PC, SWI_AddrLDR PC, PAbt_AddrLDR PC, DAbt_Addr蓝色语句是程序复位后要执行的第一条指令,即复位异常入口;而红色语句就是执行一个软件中断指令后,要跳转到的软件中断异常入口.通过语句"SWI_Addr DCD SWI_Handler"进行中转,软件中断会跳转到标号为SWI_Handler的语句处,该处即处理软件中断的命令号.源代码如下:EXPORT SWI_Handlerextern EnableIrqFunc ;使能中断函数名,用C语言实现extern DisableIrqFunc ;禁止中断函数名,用C语言实现SWI_HandlerSTMFD SP!, {R0,R12,LR} ;入栈LDR R0, [LR,#-4] ;取指令BIC R0,R0,#0xFF000000 ;取软件中断命令号CMP R0,#0 ;和0比较,因为我的使能中断用了软件中断命令0,禁止中断使用了软件中断命令1BLEQ EnableIrqFunc ;为零调用使能中断函数BLNE DisableIrqFunc ;不为零调用禁止中断函数LDMFD SP!,{R0,R12,PC}^ ;出栈第二部:编写相应命令号的C语言服务函数.声明软件中断:__svc(0x00) void EnableIrq(void); //使能中断__svc(0x01) void DisableIrq(void); //禁止中断编写服务函数:view plain1.void DisableIrqFunc(void)2.{3. int temp;4. __asm5. {6. MRS temp,SPSR7. ORR temp,temp,#0x808. MSR SPSR_c,temp9. }10.}11.void EnableIrqFunc(void)12.{13. int temp;14. __asm15. {16. MRS temp,SPSR17. BIC temp,temp,#0x8018. MSR SPSR_c,temp19. }20.}view plain1.void DisableIrqFunc(void)2.{3. int temp;4. __asm5. {6. MRS temp,SPSR7. ORR temp,temp,#0x808. MSR SPSR_c,temp9. }10.}11.void EnableIrqFunc(void)12.{13. int temp;14. __asm15. {16. MRS temp,SPSR17. BIC temp,temp,#0x8018. MSR SPSR_c,temp19. }20.}到此,使能和禁止中断的软中断就结束了,下面看一下执行过程.在程序中,如果想关中断,只需使用:DisableIrq();MDK编译器在执行这句函数时,自动用软中断指令代替,即: SWI 0x01ARM 执行这条软件中断指令后,发生软件中断异常,程序跳转到软件中断异常服务函数处,即汇编代码标号为SWI_Handler处,在这里判断软件中断命令号是0x01,然后执行 BLNE DisableIrqFunc 语句,调用禁止中断函数,实现关中断.。
ARM SWI

Address 1 2 3 4 5 x 6 7 0x00000000 0x00000004 0x00000008 0x0000000C 0x00000010 0x00000014 0x00000018 0x0000001C Reset
Exception
Mode in Entry Supervisor Undefined Supervisor Abort Abort Reserved IRQ FIQ
7
Introduction to
Software Interrupt (SWI)
CEG2400 Ch12 . SWI v4a
8
Compare hardware and software interrupt
– Hardware interrupt, e.g.
IRQ_Eint1() { :: } Computer EINT3 A falling edge at EINT3 will trigger the execution of the interrupt service routine __irq IRQ_Eint1()
– Software interrupt
Computer N-th-sys-routine() Main{ : { SWI N :: : } } An instruction “SWI N” in the program will trigger the execution of the N-th-sys-routine (system routine)
SWI
Undefined instruction Software Interrupt Abort (prefetch) Abort (data) Reserved IRQ (external interrupt) FIQ (fast interrupt)
arm汇编程序退出方式

arm汇编程序退出方式1.引言概述部分的内容如下所示:1.1 概述ARM汇编语言是一种低级的程序设计语言,专门用于编写ARM架构下的机器指令。
与高级语言相比,ARM汇编语言更加底层且与硬件关联密切,可以直接操作寄存器、内存和设备等。
在编写ARM汇编程序时,了解如何正确退出程序是非常重要的。
程序的退出方式通常有两种:正常退出和异常退出。
正常退出是指程序在完成所需的任务后,通过一系列指令主动结束程序的执行。
异常退出是指在程序执行过程中发生了错误或异常情况,导致程序意外终止。
无论是正常退出还是异常退出,程序的结束都需要进行一系列的清理工作,如关闭文件、释放内存等,以确保程序能够正确退出并回收资源。
在ARM汇编程序中,正常退出通常通过以下几种方式实现:1. 返回指令:使用指令`BX LR`或`MOV PC, LR`将程序的执行流程返回到调用该函数的位置。
这通常用于函数的正常返回。
2. 终止指令:使用指令`MOV PC, 0`或`MOV PC, R0`将程序的执行流程直接跳转到地址0处,从而结束程序的执行。
这通常用于主程序的结束。
异常退出则需要通过异常处理机制来实现,例如使用相关的中断处理程序或异常处理程序。
当程序发生异常情况时,处理程序会根据异常类型进行相应的处理和清理工作,最终将程序的执行流程返回到预定的位置。
本文将重点讨论ARM汇编程序的退出方式,以及如何正确地进行清理工作,确保程序的正常退出和资源的释放。
在接下来的章节中,我们将详细介绍不同的退出方式,并提供示例代码以说明其用法和注意事项。
1.2文章结构1.2 文章结构本文将围绕ARM汇编程序的退出方式展开讨论。
首先在引言部分进行了概述,介绍了本文的背景和意义。
接着通过文章结构的说明,将向读者展示本文的组织架构和思路。
在正文部分,将重点讨论两个要点,分别是“第一个要点”和“第二个要点”。
通过详细的解释和实例分析,将阐明ARM汇编程序退出的不同方式及其相关的特点和优缺点。
ARM异常处理机制

关键词: ARM;异常处理;异常中断;VIC;SWI
中图分类 号:TP311. 11
文献标识码:A
作为嵌入式系统处理器,为了保证系统的实时 性和程序执行的稳定性,ARM 处理器建立了一套 完整的异常处理机制。ARM 处理器共有 7 种异常
NOP LDR LDR
;保留向量 PC, IRQ_Addr PC, FIQ_Add r
3)将返回地址修正为 PC 4,并保存到相应 的 LR 寄存器中;
4)异常向量地址入 PC,跳转并执行中断服务 程序。
1.2 用户程序中需要关心的问题
1)异常向量的重新定位
收稿日期:2006-01-07
作者简介:李 莉(1974 - ),女,山东青岛人。硕士,讲师。主要研究方向为单片机及嵌入式系统。
快速中断请求 FIQ
FIQ 模式
各异常都有固定的优先级,依次为:复位、数
据中止、FIQ、IRQ、预取指中止、未定义指令和
SWI。由表 1 可知,各异常向量之间只有 4 个字节
的空间,因此通常在向量表中放置跳转指令,程序
如下:
Vectors
LDR LDR LDR LDR LDR
PC , R eset_Addr PC , Undef_Addr PC , SWI_Ad dr PC , PAbt_Addr PC , DAbt_Addr
未定义指令
未定义模式
0x00000 008
软件中断 (SWI)
特权模式
0x00000 00C 预取指中止(从存储器取指出错) 中止模式
0x00000 010 数据中止(数据访问存储器出错) 中止模式
0x00000 014
保留
保留
0x00000 018
ARM中断程序的原理和实现

ARM中断程序的原理和实现引言:中断是计算机系统中一种特殊的事件,它可以打断当前正在执行的程序,并执行一段特定的代码。
在ARM架构中,中断主要由两部分组成:中断处理程序和中断控制器。
本文将介绍ARM中断程序的原理和实现,包括中断的基本概念、中断的分类、中断的处理过程以及中断控制器的实现方式。
一、中断的基本概念中断可以看作是外部设备向CPU发送一个请求的一种方法。
当外部设备发生一些特定的事件时(如按键、时钟周期等),它会产生一个中断请求信号,通知CPU去处理相应的事件。
CPU收到中断请求信号后,会暂停当前的任务,保存现场并跳转到中断处理程序来处理中断。
二、中断的分类1.外部中断:外部中断是由外设产生的中断信号,如GPIO、串口等。
当外设产生中断请求信号时,中断控制器会将信号传递给CPU,触发相应的中断处理程序。
2.软件中断:软件中断是由软件主动触发的中断,通过软件指令可以触发中断控制器发送中断请求信号给CPU。
软件中断可以用于实现系统调用、任务切换等功能。
三、中断的处理过程1.中断请求:外部设备发生特定事件,产生中断请求信号。
中断请求信号会被中断控制器接收并传递给CPU。
2.中断响应:CPU收到中断请求信号后,会立即响应中断,并执行中断处理程序。
在响应中断之前,CPU需要保存当前的现场(包括程序计数器PC、寄存器等)。
3.中断处理:CPU跳转到中断处理程序的入口地址,开始执行中断处理程序。
中断处理程序通常用来处理中断事件,并根据需要进行中断服务例程的调用。
4.中断返回:中断处理程序执行完毕后,CPU会根据中断处理程序的返回指令返回到原来的程序中,并恢复之前保存的现场。
同时,中断控制器会清除中断请求信号,使其能够接受新的中断请求。
四、中断控制器的实现方式ARM架构中,中断控制器常用的实现方式包括级联式中断控制器和向量式中断控制器。
1.级联式中断控制器:级联式中断控制器是一种层级结构的中断控制器。
它包含多个级别的中断控制器,每个级别对应一组中断请求。
[参考]swi软中断
![[参考]swi软中断](https://img.taocdn.com/s3/m/31342759842458fb770bf78a6529647d272834a6.png)
arm 软件中断的方法介绍SWI指令---软件中断实例详解关键字: SWI,指令,软件中断,实例,详解SWI,即software interrupt软件中断。
该指令产生一个SWI异常。
意思就是处理器模式改变为超级用户模式,CPSR寄存器保存到超级用户模式下的SPSR寄存器,并且跳转到SWI向量。
其ARM指令格式如下:SWI{cond} immed_24Cond域:是可选的条件码 (参见 ARM汇编指令条件执行详解).immed_24域:范围从 0 到 224-1 的表达式, (即0-16777215)。
用户程序可以使用该常数来进入不同的处理流程。
一、方法1:获取immed_24操作数。
为了能实现根据指令中immed_24操作数的不同,跳转到不同的处理程序,所以我们往往需要在SWI异常处理子程序中去获得immed_24操作数的实际内容。
获得该操作数内容的方法是在异常处理函数中使用下面指令:LDR R0,[LR,#-4]该指令将链接寄存器LR的内容减去4后所获得的值作为一个地址,然后把该地址的内容装载进R0。
此时再使用下面指令,immed_24操作数的内容就保存到了R0:BIC R0,R0,#0xFF000000该指令将R0的高8位清零,并把结果保存到R0,意思就是取R0的低24位。
可能还是有人会问:为什么在SWI异常处理子程序中执行这两条指令后,immed_24操作数的内容就保存到了R0寄存器呢?之所以会有这样的疑问,基本都是因为对LR寄存器的作用没了解清楚。
下面介绍一下链接寄存器LR(R14)的作用。
寄存器R14(LR寄存器)有两种特殊功能:·在任何一种处理器模式下,该模式对应的R14寄存器用来保存子程序的返回地址。
当执行BL或BLX指令进行子程序调用时,子程序的返回地址被放置在R14中。
这样,只要把R14内容拷贝到PC中,就实现了子程序的返回(具体的子程序返回操作,这里不作详细介绍)。
ARM异常中断以及对ARM异常返回地址的分析

返回地址:SUBS PC,R14,#8 返回地址分析: 当进入异常时,R14_abt = address of the aborted instruction + 8
所以要返回到有问题的指令处重新执行,所以返回的地址为 R14-8 IRQ 中断异常:
产生原因: 当处理器的外部中断请求引脚有效,且 CPSR 寄存器的 I 控制位被清除 时,处理器产生外部中断 IRQ 异常。
是因为当前指令即引起软件异常中断的指令执行后所引起的,说明当前指令已近执行,当从
中断返回时,执行的指令应该是当前指令的下一条指令,即待执行指令的地址应该是 0x3004, 而 R14 中存放的即为 0x3004,所以返回时使用将 R14 的值直接赋给 PC 即可。
指令预期中止异常: 发生原因:若在指令预取阶段遇到无效指令时,系统存储器将该预取的指令标记为无
效指令,当处理器试图去执行这一条被标记为预取无效的指令时,将产生指令预取中止异常, 注意若处理器没有执行无效指令时将不会产生异常中断(在流水线中存在一条分支指令,导 致该非法指令没有执行,将不会产生该异常)。
处理器动作: R14_abt = address of the aborted instruction + 4 SPSR_abt = CPSR ….. …..
2、各异常分析
举个小例子,下面是一段 ARM 汇编代码: (后面的返回地址分析中将会用到此图)
arm处理器异常模式有哪些

arm 处理器异常模式有哪些
ARM 处理器异常处理
所谓异常就是正常的用户程序被暂时中止,处理器就进入异常模式,例如响应一个来自外设的中断,或者当前程序非法访问内存地址都会进入相应异常模式。
1.1.1 异常分类
(1)复位异常
当CPU 刚上电时或按下reset 重启键之后进入该异常,该异常在管理模式下处理。
(2)一般/快速中断请求
CPU 和外部设备是分别独立的硬件执行单元,CPU 对全部设备进行管理和资源调度处理,CPU 要想知道外部设备的运行状态,要幺CPU 定时的去查看外部设备特定寄存器,要幺让外部设备在出现需要CPU 干涉处理时打断CPU,让它来处理外部设备的请求,毫无疑问第二种方式更合理,可以让CPU 专心去工作,这里的打断操作就叫做中断请求,根据请求的紧急情。
ARM七种异常类型详解(精华版)

ARM7支持六种操作模式:(1)用户模式(usr):正常的程序执行状态(2)FIQ模式(fiq):支持数据传送或通道处理(3)IRQ模式(irq):用于通用的中断处理(4)管理模式(svc):用于操作系统的保护模式(5)异常模式(abt):数据或者指令预取异常时进入(6)无定义模式(und):当无定义指令被执行时进入(7)软件控制,外部中断,异常处理都可以改变操作模式。
大部分的应用程序在用户模式下执行。
其他模式,比如管理模式,在中断、异常服务、或者访问被保护资源时进入。
ARM 的中央寄存器集是16 个用户寄存器R0 – R15。
这些寄存器均是32 位宽度,R0 – R12 没有其他特殊功能,寄存器R13 – R15在CPU中有特殊功能。
R13被用作栈指针(stack pointer,SP)。
R14被称为链接寄存器(link register, LR),当调用一个函数时返回地址被自动保存到链接寄存器,在函数返回时有效。
这使得快速进入和返回“叶”函数(不调用其他函数的函数)成为可能。
如果函数是分支的一部分(即该函数将调用另一个函数),链接寄存器必须入栈(R13)。
R15 是程序计数器(program counter, PC)。
有趣的是,许多指令也可以在R13 – R15中执行,就像它们是标准的用户寄存器。
ARM中断的问题ARM的七种异常类型---------1> 复位异常2> 数据访问中止异常3> 快速中断请求异常4> 一般中断请求5> 预取指令异常6> 软件中断异常7> 未定义异常-------------------------问题:1> 为什么除了进入复位异常模式外,在别的异常处理模式中都允许FIQ中断?2> 数据访问中止异常的优先级大于 FIQ异常,为什么在数据访问异常处理模式中,还允许 FIQ中断?这样不就成了:在高优先级异常处理中允许低优先级的中断发生?即使这样,因为FIQ中断的优先级 < 数据异常中断优先级,也不会进入 FIQ中断处理程序啊,这样不就更没有用处了??ARM体系的各种异常的分析(学习日记)- [ARM7TDMI]版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明/logs/10669519.html1.复位异常(1)当内核的nRESET信号被拉低时,ARM处理器放弃正在执行的指令,当nRESET信号再次变高时,ARM处理器进行复位操作;(2)系统复位后,进入管理模式对系统进行初始化,复位后,只有PC(0x00000000)和CPSR (nzcvqIFt_SVC)的值是固定的,另外寄存器的值是随机的。
ARM Linux对中断的处理

void (*bus_lock)(unsigned int irq);
void (*bus_sync_unlock)(unsigned int irq);
/* Currently used only by UML, might disappear one day.*/
kstat_irqs: irq stats per cpu
irq_2_iommu: iommu with this irq
handle_irq:高层的irq时间处理程序(如果为NULL,则默认调用__do_IRQ())
chip:底层的中断硬件访问,指向PIC对象(irq_chip结构),它服务于IRQ线,Linux中断管理系统使用该成员来进行中断控制器的访问。
struct proc_dir_entry *dir;
#endif
const char *name;
}____cacheline_internodealigned_in_smp;
irq_desc结构体(中断描述符)中各个字段说明:
irq:中断描述符的中断号
timer_rand_state: pointer to timer rand state struct
#endif
irq_flow_handler_t handle_irq;
struct irq_chip *chip;
struct msi_desc *msi_desc;
void *handler_data;
void *chip_data;
struct irqaction *action; /* IRQ action list */
ARM汇编的SWI指令软中断

处理程序要通过读取引起软中断的SWI指令,以取得24位立即数.
(1) 指令中的24位立即数指定了用户请求的服务类型,参数通过通用
寄存器传递.
movr0,#34;设置子功能号位34
SWI12;调用12号软中断
(2) 指令中的24位立即数被忽略,用户请求的服务类型有寄存器RO
BICNER0,#0XFF00:取得Thunb指令的8位立即数
LDREQR0,[LR,#[标签:内容]
ARM汇编的SWI指令软中断
从下面的一个ARM汇编小程序要弄懂的以下三个问题:1).在ARM状态转
到THUNB状态和BX的应用
2).汇编的架构
3).SWI指令的使用
AREAADDREG,CODE,READONLY
ENTRY
MAIN
ADRr0,ThunbProg1;(为什么要加1呢?因为BX指令跳转到指定的地址执
addr4,r4,r5
stopmovr0,#0x18
LDRr1,=0x20026
SWI0x123456
END
SWI--软中断指令:
SWI指令用于产生软中断,从拥护模式变换到管理模式,CPSR保存到
管理模式的SPSR中.
SWI{cond}immed_24;immed_24为软中断号(服务类型)
使用SWI指令时,通常使用以下两种方法进行传递参数,SWI异常中断处
的值决定,参数通过其他的通用寄存器传递.
movr0,#12;调用12号软中断
movr1,#34;设置子功能号位34
SWI0
在SWI异常中断处理程序中,取出SWI立即数的步骤为:首先确定引起软
中断异常处理流程

中断异常处理流程1.特殊中断响应与返回系统运行时,特殊可能会随时发生。
当一个特殊出现以后,ARM微处理器会执行下列几步操作:1) 将下一条指令的地址存入相应连接寄存器LR,以便程序在处理特殊返回时能从正确的位置重新开始执行。
2) 将CPSR复制到相应的SPSR中。
3) 根据特殊类型,强制设置CPSR的运行模式位。
4) 强制PC从有关的特殊向量地址取下一条指令执行,从而跳转到相应的特殊处理程序处。
这些工作是由ARM 内核完成的,不需要用户程序参与。
特殊处理完毕之后,ARM 微处理器会执行下列几步操作从特殊返回:1) 将连接寄存器LR的值减去相应的偏移量后送到PC中。
2) 将SPSR复制回CPSR中。
3) 若在进入特殊处理时设置了中断禁止位,要在此清除。
这些工作务必由用户在中断处理函数中实现。
为保证在ARM处理器发生特殊时不至于处于未知状态,在应用程序的设计中,首先要进行特殊处理。
使用的方式是在特殊向量表中的特定位置放置一条跳转指令,跳转到特殊处理程序。
当ARM处理器发生特殊时,程序计数器PC会被强制设置为对应的特殊向量,从而跳转到特殊处理程序。
当特殊处理完成以后,返回到主程序继续执行。
能够认为应用程序总是从复位特殊处理程序开始执行的,因此复位特殊处理程序不需要返回。
2.特殊处理程序设计2.1 特殊响应流程由于向量表的限制,只能有一条指令B完成32MB范围内的跳转,并不能保证所有的特殊处理函数都位于32MB范围内。
为了扩展跳转范围,需要二次跳转才能把特殊处理函数的地址传送给PC。
特殊处理调用关系如图1所示。
三星公司网站提供了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图1特殊处理调用同时在RAM中定义了存有中断程序入口地址表_ISR_STARTADDRESS:AREA RamData, DA TA, READWRITE^ _ISR_STARTADDRESSHandleReset # 4HandleUndef # 4HandleSWI # 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ # 4HandleFIQ # 4通常HandlerXXX位于程序入口地址32MB范围内,HandleXXX是以_ISR_STARTADDRESS为基地址的RAM中地址。
ARM中断编程实验

数字信息技术实验学校学院专业实验题目 ARM 中断实验编程小组成员二Ο一七年三月一.实验目的通过本次实验了解中断是什么以及学会如何进行中断编程。
二.实验要求基础实验:利用Exynos4412 的K1、K2 这2 个I/O 引脚的中断模式,分别点亮LED1和LED2,扩展实验:配置K3为中断模式,点亮LED3.三.实验仪器1、计算机2、USB转9脚串口线(通过USB与计算机连接,母头与实验平台连接)3、Exynos4412处理器开发与应用实验平台4、BL-JTAG 仿真器(通过USB与计算机连接,JTAG口与实验平台连接)5、电源线(与实验平台相连接的交流电源线)四.实验原理1.电路原理K1、K2、K3 分别与GPX1_1、GPX1_2、GPX3_2相连,在没有按下按键时这些引脚上一直处于高电平,当按键按下时产生下降沿触发中断。
EXYNOS4412 中断实验电路图实验箱上按键位置2、编程流程去除GPX1_2、GPX1_2,GPX3_2 内部上下拉属性,配置为中断模式。
GPIO 控制器中关闭屏蔽、使能中断;在GIC 中断控制器中使能中断;设置中断优先级;使能GIC;选择中断发送给CPU0;等待中断产生,然后进入中断处理函数;清除中断源。
五.实验内容(1)连接好开发板与计算机之间的串口线和BL-JTAG 仿真器(2)连接好开发板的交流电源线(3)接下来利用计算机演示集成开发环境的使用,以及LED灯的控制实验软硬件仿真流程,打开Eclipse,导入工程Key_Int,进行相应代码编写,编译,配置相关debug信息,装载程序,按下KEY1,KEY2,KEY3在putty串口终上查看相应的信息输出以及可以看到LED1和LED2和LED3亮灭情况。
六.实验步骤根据实验一步骤,连接仿真器、串口线,打开Eclipse,导入工程Key_Int,进行相应代码编写,编译,配置相关debug信息,装载程序,按下KEY1,KEY2,在putty 串口终端上查看相应的信息输出以及可以看到LED1和LED1亮灭情况。
第9章异常中断处理

Undef handler outside 32MBytes branch instruction range
SWI Exception handler placed on applicable address boundary
IRQ handler within 32MBytes Branch instruction range
14
向量表指令
0xFFFFFFFF
0x30008000
0x30000000
> 32 Mbytes
0x2000000
< 4 Kbytes
0x1000 0xFFC
0x1C 0x18
Undef Handler SWI Handler
IRQ Handler 0x30008000 FIQ Handler B IRQ_handler
20
软中断
用户程序 (C/ASM)
SWI 0x01
向量表
SWI 处理程序 (ASM)
SWI 处理程序
(C)
用户程序调用 SWI
SWI 中断处理程序包含汇编部分和可选用 的 C 部分
AAsssseemmbbllee LLanguaaggee ooffAARRMM
(可选)
21
9.4.2 SWI异常中断调用
未定义指令中止模式 (und) 系统模式(sys)
描述
正常程序执行的模式
用于高速数据传输或通道处理
用于通用的中断处理
供操作系统使用的保护模式(复位或软中断)
当数据或指令预取终止时进入该模式,可用于 虚拟存储及存储保护。 当未定义的指令执行时进入该模式,可用于支 持通过软件仿真硬件的协处理器。
用于运行具有特权级的操作系统任务。
3ARM体系结构及编程模型

第二章 ARM体系结构及编程模型
1
ARM技术的应用领域及特点
2 ARM微处理器系列 3 ARM处理器的工作状态 4 ARM处理器的工作模式 5
ARM处理器的存储器格式
6 ARM 处理器的寄存器组织 7
ARM 异常处理 1
ARM技术的应用领域及特点
ARM-Advanced RISC Machines
8
ARM微处理器系列
ARM微处理器系列
ARM7系列 系列 ARM9系列 系列 ARM9E系列 系列 ARM10E系列 系列 SecurCore系列 系列 Intel的Xscale 的 其中, 其中,ARM7、ARM9、ARM9E和ARM10为4个通用 、 、 和 为 个通用 处理器系列, 处理器系列,每一个系列提供一套相对独特的性能来满足不 同应用领域的需求。 同应用领域的需求。SecurCore系列专门为安全要求较高的 系列专门为安全要求较高的 应用而设计。 应用而设计。
5
ARM技术的应用领域及特点
ARM微处理器的特点—大量使用寄存器 大量使用寄存器
ARM 处理器共有 个寄存器,被分为若干个组,这些 处理器共有37个寄存器 被分为若干个组, 个寄存器, 寄存器包括: 寄存器包括: 31个通用寄存器,包括程序计数器(PC 指针), 个通用寄存器,包括程序计数器( 指针), 个通用寄存器 均为32位的寄存器 位的寄存器; 均为 位的寄存器; 6个状态寄存器,用以标识CPU的工作状态及程 个状态寄存器,用以标识 个状态寄存器 的工作状态及程 序的运行状态,均为32位 序的运行状态,均为 位。
14
ARM微处理器的工作状态
ARM与THUMB
THUMB指令是ARM指令的子集 可以相互调用,只要遵循一定的调用规则 Thumb指令与ARM指令的时间效率和空间效率关系为: 存储空间约为ARM代码的60%~70% 指令数比ARM代码多约30%~40% 存储器为32位时ARM代码比Thumb代码快约40% 存储器为16位时Thumb比ARM代码快约40~50% 使用Thumb代码,存储器的功耗会降低约30%
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ห้องสมุดไป่ตู้
int main(void) { int result1,result2; struct four_results res_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",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,3,4,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); return 0; }
第2步SWI异常中断处理的中断服务程序代码如下: void swi_service_func(unsigned int number,unsiged int *reg) { case 1: unsigned int reg1,reg2,reg3,reg4; //do something //获取 SWI传入的参数 break; reg1=reg[0]; case n: reg2=reg[1]; //do reg3=reg[2]; something reg4=reg[3]; break; switch(number) default: { //do case 0: something //do something } break; reg[0]=updata_reg1; reg[1]=updata_reg2; reg[2]=updata_reg3;
用C语言编写的第2步SWI异常中断处理的中断服务程序。用 C语言编写的第2步SWI异常中断处理的中断服务程序的函数 原型如下: void swi_service_func(unsigned int number,unsigned int *reg) 注:参数number是SWI的中断调用号,是利用从中断处理 函数获得的中断调用号。 参数reg是SWI 异常中断第1步中中断处理程序传递来的 数据栈指针。 在第1步的SWI异常中断处理程序调用第2步中断处理程 序的操作如下: mov r1,sp ;根据ATPCS将r1中的值作为第二参数传入 bl swi_service_func ;调用功能服务函数,中断调用号通 过r0传入,参数通过r1传入
2.SWI异常中断处理的中断服务程序 (用汇编写的) 为了具体实现SWI的各个功能,须编写SWI异常中断处理的功能服务 程序,它既可以是汇编语言又可以是C语言。
area top_swi code readonly export swi_headler swi_headler stmfd sp!,{r0-r12,lr} ldr r0,[lr,# -4] bic r0,r0,#ff000000 mov r1,sp ;判断立即数是否有效 cmp r0,#MaxOfSWI ldrls pc,[pc,r0,lsl #2] b OutOfSWIRange JumpListofSWI dcd SWIPro_0 dcd SWIPro_1 ;其它所有的软中断入口 SWIPro_0 ;进入SWI对应立即数0的中断程序 ;对应立即数0的中断处理程序 b EndOfSWI SWIPro_1 ;进入SWI对应立即数1的中断程序 ;对应立即数1的中断处理程序 b EndOfSWI EndOfSWI ldmfd sp!,{r0-r12,pc}^ end
二、SWI异常中断调用 2.从应用程序中调用SWI (1)使用汇编指令调用特定的SWI功能 (2)用C程序调用特定的SWI功能 注意:汇编指令调用特定的SWI功能只要将所需的参数按 ATPCS要求放置在相应的寄存器中,然后在指令SWI中指定 相应24位立即数即可。 例:用汇编指令实现SWI的调用。SWI中断处理程序所需的 参数放在寄存器r0中,然后调用功能号0x0的SWI功能调用。 MOV r0,#100 SWI 0x0
二、SWI异常中断调用 2.从应用程序中调用SWI C程序中调用特定的SWI功能比汇编语言调用要复杂一些, 因为C语言中调用特定的SWI 特定功能需将C程序的子程序 调用映射到一个SWI异常中断处理程序。这些被映射的C语 言子程序使用编译器伪操作_ _SWI来声明。该子程序所需的 参数和返回的结果放在R0~R3中,则该SWI可以被视为inline, 不需要使用子程序调用过程;否则必须告诉编译器通过结构 数据类型来返回参数,这时需要使用编译器伪操作 _value_in_reg声明该C语言子程序。 例:提供4个SWI功能调用,功能号分别为 0x00,0x01,0x02,0x03。其中SWI 0x0和SWI0x1使用两个整 型的输入参数,并返回一个结果值;SWI 0x2使用4个输入参 数,并返回一个结果值;SWI0x3使用4个输入参数,并返回 4个结果。
C程序中调用特定的SWI功能程序代码: unsigned *swi_vec =(unsigned *)0x08; extern SWI_Handler; /*头文件—swi.h*/ _ _swi(0) int multiply_two(int,int); /*使用Install_Handler()安装 _ _swi(1) int add_two(int,int); SWI异常中断处理程序*/ _ _swi(2) int add_multiply_two(int,int,int,int); unsigned Install_Handler( unsigned routine,unsigned *vector) struct four_results { { unsigned vec ,old_vec; int a ; vec=(routine-(unsigned)vector-8)>>2; int b ; if(vec&0xff000000) int c ; { printf("Handler greater than int d ; 32M from vector"); }; __swi(3) _ _value_in_regs struct four_results } vec=0xea000000|vec; many_operations(int,int,int,int); old_vec=*vector; /*主程序—main( )*/ *vector=vec; #include <stdio.h> return (old_vec); #include "swi.h"
area top_swi code readonly export swi_headler swi_headler stmfd sp!,{r0-r3,r12,lr} ;保存SPSR_svc mov r1,sp MRS r0,spsr stmfd sp!,{r0} ;读取SWI指令 ldr r0,[lr,# -4] bic r0,r0,#ff000000 bl swi_service_func ldmfd sp!,{r0} ;恢复调用前的r0 MSR spsr_cf,r0 ldmfd sp!,{r0-r3,r12,pc}^ end
二、SWI异常中断调用 1.特权模式下调用SWI 执行SWI指令后,系统将会把CPSR寄存器的内容保存 在寄存器SPSR_svc中,将返回地址保存在寄存器LR_svc中。 如果在执行的SWI指令已经在svc模式下时,这时SPSR_svc 和LR_svc中的内容就会被破坏。因此在特权模式下调用SWI 功能(执行SWI指令),就必须将原始的寄存器SPSR_svc 和LR_svc的值保存在数据栈中。
1.用汇编语言编写的SWI异常中断处理程序 由于SWI异常中断处理程序属于底层操作,所以必须用汇 编语言编写。如下例所示:SWI异常中断处理程序中的 bl swi_service_func指令用于调用第2步的SWI异常中断处理 的功能服务程序,此函数用于实现SWI的各个功能。 汇编语言编写的第1步SWI异常中断处理程序
;第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] bicne r0,r0,#0xff00 ldreq r0,[lr,#-4] biceq r0,r0,#0xff000000 bl c_swi_handler ldmfd sp!,{r0} msr spsr_cf,r0 ldmfd sp!,{r0-r3,r12,pc}^ end