Chinaunix首页 | 论坛 | 博客
  • 博客访问: 227009
  • 博文数量: 18
  • 博客积分: 3295
  • 博客等级: 少校
  • 技术积分: 431
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-26 19:11
文章分类
文章存档

2010年(18)

分类: LINUX

2010-11-22 22:18:43

中断是指计算机在执行程序的过程中,当出现异常情况或特殊请求时,计算机停止现行程序的运行,转向对这些异常情况或特殊请求的处理,处理结束后再返回现行程序的间断处,继续执行原程序。中断可以效的提高CPU的利用效率和程序运行的效率。本章对中断的学习进行一下总结。 

介绍 、中断的相关概念

1)        异常

在处理器执行到由于编程失误而导致的错误指令(例如除数是0)的时候,或者在执行期间出现特殊情况(例如缺页),需要靠操作系统来处理的时候,处理器就会产生一个异常。对大部分处理器体系结构来说,处理异常和处理中断的方式基本是相同的,x86架构的CPU也是如此。异常与中断还是有些区别,异常的产生必须考虑与处理器时钟的同步。实际上,异常往往被称为同步中断。

2)        中断向量

中断向量代表的是中断源――从某种程度上讲,可以看作是中断或异常的类型。中断和异常的种类很多,比如说被0除是一种异常,缺页又是一种异常,网卡会产生中断,声卡也会产生中断,CPU如何区分它们呢?中断向量的概念就是由此引出的,其实它就是一个被送往CPU数据线的一个整数。CPU给每个IRQ分配了一个类型号,通过这个整数CPU来识别不同类型的中断。这里可能很多朋友会寻问为什么还要弄个中断向量这么麻烦的东东?为什么不直接用IRQ0~IRQ15就完了?比如就让IRQ00IRQ11……,这不是要简单得多么?其实这里体现了模块化设计规则,及节约规则。

3)        中断服务程序(ISRInterrupt Service Routine

在响应一个特定中断的时候,内核会执行一个函数,该函数叫做中断处理程序(interrupt handler)或中断服务程序(interrupt service routine(ISR))。产生中断的每个设备都有相应的中断处理程序。例如,由一个函数专门处理来自系统时钟的中断,而另外一个函数专门处理由键盘产生的中断。一般来说,中断服务程序要负责与硬件进行交互,告诉该设备中断已被接收。此外,还需要完成其他相关工作。比如说网络设备的中断服务程序除了要对硬件应答,还要把来自硬件的网络数据包拷贝到内存,对其进行处理后再交给合适的协议栈或应用程序。每个中断服务程序根据其要完成的任务,复杂程度各不相同。一般来说,一个设备的中断服务程序是它的设备驱动程序(device driver)的一部分――设备驱动程序是用于对设备进行管理的内核代码。

ARMCPU7种工作模式

1.         用户模式(USR):ARM处理器正常的程序执行状态。

2.         快速中断模式(FIQ):用于高效数据传输或通道处理。

3.         中断模式(IRQ):用于通用的中断处理。

4.         管理模式(SVC):操作系统使用的保护模式。

5.         数据访问终止模式(ABT):当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护。

6.         系统模式(SYS):运行具有特权的操作系统的任务。

7.         未定义指令中终止模式(UND):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。

以上七种工作模式可以通过软件来进行模式切换,或者发生各类中断、异常时CPU自动进入相应的模式。除了用户模式外,其它6种工作模式均为特权模式。大部分程序是运行在用户模式状态下的,进入特权模式是为了处理中断、异常或者是访问被保护的系统资源。

另外,ARM体系的CPU有以下两种状态:

ARM状态:此时CPU执行32的字对齐指令。

THUMB状态:此时处理器执行的是16位的半字对齐的指令。

CPU一上电就是处于ARM状态的,博客中的程序也是ARM状态的。

、中断的处理过程

1)        中断控制器汇集各类外设发出的中断信号,然后告诉CPU

2)        CPU保存当前程序的运行环境,调用中断服务程序处理中断。

3)        在中断服务程序中通过读取中断控制器、外设的相关寄存器来识别这是个哪个中断,并进行相应的处理。

4)        清除中断:通过读写中断控制器和外设的相关寄存器来实现。

5)        中断返回:最后恢复被中断程序的运行环境,继续执行。

