1、arm 中断处理1. 首先就是知道 ARM 状态下 37 个寄存器包括通用寄存器、程序计数器、状态寄存器。绿颜色的就是相应模式下的私有寄存器。就是说程序一般运行在系统和用户模式下,使用的是系统和用户模式下的通用寄存器,当有异常发生时,比如 FIQ,那么系统将切换到FIQ 模式下,相应的就会采用 FIQ 模式下的寄存器,其中绿颜色的就是只在 FIQ 模式下才会用到的寄存器。2. 在模式切换的过程中,要保护系统和用户模式下的通用寄存器状态,以便在异常处理完成之后程序能正常返回。因为 FIQ 模式下 R8-R14 为其私有寄存器,所以切换到 FIQ 模式的过程中,系统和用户模式下的通用寄存器的 R8
2、-R14 就不用保护了,所以减少了对寄存器存取的需要,从而可以快速的进行 FIQ 处理,故称为 FIQ。这就是 FIQ 的私有寄存器比其它模式多的原因。切到 FIQ 模式需要保护的寄存器为 R0R7,切到 SVC,IRQ,ABORT.和未定义模式需要保护的寄存器为 R0R123. 异常处理的动作。当然这都是 CPU 内核自己干的。以 FIQ 为例。当 CPU 切入 FIQ 模式时,第一,将原来执行程序的下一条指令地址保存到 LR 中,就是将 R14 保存到 R14_fiq 里面。第二,拷贝 CPSR 到 SPSR_fiq。第三,改变 CPSR 模式位的值,改到 FIQ 模式。第四,改变 PC
3、值,将其指向异常处理向量所指的下一条指令。离开异常处理的时候,第一,将 LR(R14_fiq )赋给 PC。第二,将 SPSR(SPSR_fiq )拷贝到 CPSR。第三,清除中断禁止标志(如果开始时置位了)。4异常中断向量异常中断的向量地址地址 异常中断类型 入口时处理器的操作模式0x00000000 复位 超级用户0x00000004 未定义指令 未定义0x00000008 软件中断 超级用户0x0000000c 中止(预取指) 中止0x00000010 中止(数据) 中止0x00000014 保留 保留0x00000018 IRQ IRQ0x0000001c FIQ FIQ异常中断优先级
4、中断 优先级复位 最高数据异常 FIQIRQ预取指异常中断未定义指令和软件中断 最低5当发生 IRQ 中断时第一,模式进入到 IRQ 里面。第二,PC 跳到 0x00000018 处运行。因为这是 IRQ 的中断入口。第三, 通过 0x00000018:LDR PC, IRQ_ADDR。跳转到相应的中断服务程序。这个里面就有个确定哪个中断源的问题了。那就有优先级的问题了。每个中断源会有自己的中断服务程序。第四,得到中断源有硬件实现和软件处理两种方式。比如 LPC21XX 的就是利用硬件方式,为了利用向量中断控制器的优点,IRQ 中断向量入口处代码做了修改,变成0x00000018:LDR PC
5、, PC, #-0xff0。这条指令从内存映射地址 0xfffff030 处获得数据装载到 PC,这样就能够直接从硬件中获得中断源。这样就减少了中断延迟。记得,三星的 S3C44B0 好象采用的是用软件确定中断源,因此要建立中断向量表。好久不用了,记不清了。第五,得到中断源,就知道要跳到哪个中断服务程序去了。一般都是这么定义的。Timer0_Handler HANDLER Timer0 。这种格式是调用一种宏定义,目的是保护现场,跳到中断服务程序。arm 中断机制通俗文章(二)(2012-04-13 10:09:48)转 载 标签: 杂谈分类: arm 硬件开发http:/ 转载请注明出处:h
6、ttp:/ S3C2440 系统中断CPU 和外设构成了计算机系统,CPU 和外设之间通过总线进行连接,用于数据通信和控制,CPU 管理监视计算机系统中所有硬件,通常以两种方式来对硬件进行管理监视: 查询方式:CPU 不停的去查询每一个硬件的当前状态,根据硬件的状态决定处理与否。好比是工厂里的检查员,不停的检查各个岗位工作状态,发现情况及时处理。这种方式实现起来简单,通常用在只有少量外设硬件的系统中,如果一个计算机系统中有很多硬件,这种方式无疑是耗时,低效的,同时还大量占用 CPU 资源,并且对多任务系统反应迟钝。 中断方式:当某个硬件产生需要 CPU 处理的事件时,主动通过一根信号线“告知”
7、CPU,同时设置某个寄存器里对应的位,CPU 一旦发现这根信号线上的电平有变化,就会中断当前程序,然后去处理发出该中断请求。这就像是医院重危病房,病房每张病床床头有一个应急按钮,该按钮连接到病房监控室里控制台一盏指示灯,只要该张病床出现紧急情况病人按下按钮,病房监控室里电铃会响起,通知医护人员有紧急情况,医护人员这时查看控制台上的指示灯,找出具体病房,病床号,直接过去处理紧急情况。中断处理方式相对查询方式要复杂的多,并且需要硬件的支持,但是它处理的实时性更高,嵌入式系统里基本上都使用这种方式来处理。系统中断是嵌入式硬件实时地处理内部或外部事件的一种机制。对于不同 CPU 而言,中断的处理只是细
8、节不同,大体处理流程都一样,S3C2440A 的中断控制器结构如下图所示:图 3-3 S3C2440 中断控制器中断请求由硬件产生,根据中断源类型分别将中断信号送到SUBSRCPND(SubSourcePending )和 SRCPND(SourcePending)寄存器,SUBSRCPND 是子中断源暂存寄存器,用来保存子中断源信号,SRCPND 是中断源暂存寄存器,用来保存中断源信号。中断信号可通过编程方式屏蔽掉,SUBMASK 是子中断源屏蔽寄存器,可以屏蔽指定的子中断信号, MASK 功能同 SUBMASK 用来屏蔽中断源信号。中断分为两种模式:一般中断的和快速中断,MODE 是中断模
9、式判断寄存器,用来判断当前中断是否为快速中断,如果为快速中断直接将快速中断信号送给 ARM 内核(为什么快速中断不需要仲裁,因为 arm 规定了快速中断只能有一个),如果不是快速中断,还要将中断信号进行仲裁选择。S3C2440A 支持多达 60 种中断,很有可能多个硬件同时产生中断请求,这时要求中断控制器做出裁决,Priority 是中断源优先级仲裁选择器,当多个中断产生时,选择出优先级最高的中断源进行处理,INTPND 是中断源结果寄存器,里面存放优先级仲裁出的唯一中断源。1 中断的产生-中断源S3C2440A 支持 60 种中断源,基本上满足了开发板内部,外部设备等对中断的需求。其中每一个
10、中断源对应寄存器中的一位,显然要支持 60 种中断至少需要二个 32 位寄存器,SUBSRCPND 和 SRCPND 分别保存中断源信号。S3C2440A 对 60 种中断源的管理是按层级分的。如图 3-4 所示:图 3-4 中断源信号复合示意图S3C2440A 将中断源分为两级:中断源和子中断源,中断源里包含单一中断源和复合中断源,复合中断源是子中断源的复合信号。如实时时钟中断,该硬件只会产生一种中断,它是单一中断源,直接将其中断信号线连接到中断源寄存器上。对于复合中断源,以UART 串口为例进行说明,S3C2440A 可以支持 3 个 UART 串口,每个串口对应一个复合中断源信号 INT
11、_UARTn,每个串口可以产生三种中断,也就是三个子中断:接收数据中断 INT_RXDn,发送数据中断 INT_TXDn,数据错误中断 INT_ERRn,这三个子中断信号在中断源寄存器复合为一个中断信号,三种中断任何一个产生都会将中断信号传递给对应的中断源 INT_UARTn,然后通过中断信号线传递给 ARM 内核。图 3-5 UART 串口中断源信号复合示意图总中断源详下面表中列出了 S3C2440A 部分中断源,它分别对应中断源寄存器里某个位:详细中断源请查看 S3C2440A 硬件手册。表 3-5 部分中断源信号中断源 描述 优先级仲裁分组INT_ADC 数模转换和触摸屏中断 ARB5I
12、NT_RTC 实时时钟中断 ARB5INT_UART0 UART0 中断(包含子中断) ARB5INT_NFCON NandFlash 控制中断 ARB4INT_WDT_AC97 看门狗中断 ARB1EINT8-23 外部中断 823(包含外部子中断) ARB1EINT4-7 外部中断 47(包含外部子中断) ARB1EINT3 外部中断 3 ARB0EINT2 外部中断 2 ARB0EINT1 外部中断 1 ARB0EINT 0 外部中断 0 ARB0中断信号除上述分法之外,还可以按照硬件位置分为:外部中断源和内部中断源。 内部中断源:它是嵌入式系统中常见硬件产生的中断信号,比如:UART
13、串口中断源,时钟 Timer 中断源,看门狗中断源等 外部中断源:有时嵌入式系统里要在外部接口上挂载一些外部设备,这些设备并不是一个通用嵌入式系统里必备硬件,比如:蓝牙模块,各种传感器,WIFI 无线通信模块,这些硬件也要产生中断让 CPU 来处理数据,因此这些外设硬件通过中断信号线连接到中断控制器上,它们产生的中断叫做外部中断信号。它们有着和内部中断一样的处理机制,只不过,它没有一个固定的中断号与之对应,硬件与嵌入式系统的连接方式与中断处理完全由系统硬件与软件设计者实现。外设硬件通过输入输出接口 I/O Ports 挂接到嵌入式系统上,I/O Ports 向外设提供外部中断信号线,输出电源,
14、频率时钟和输入输出信号线,外部硬件根据自己需要连接到 I/O Ports 上,产生中断时向外部中断信号线上送出中断信号,通过外部中断信号线传递到中断控制器。按键 Key 可以认为最为简单的一种硬件设备了,如下图所示:图 3-6 按键硬件接线原理图它功能很简单,可以将电路接通,按键 K1K6 一端接地为低电平,另外一端接电源正极为高电平,EINT8,EINT11,EINT13,EINT14 ,EINT15,EINT19 六根中断信号线分别和高电平端按键相连,当按键按下时电路接通,整个电路变成低电平,中断信号线上电压产生变化,通过设置中断触发方式,产生外部中断请求,输入到 CPU 内部,从而实现按
15、键中断控制。S3C2440A 可以支持 EINT0EINT23 共 24 种外部中断,完全可以满足小型嵌入式设备外设硬件的需求。外部中断源也分为外部中断源和外部子中断源,其处理方式和内部中断源基本一样。1.1.1 中断优先级S3C2440A 支持 60 种中断,多个硬件可能同时产生中断请求,由于 CPU 只能处理一个中断,中断控制器怎么选择出一个最佳的中断,交给 ARM 内核进行处理呢? 中断控制器采用优先级仲裁比较的方式进行选择,找出优先级最高的中断源。中断控制器将 60 种中断源分成 7 组,如下图所示,它类似体育赛事里的比赛方式,所有参赛选手在小组赛 PK,选择出小组赛最优秀选手,然后进
16、入决赛阶段和其它小组最优先选择再 PK,最后优胜者就是总冠军。其中 ARBITER0ARBITER5 为“小组赛”阶段,中断源信号在各自小组里进行优先级仲裁,选择出最高优先级中断信号,每小组选出的中断信号送到 ARBITER6,也就是决赛阶段,选择出最高优先级中断信号,交给 ARM 内核。图 3-7 S3C2440 优先级仲裁示意图中断信号在 7 个分组里 PK 时的优先级是可编程的,通过 PRIORITY 寄存器进行优先级设置。如下表(只列出 PRIORITY 寄存器部分位):表 3-6 中断优先级控制寄存器(PRIORITY)寄存器名 地址 是否读写 描述 复位默认值PRIORITY 0x
17、4A00000C R/W 中断优先级控制寄存器 0x7FPRIORITY 位 描述 初始值ARB_SEL6 20:19仲裁组 6 优先级排序方式00 = REQ 0-1-2-3-4-5 01 = REQ 0-2-3-4-1-510 = REQ 0-3-4-1-2-5 11 = REQ 0-4-1-2-3-50x00ARB_SEL5 18:17仲裁组 5 优先级排序00 = REQ 1-2-3-4 0001 = REQ 2-3-4-110 = REQ 3-4-1-211 = REQ 4-1-2-3 ARB_MODE6 6仲裁组 6 优先级是否轮转:0 = 不轮转, 1 = 轮转 1ARB_MOD
18、E5 5仲裁组 5 优先级是否轮转:0 = 不轮转, 1 = 轮转 1 通过设置仲裁组 n 优先级排序方式位,设置每个仲裁组内中断信号的优先级顺序,比如:ARB_SEL5 分组时包含四个中断信号:REQ1 INT_UART0, REQ2 INT_SPI1, REQ3 INT_RTC, REQ4 INT_ADC, ARB_SEL5 位采用默认值: 00,当 INT_UART0 和 INT_RTC中断信号同时产生时,INT_UART0 会被选出,通过可编程方式改变优先级排序方式来改变中断信号优先级。ARB_MODE0 ARB_MODE6 为每个仲裁分组的优先级轮转设置位,采用默认值时,当前中断信号
19、被选择处理之后,再次产生中断请求时,它的优先级自动轮转到该组最低,这样可以保证优先级低的中断信号可以被及时处理,不至于出现优先级高且中断请求频繁的中断每次都被优先处理,而优先级低的被“饿死”的情况。显然,这种方式更民主,实时性更佳。2 中断控制器相关寄存器(1)SUBSRCPND 子中断源暂存寄存器表 3-7 子中断源暂存寄存器(SUBSRCPND)寄存器名 地址 是否读写 描述 复位默认值SUBSRCPND 0x4A000018 R/W 子中断源暂存寄存器,保存中断请求状态:0:没有中断请求信号1:中断请求信号产生0x00000000SUBSRCPND 对应 SRCPND 位 描述 初始值R
20、eserved 无 31:15 未使用 0INT_AC97 INT_WDT_AC97 14 0 = 未产生中断 1 = 产生中断 0 INT_RXD0 INT_UART0 0 0 = 未产生中断 1 = 产生中断 0该寄存器用来标识保存子中断源信号,当某个子中断信号产生之后,SUBSRCPND 对应位被自动置 1,该位会一直保持被置位,只到中断处理程序将其清除为止,需要注意一下,清除中断是通过向对应位写入 1 来清除,而不是写入 0,写入 0 无效。(2)INTSUBMSK 子中断源屏蔽寄存器表 3-8 子中断源屏蔽寄存器(INTSUBMSK)寄存器名 地址 是否读写 描述 复位默认值INTS
21、UBMSK 0x4A00001C R/W 子中断源信号屏蔽存寄存器,设置相应位来屏蔽中断信号:0:未屏蔽,中断可用1:屏蔽中断信号0xFFFFINTSUBMSK 位 描述 初始值Reserved 31:15 未使用 0INT_AC97 14 0 = 未屏蔽 1 = 屏蔽中断 1 INT_RXD0 0 0 = 未屏蔽 1 = 屏蔽中断 1该寄存器用来屏蔽子中断源信号,默认值为全部子中断都被屏蔽掉,因此要想处理某个硬件中断,必须要打开中断屏蔽位,通过写入 0 来取消屏蔽中断。(3)SRCPND 中断源暂存寄存器表 3-9 中断源暂存寄存器(SRCPND)寄存器名 地址 是否读写 描述 复位默认值S
22、RCPND 0x4A000000 R/W 中断源暂存寄存器,保存中断请求状态:0:没有中断请求信号1:中断请求信号产生0x00000000SRCPND 位 描述 初始值INT_ADC 31 0 = 未产生中断 1 = 产生中断 0 EINT0 0 0 = 未产生中断 1 = 产生中断 0该寄存器用来保存中断源信号,当某个中断信号产生之后, SRCPND 对应位被自动置 1,该位会一直保持被置位,只到中断处理程序将其清除为止,需要注意一下,清除中断是通过向对应位写入 1 来清除,而不是写入 0,写入 0 无效。(4)INTMSK 中断源屏蔽寄存器表 3-10 中断源屏蔽寄存器(INTMSK)寄存
23、器名 地址 是否读写 描述 复位默认值INTMSK 0x4A000008 R/W 中断源信号屏蔽存寄存器,设置相应位来屏蔽中断信号:0:未屏蔽,中断可用1:屏蔽中断信号0xFFFFFFFFINTMSK 位 描述 初始值INT_ADC 31 0 = 未屏蔽 1 = 屏蔽中断 1 EINT0 0 0 = 未屏蔽 1 = 屏蔽中断 1该寄存器用来屏蔽中断源信号,默认值为全部中断都被屏蔽掉,因此要想处理某个硬件中断,必须要打开中断屏蔽位,通过写入 0 来取消屏蔽中断。(5)INTPND 最高优先级中断暂存寄存器表 3-11 最高优先级中断暂存寄存器(INTPND)寄存器名 地址 是否读写 描述 复位默
24、认值INTPND 0x4A000010 R/W 最高优先级中断暂存寄存器里面保存有经过优先级仲裁的结果:0:没有中断请求信号1:中断请求信号产生0x00000000INTPND 位 描述 初始值INT_ADC 31 0 = 未产生中断 1 = 产生中断 0 EINT0 0 0 = 未产生中断 1 = 产生中断 0该寄存器保存了经过优先级仲裁出的中断信号位,它是所有当前中断请求里优先级别最高的中断,因此该寄存器里的值最多有一位被置 1,通常中断处理程序中会通过读取该寄存器的值来获得当前正在处理的中断请求。中断处理完成之后,通过写入 1 来清除中断。(6)INTOFFSET 中断号偏移量寄存器表
25、3-12 中断号偏移量寄存器(INTOFFSET)寄存器名 地址 是否读写 描述 复位默认值INTOFFSET 0x4A000014 R 中断号偏移量寄存器,用来保存当前处理的中断号0x0000000该寄存器里存放的是经过优先级仲裁出的中断信号对应的中断号,是一个 031 之间的整数,其实它就是 INTPND 里对应的位号,比如:INT_UART0 产生了中断,INTPND 里第 28 位置 1,INTOFFSET 里保存的整数就是 28,多出来这个寄存器的目的主要是方便中断处理程序查询中断源,清除中断源:#define TIMER0_IRQ_OFT 10 / 时钟 0 定时中断#define
26、 EINT0_IRQ_OFT 0 / 开发板 K1 按键 1 对应外部中断 EINT0void handle_irq()unsigned long irqOffSet = INTOFFSET; / 取得中断号switch(irqOffSet)case TIMER0_IRQ_OFT: / 当前中断为定时器 0 中断do_timer(); / 跳入定时器 0 处理程序break;case EINT0_IRQ_OFT: / 当前中断为 K1 按键触发do_key1_pressed(); / 处理 K1 按下事件break;SRCPND / 清除中断源INTPND = INTPND; / 清除最高优先级中断暂存寄存器中断(7)INTMOD 中断模式寄存器表 3-13 中断模式寄存器(INTMOD )寄存器名 地址 是否读写 描述 复位默认值INTMOD 0x4A000004 R/W 中断模式寄存器,指定对应中断模式:0 = IRQ 一般中断模式1 = FIQ 快速中断模式0x0000000INTMOD 位 描述 初始值INT_ADC 31 0 = IRQ 1 = FIQ 0 EINT0 0 0 = IRQ 1 = FIQ 0通过设置 ARM 内核产生中断。需要注意的是,快速中断不存在优先级仲裁,只能有一位被设置为