一.中断的场景模拟
----------------------------------------------------------------------------
中断(Interrupt)是最常用的硬件通知软件的机制。中断的优点相对另一种机制轮询(Polling)的缺点而言,这两种的机制我们考虑如下大家比较熟悉的场景.
以学生上晚自习为例,老师这里也坐在讲台上备课,改作业,试卷。其中不时会有学生举手来示例老师下来辅导。这个场境一般中学生都经历过。
这里的老师相当是CPU,学生相当是外设。老师下来的辅导相当于CPU处理外设的请求。老师辅导的策略有两种办法。一种是老师改一段时间的卷子,然后下去查看一下学生是否有问题要辅导。另外一种就是学生有问题主动举手来请老师下来辅导。
第一种策略称为轮询.它的问题导致老师的工作效率低下。因为每次老师停下手头事去查看学生情况,但是可能学生未必有问题提出,这样浪费老师大量时间。轮询的优点是执行比较简单。
第二种方法就是中断,老师在讲台上全速修改试卷或备课。当学员有问题再举手示意请老师下来辅助。中断的优点是外设与CPU都能用较高速度运行。缺点就是执行起来动作比较复杂。
这里有几个概念.
在中断活动中,学生相当于外设,也称为中断源(interrupt source)。学生的问题五花八门。因此每一个问题我们会编上号称为中断号(interrupt number),在嵌入式编程里,中断号是一个无符号整数,每一个中断号代表一个固定的问题。
如果同时有多个学生请求辅导,则按老师按一定的规则来辅导,通常是由近至远。这种处理先后顺序称为中断优先级(interrupte PRIORITY)。优先级软件是可以调整的。
如果某一些学员优先级很高,比如他可以用同时用声音来呼叫老师。这种有较高的优先级中断称为快速中断请求(FIQ ,Fast Interrupte Request),其余的中断称为中断请求 (IRQ ,Interrupte Request).
在同一时刻,只有一个中断能被设为FIQ,否则CPU就将会无法处理,就象一个教室里同时有两个大嗓门在同喊将会产生混乱。
学生通知老师的方式称为中断信号(Interrupte signal).这都是事先约定,在嵌入式CPU里,一般两类中断信号,一种电平触发信号,一种是边缘触发信号.
以低电平触发信号为例,中断脚平时维持高电平状态,一但有中断产生,会产生一段时间的低电平。这样CPU就知道外面来中断了。
边缘触发的中断,是指当中断脚平时维持高电平,有中断产生时,电平由高电平切换到低电平,在切换时CPU就知道来中断了,由低电平切换到高电平的触发,称为上升沿触发,由高电平切换到低电平的触发称为下降沿触发
老师的脑海钟对不同问题有对应的辅导方法, 我们称为这种辅导方法称为 ISR(Interrupte Service Routing),它完全是软件实现的。但是由老师来根据中断号来调用。
因此嵌入式软件里的中断处理,除了中断初始化,主要工作就是编写ISR.
在嵌入式的SOC的CPU里,在CPU里内部会带一些设备模块,它们产生的中断称为内部中断。因为联线比较固定,因此编程比较简单。而且在物理上CPU分离的芯片产生的中断,称为外部中断,外部中断可以联接不同的中断脚上,因此需要对中断IO进行较复杂的配置。
轮询模式是否一无是处?轮询的优点是在重负荷的情况下,轮询比中断效率会高很多。比如一个教室很多学生不断的问问题,这样与其不断被中断,老师还不如起身在教室走动,随机处理学生问题会高很多。
二.异常(Exception)
--------------------------------------------------------------------------
Exception(异常),计算机体系结构中,异常或者中断是处理系统中突发事件的一种机制,几乎所有的处理器都提供这种机制。异常主要是从处理器被动接受的角度出发的一种描述,指意外操作引起的异常。而中断则带有向处理器主动申请的意味。但这两种情况具有一定的共性,都是请求处理器打断正常的程序执行流程,进入特定程序的一种机制。
从结构来看,外部设备产生的中断可以看成一种特殊的异常.除了中断之外,还有ARM不少固定的异常.包括以下七种:
1. 复位(Reset)
当按下RESET键后,会产生一个复位异常,此时程序跳转到复位异常处理程序处执行.当CPU重启后.一般刚好跳到这个复位异常来
2. 未定义指令
当ARM的处理器或协处理器遇到不能处理的指令时,产生未定义指令异常,采用这个机制,可以通过软件仿真扩展ARM或Thumb 指令集.
3. 软件中断(SWI)
硬件中断是有固定的硬件产生的中断,而软中断是指没具体的硬件产生,是CPU虚拟出来的.该异常由程序执行汇编SWI产生.软中断的优点,
l 可用于用户模式下的程序调用特权操作指令.Linux 系统调用就是使用这个异常来实现的.
l 有利用程序结构的优化.比如在Linux 驱动里,硬件中断不能长时间运行.但是很多软件的长时间操作依赖的于中断的调用.有时为解决这个冲突,会在驱动设计两级,从硬件存取用硬件中断,而长时间操作用软件中断的模拟.
4. 指令预取中止
若处理预取的指令的地址不存在,或该地址不允许当前指令访问,存储器会向处理器发出中止信号,但当预取的指令被执行时,才会产生指令预取中止的异常.比如用ADS把程序下载到开发板上0x8000地址上.就会产生Abort异常.
5. 数据中止
若处理器数据访问数据的地址不存在,或该地址不允许当前指令访问时,产生数据中止异常
6. IRQ
当外部设备在外部中断脚产生中断信号时.即触发了IRQ中断.这是外部设备使用最常用的一种手段.
在S3C24X0是一个集成的SOC,内部除了ARM模块以外.还其它内部集成的模块,如USB,RTC,等.这一些模块在CPU内部也会有相应的中断线连到ARM920T的内核上.但这一些管脚在CPU外部是不可见的,只能用于寄存器去控制.
还一些GPIO脚就充当外部中断控制线,外部IC可以把自己中断信号线连到相应的中断脚上.当外部产中断信号后,CPU就可以知道,外设有中断发来.
7. FIQ
快速中断,类似于IRQ,但是具有较快响应速度.而且设为FIQ的条件也比较严格,比如一次触发只能有一个FIQ
一句话,中断(IRQ,FIQ,SWI)是异常中的一个特例。当产生外部中断时,大部分CPU会只产生一个异常。在异常处理程序里软件再去读不同的中断寄存器分析后来调用ISR。这里ISR是由软件来执行的。象S3C2440就是这样机制。
在S3C6410中,还可以采用简化的中断处理流程。由CPU直接去调用中断的ISR来处理。 这样中断处理软件的编写难度就大大下降了。
向量(vector)
异常处理函数或中断处理函数的地址都会按中断号的顺离顺序排列在一个连续的内存当中,从C语言的角度来看,可以看成是一个指针数组。数组又称为向量(Vector).
如果你熟悉S3C2440的中断处理机制,可以发现S3C6410大大简化的中断编程处理。
相对于S3C2440详细而丰富的关于中断的解释,S3C6410的dataSheet明显是赶工之作,关于中断只有短短的15页,大量内容还是寄存器表格。
因此以下大部分我从S3C6410的测试程序和Application Note反推出来的。并且重新用ADS写程序验证了。
S3C6410的中断主要改进是.
增加中断向量控制器,这样在S3C2440里需要用软件来跳转的中断处理机制,在S3C6410完全由硬件来跳转。你只要把ISR地址是存在连续向量寄存器空间,而不是象S3C2440自行分配空间自行管理。
换句话说,在S3C2440下是由CPU触发IRQ/FIQ异常,由异常处理函数里再查找相关中断寄存器来跳到指定的ISR,而可以全部由S3C6410的VIC硬件来自动处理。 这个大大简化中断处理编程。
另一个是外部中断加入滤波电路,这样原来需要软件去毛刺的地方均可以采用硬件来进行滤波了,这样大大简化外部中断处理。
S3C6410 中断操作
--------------------------------------------------------------------
S3C6410 中断号
64个中断按硬件分组分成VIC0, VIC1两个组,各组由一个相应寄存器来处理。
中断号为0-31是VIC0组
中断号为32-63是VIC1组
S3C6410中断操作很简单。
打开中断 VICxINTENABLE
x为0,1,0-31中断使用VIC0INTENABLE,32-63中断使用VIC1INTENABLE.以下各寄存器均同,不再重复.
对应位为1表示这个中断可用,如0号中断有效,是VIC0INTENABLE的第0位为1
关闭一个中断
向VICxINTENCLEAR对应位置1表示关闭这个中断.
这个是三星比较明智的改进,不会让开发感到比较迷惑的地方
设置中断类型
设置某一个中断是IRQ还是FIQ,注意只有一个中断才能FIQ.设置对应位1表示设为FIQ模式。
设置S3C6410的向量地址(ISR地址)
注意在S3C6410自已从了各用32个地址连续的寄存器然成两个寄存器数组。首地址分别是0x71200100和0x71300100.你可以象指针数组一样来操作它们,数组的下标就是中断号。
这样设置让开发者大大简单化ISR的向量组织。
设置中断优先级
这个也采用用32*2寄存器形成两个优先级数组。每一个寄存器对应优先级别,取值范围在0-15之间.
中断运行后指示
这个因为了用VIC,现在省掉了S3C2440一大堆的SRCPND,INTPND,INTOFFSET,SUBSRCPND等寄存器。直接由VICxADDRESS来指示当前的ISR地址。
注意这个VICxADDRESS的寄存器,在S3C6410里称为在System BUS.调用。这种方式不建议调用,因为这种模式相当于S3C2440的用软件进行ISR跳转.
这三星的给的参考流程。
更为简单的调用方式.是VIC port 模式,是我强烈推荐的模式,它是系统产生中断后,将由VIC直接去执行相应的ISR。这不仅上编程变成简单,而且效率上更快,因为它没有访问VICxADDRESS和在System BUS执行的时间
使用这种模式,只需要在启动加上特定的代码
外部中断编程
----------------------------------------------------------
除INT_EINT0-INT_EINT4以外,全部中断是由S3C6410内部的模块触发的。称为内部中断
INT_EINT0-INT_EINT4是外部中断,是由CPU外的外设来触发的,它的触发哪一个中断取决外设联接哪一个GPIO中断脚。
象开发板的网络控制器,按钮等都是挂在某一些GPIO脚上。它们都是使用典形外部中断.
外部中断脚
S3C6410 分9组GPIO脚来充当外部中断脚
第0组,共28脚.GPN0-GPN15 (16脚),GPL8-GPL14(7脚),GPM0-GPM4 (5脚)
第1组,由GPA0-GPA7,共8个中断脚
第2组,由GPC0-GPC0,共8个中断脚…
…
第8组,由GPP0-GPP14,共15个中断脚
第9组,由GPQ0-GPQ8,共9个中断脚
外部中断号
第0组的第0脚到第3脚的设备将触INT_EINT0=0中断
第0组的第4-11脚将触发INT_EINT1=1中断
第0组的第12-19脚将触发INT_EINT2=32中断
第0组的第20-27脚将触发INT_EINT3=33中断
第1组-第9组所有设备只触发INT_EINT4=53中断
我们可以看到,每一个组都是多个中断脚共享一个中断号的。其中第0组比较常用。占用了3个中断.
在ISR中,如何判断是哪一个中断脚的产生中断?
不同的IO脚上多个设备产生同一个中断,软件如何知道是哪一个脚?
由External Interrupt Pending Register 来判断
第0组由EINT0PEND来判断
第1,2组由EINT12PEND来判断
依此类推,EINT34PEND,EINT56PEND, 一直到EINT9PEND 来指示
外部中断信号类型
这里设置中断产生何种信号才会被捕获。主要是五种,低电平,高电平,上升沿,下降沿或者两者均可,
第0组用 EINT0CON0/EINT0CON1两个寄存器来设定.
第1,2组采用 EINT12CON ,
第3,4组采用EINT34CON,
依此类推
临时关闭外部中断
EINTxMask是临时性关闭中断
为1表示关闭某一个中断,为表示打开0,一般只要需要使用中断才会打开。
EINT0MASK是第0组的使用
EINT12MASK是第1,2组的中断掩码
依次类推...
定义硬件滤波类型
对于一些波形不规整的外部中断信号,可以通过滤波电路让其变成规整,这样会简化软件的编写.
S3C6410有两种滤波电路,一种延时滤波(如按钮类中断可以采用这一类型),一种是数字采样滤波.第二种滤波电路还要设采样宽度。
第0组的滤波用EINT0FLTCON0,EINT0FLTCON1, EINT0FLTCON2, EINT0FLTCON3配置.
FLTEN表示是否打开滤波功能,FLTSEL是设置滤波方式,EINTn表示数字滤波采校的宽度
第1,2组的滤波采用 EINT12FLTCON
第3,4组的滤波采用 EINT34FLTCON
第9组滤波 采用EINT9FLTCON
外部中断编程
外部中断除了中断编程所有流程外,
一般额外配置相应的GPxCON配置成中断脚。
还要配置滤波方式和中断信号方式。
还要打开外部中断掩码
在ISR中,在最后除了要把VICxADDRESS清0外,还需要清除 VICxSOFTINTCLEAR相应位。
软件中断编程
-------------------------------------------------------------
在S3C6410有64个软中断(与硬件中断对应),这一段描述是非常含糊。是同一硬件中断可以用软件触发还是是,有一个完全对应的软件中断?这个需要软件来验证.
软中断除硬件中断的所有流程还要加上如下两条.
用VICxSOFTINT来触发软中断
ISR退出时使用VICxSOFTINTCLEAR清除状态
软中断编程流程
文章评论(0条评论)
登录后参与讨论