对于不同的CPU,中断处理的过程可能细节上略有不同,但这里要注意,有些初学者对中断返回有些误解,请大家记住:从哪里中断,返回到哪里。

FIQIRQ

为什么要有中断呢?那是因为外设的速度远远低于CPU的速度,如果让CPU一直等待外设的话,那么效率就低得可怜了,因此才会有中断的概念被引出,它的目的也正是为了更好的、更高效的完成工作。

那么IRQ是普通中断,FIQ是又是什么呢?两者有什么区别呢?这里主要体现嵌套和原子性的概念。

也就是说,IRQ中断是可以嵌套的,即在执行一个IRQ服务程序的时候,更高级的中断可以打断它,从而执行一个新的中断。而FIQ是具有原子性的,是不可以被打断,直至完成整个FIQ

S3C2440中断体系介绍 、中断处理过程

SUBSRCPND

SRCPND寄存器表明有哪些中断被触发了,正在等待处理(Pending);SUBMASKINTSUBMSK寄存器)和MASKINTMSK寄存器)用于屏蔽某些中断。

1)         Request sourceswithout sub-register)中的中断源被触发后,SRCPND寄存器中相应位被置1,如果此中断没有被INTMSK寄存器屏蔽或者快速中断的话,它将被进一步处理。

2)         Request sourceswith sub-register)中的中断源被触发后,SUBSRCPND寄存器中相应位被置1,如果此中断没有被INTSUBMSK寄存器屏蔽的话,它在SRCPND中相应位也会被置1

3)         如果被触发的中断中有快速中断的话,CPU会进入快速中断模式进行处理。

4)         对于一般的中断,可能同时有几个中断被触发,未被INTMSK寄存器屏蔽的中断经过比较后,选出优先级最高的中断,此中断在INTPND寄存器中的相应位被置1,然后CPU进入中断模式进行处理。中断服务程序可以通过读取INTPND寄存器或者INTOFFSET寄存器来确定中断源。

Priority表示中断的优先级判决,通过PRIORITY寄存器进行设置。

、中断的处理步骤

1)         设置好中断模式和FIQ模式下的栈

2)         准备好中断处理函数(中断服务程序)

a)         在异常向量表中设置好相应的跳转函数,异常向量地址0x000000180x0000001c

b)         中断服务程序(ISR

对于IRQ,读出INTPND寄存器或INTOFFSET寄存器来判断中断源,然后分别处理。

对于FIQ,因为只有一个中断,无需判断。

c)         清除中断

可以在调用ISR之前清除中断,也可以在调用之后清除,这取决于ISR执行过程中,这个中断是否可能继续发生、是否能够丢弃。如果在ISR执行过程中可能发生并不能丢弃,那么就在ISR执行之前清除,否则可以在ISR之后清除。

3)         进入、退出中断模式和FIQ模式时需要保存、恢复被中断程序的运行环境。两种方式在寄存器(r0-r15)的使用上不同。请详见手册。

4)         根据具体的中断、设置相关外设。比如对于GPIO中断,应设为外部中断,设置中断触发条件(低电平触发、高电平触发、下降沿还是上升沿触发等等)。

5)         对于Request sourceswithout sub-register)中的中断,将INTSUBMSK寄存器中相应的位设为0

6)         确定使用IRQ还是FIQ,如果是FIQ,应在INTMOD的寄存器相应位设为1;如果是IRQ,则应设置PRIORITY优先级。

7)         如果是IRQ则应在INTMSK的相应位设置为0FIQ不受INTMSK影响。

8)         设置CPSRI-bitF-bit位为0,使能IRQFIQ

、中断控制器寄存器

SUBSRPNDINTSUBMSK这两个寄存器中相同的位对应相同的中断;SRCPNDINTMSKINTMODINTPND4个寄存器中相同的位对应相同的中断。

下面来介绍一下主要用的寄存器,其它的寄存器请详见手册。

1)         SUBSRCPND 子中断源未决寄存器 (R/W

S3C2440支持15个子中断源,每一位对应一个,该寄存器标识这些中断是否发生。当这些中断发生且没有被中断屏蔽寄存器屏蔽,则它们中的若干位将“汇集”到SRCPND寄存器的相应位上。比如INT_RXD0INT_TXD0INT_ERR0,只要有一个发生了中断且没有被屏蔽,则SRCPND寄存器的INT_UART0就会被置1

要清除中断是,需要向该位写“1”。

2)         INTSUBMSK 子中断源屏蔽寄存器 (R/W

用来屏蔽SUBSRCPND寄存器中的子中断源,某位置1时,对应该位的中断被屏蔽。

3)         SRCPND   中断源未决寄存器(R/W

该寄存器中的某一位用来表示一个或一类的中断是否已发生,若想清除中断,应向相应位写1

4)         INTMSK   中断源屏蔽寄存器 (R/W

用来屏蔽SRCPND中的中断,写1屏蔽,但只能屏蔽IRQ,无法屏蔽FIQ

5)         INTMOD   中断模式寄存器(R/W

用来选择是IRQ还是FIQ,写1代表FIQ注意:同一时间只能一位被置1,因为只能有一个FIQ

6)         PROORITY    优先级寄存器 (R/W

用来设置IRQ中断的优先级。

7)         INTPND   中断未决寄存器 (R/W

经过中断优先级仲裁器选出优先级最高的中断后,这个中断在该寄存器的相应位被置1,随后,CPU将进入中断模式来处理它。同一时间只能有一位为1,清除中断时,向其写1

8)         INTOFFSET  中断偏移寄存器 (R

用来表示INTPND中的哪位被置1了,如果是[X]位被置1了,该寄存器的值就为X。清除SRCPNDINTPND寄存器时,该寄存器自动被清除。

整个程序由head.Sinit.cinterrupt.cmain.c组成的。在读程序前,请先查看TQ的原理图,明确以下几点:

1、 LED1~LED4对应着GPB5~GPB8

2、 K1对应EINT1

K2对应EINT4

K3对应EINT2

K4对应EINT0

程序完成按下Kx键点亮相应的LEDx,其中x1~4,例如:按下K1键点亮LED1

程序由中断函数完成,4个中断的优先级为:K4 > K1 > K3 > K2

程序我已完善注释,请大家一边看程序,一边看下面的博客内容。

Head.S

该文件为整个程序的入口,也为程序的代码段(text)开始处,第一条是存放在地址0x0处的,即“b Reset”的地址为0x0。请大家参考反汇编文件int.dis,前面的第19232731353842七行就是所谓的异常向量,当发生异常时,就从异常向量处运行。因为程序处于ARM状态,每句占4个字节,因此七句为七个向量。

本程序只用到Reset和中断,其它异常向量没有实际作用。

该文件中的初始化看门狗、初始化LED、初始化中断函数都在init.c文件中实现。

中断服务函数(EINT_Handle)在interrupt.c文件中实现。

将编译好的程序烧写到TQ2440后,先按下K1~K4,对应的LED会发光,其余的不亮。

请大家自行试试中断的优先级,按住高优先级的按键不放,再按低优先级的按键LED会没有反应;反之,先按下低优先级的按键不放,再按下高优先级的按键会点亮LED

1.韦东山 《嵌入式LINUX应用开发完全手册》

2.三星  《S3C2440手册》

3.

阅读(3062) | 评论(5) | 转发(3) |
给主人留下些什么吧!~~

whq200808082010-12-15 23:26:53

machoe: 这是一个指针。.....
我知道是指针啊,不过后来发现凡是只用到八位的就用unsigned char 而用到32位的就用unsigned long,说明,这个指针定义成char型的只寻址八位,这样的话可以节省空间,这样理解对吗?

machoe2010-12-15 22:34:34

whq20080808: (*(volatile unsigned char *)0x4e000008) unsigned char 不是两个字节吗?怎么会存的下八个字节?还有为什么这里用unsigned char?习惯问题吗?.....
这是一个指针。

machoe2010-12-15 22:34:01

whq20080808: #define NFCMD               (*(volatile unsigned char *)0x4e000004)是定义NAND FLASH寄存器时用到的.....
请对应手册中的寄存器读程序

whq200808082010-12-15 22:07:33

#define NFCMD               (*(volatile unsigned char *)0x4e000004)是定义NAND FLASH寄存器时用到的

whq200808082010-12-15 22:04:11

(*(volatile unsigned char *)0x4e000008) unsigned char 不是两个字节吗?怎么会存的下八个字节?还有为什么这里用unsigned char?习惯问题吗?