100427张家庆嵌入式系统论文.docx
《100427张家庆嵌入式系统论文.docx》由会员分享,可在线阅读,更多相关《100427张家庆嵌入式系统论文.docx(11页珍藏版)》请在冰豆网上搜索。
![100427张家庆嵌入式系统论文.docx](https://file1.bdocx.com/fileroot1/2022-12/12/b064b557-569e-4a4e-b6a7-12630a79d8a5/b064b557-569e-4a4e-b6a7-12630a79d8a51.gif)
100427张家庆嵌入式系统论文
嵌入式系统论文
————SEP3203中断和异常相应机制
姓名:
张家庆
学号:
1004220247
指导老师:
陈文武
摘要
现代嵌人式操作系统中,中断处理技术是一项重要的技术。
通过中断技术,使得处理器能够和外设并行地工作,提高了CPU的执行效率。
首先分析了SEP3203的中断响应机制,然后介绍了中断向量表的软件实现,最后分析了异常发生的硬件操作以及处理返回。
关键字:
ARM,SEP3203,中断,异常
一、概述
ARM(AdvancedRISCMachines),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。
1991年ARM公司成立于英国剑桥,主要出售芯片设计技术的授权,作为知识产权供应商,本身不直接从事芯片生产,靠转让设计许可由合作公司生产各具特色的芯片,世界各大半导体生产商从ARM公司购买其设计的ARM微处理器核,根据各自不同的应用领域,加入适当的外围电路,从而形成自己的ARM微处理器芯片进入市场。
目前,采用ARM技术知识产权(IP)核的微处理器,即我们通常所说的ARM微处理器,已遍及工业控制、消费类电子产品、通信系统、网络系统、无线系统等各类产品市场,基于ARM技术的微处理器应用约占据了32位RISC微处理器75%以上的市场份额,ARM技术正在逐步渗入到我们生活的各个方面。
SEP3203处理器内嵌由英国ARM公司提供的ARM7TDMI处理器内核,全芯片可稳定运行在75MHz。
集成了支持黑白,灰度,彩色的LCD控制器;多媒体加速模块,用于提供多媒体处理定点矢量乘加的计算能力;支持低成本的NANDFlash控制器并可从其直接启动;支持多种外存类型:
SRAM,NORFlash,SDRAM;支持实时时钟(RTC);支持四通道的定时器和两通道的PWM;支持用于连接触摸屏通讯的SPI协议;支持两个UART控制器,其中一个支持红外传输;支持USB1.1Device控制器用于PC与移动终端之间的高速信息传输;支持MMC卡控制器,用户可以扩展系统的存储能力和外设功能;支持兼容AC97协议的控制器,用于音频文件的播放和录制。
SEP3203处理器内嵌20KByte零等待的静态存储器(SRAM),用于多媒体处理时的核心代码与数据的存放,用户也可以将操作系统的核心代码或LCD帧缓存存放在该处理器中,用于提供更高的性能和更低的能量消耗;6通道DMA控制器,为用户提高了高速的数据传输通道。
为了支持低成本的系统方案,SEP3203支持外部32位/16位数据总线,结合ARM提供的Thumb指令集,将大大降低系统成本和功耗,考虑到NandFlash的成本优势,SEP3203处理器提供专用的NandFlash控制器,并支持系统直接从NandFlash启动。
SEP3203处理器采用LQFP176封装形式。
二、SEP3203的中断响应机制
1.中断延时
从外部请求信号发出到取出对应的中断服务程序(ISR)的第一条指令,这期间的间隔时间。
2.中断过程
ARM体系中通常在存储地址的低端固化了一个32字节的硬件中断向量表,用来指定各异常中断及其处理程序的对应关系。
当一个异常出现以后,ARM微处理器会执行以下几步操作:
1)保存处理器当前状态、中断屏蔽位以及各条件标志位;
2)设置当前程序状态寄存器CPSR中相应的位;
3)将寄存器lr_mode设置成返回地址;
4)将程序计数器(PC)值设置成该异常中断的中断向量地址,从而跳转到相应的异常中断处理程序处执行。
在接收到中断请求以后,ARM处理器内核会自动执行以上四步,程序计数器PC总是跳转到相应的固定地址。
三、ARM核下的多中断源处理方案
ARM核只有一个常规中断引脚nIRQ,而在现代嵌入式系统中,中断源可能多达几十个.为此,在系统设计时,采用了二级中断的方式来实现中断控制。
即由一个中断控制器来处理来自不同中断源的中断信号,经过判断后将中断信号送给ARM内核的中断引脚。
SEP3203内集成的中断控制器支持32个普通中断源,并给这32个普通中断源分配了固定的优先级。
每个中断源相应的可以配置为硬件中断或软件强制中断。
当硬件中断或软件强制中断产生的时候,都可以产生mQ中断信号。
基于硬件的架构,软件系统在实现中断向量的初始化时要构建2级向量表,如图所示。
第一级为ARM核的异常向量表(普通向量表),第二级由具体CPU中断控制器控制的异常向量表——通常第二级向量表是IRQ异常处理向量表(特殊向量表)。
B
Irqdesc()
Irqdesc{}
0x1c
0x18
0x14
Irq[3].action
Irq[2].action
Irq[1].action
0x10
0x0c
0x08
0x0
0x00
两级中断向量表
四、ARM7的异常响应机制
所谓异常就是正常的用户程序被暂时中止,处理器就进入异常模式,例如响应一个来自外设的中断,或者当前程序非法访问内存地址都会进入相应异常模式。
1.异常分类
(1)复位异常
当CPU刚上电时或按下reset重启键之后进入该异常,该异常在管理模式下处理。
(2)一般/快速中断请求
CPU和外部设备是分别独立的硬件执行单元,CPU对全部设备进行管理和资源调度处理,CPU要想知道外部设备的运行状态,要么CPU定时的去查看外部设备特定寄存器,要么让外部设备在出现需要CPU干涉处理时“打断”CPU,让它来处理外部设备的请求,毫无疑问第二种方式更合理,可以让CPU“专心”去工作,这里的“打断”操作就叫做中断请求,根据请求的紧急情况,中断请求分一般中断和快速中断,快速中断具有最高中断优先级和最小的中断延迟,通常用于处理高速数据传输及通道的中数据恢复处理,如DMA等,绝大部分外设使用一般中断请求。
(3)预取指令中止异常
该异常发生在CPU流水线取指阶段,如果目标指令地址是非法地址进入该异常,该异常在中止异常模式下处理。
(4)未定义指令异常
该异常发生在流水线技术里的译码阶段,如果当前指令不能被识别为有效指令,产生未定义指令异常,该异常在未定义异常模式下处理。
(5)软件中断指令(SWI)异常
该异常是应用程序自己调用时产生的,用于用户程序申请访问硬件资源时,例如:
printf()打印函数,要将用户数据打印到显示器上,用户程序要想实现打印必须申请使用显示器,而用户程序又没有外设硬件的使用权,只能通过使用软件中断指令切换到内核态,通过操作系统内核代码来访问外设硬件,内核态是工作在特权模式下,操作系统在特权模式下完成将用户数据打印到显示器上。
这样做的目的无非是为了保护操作系统的安全和硬件资源的合理使用,该异常在管理模式下处理。
(6)数据中止访问异常
该异常发生在要访问数据地址不存在或者为非法地址时,该异常在中止异常模式下处理。
2.异常发生的硬件操作
在异常发生后,ARM内核会自动做以下工作:
(1)保存执行状态
当前程序的执行状态是保存在CPSR里面的,异常发生时,要保存当前的CPSR里的执行状态到异常模式里的SPSR里,将来异常返回时,恢复回CPSR,恢复执行状态。
(2)模式切换
硬件自动根据当前的异常类型,将异常码写入CPSR里的M[4:
0]模式位,这样CPU就进入了对应异常模式下。
不管是在ARM状态下还是在THUMB状态下发生异常,都会自动切换到ARM状态下进行异常的处理,这是由硬件自动完成的(当一个异常发生时,ARM处理器总是切换到ARM状态(即非Thumb状态)。
Thumb指令集没有包含进行异常处理时需要的一些指令,因此在异常中断时,还是要使用ARM指令。
),将CPSR[5]设置为0。
同时,CPU会关闭中断IRQ(设置CPSR寄存器I位),防止中断进入,如果当前是快速中断FIQ异常,关闭快速中断(设置CPSR寄存器F位)。
(3)保存返回地址
当前程序被异常打断,切换到异常处理程序里,异常处理完之后,返回当前被打断模式继续执行,因此必须要保存当前执行指令的下一条指令的地址到LR,由于异常模式不同以及ARM内核采用流水线技术,异常处理程序里要根据异常模式计算返回地址。
(4)跳入异常向量表
该操作是CPU硬件自动完成的,当异常发生时,CPU强制将PC的值修改为一个固定内存地址,这个固定地址叫做异常向量。
3.异常返回地址
一条指令的执行分为:
取指,译码,执行三个主要阶段,CPU由于使用流水线技术,造成当前执行指令的地址应该是PC–8(32位机一条指令四个字节),那么执行指令的下条指令应该是PC–4。
在异常发生时,CPU自动会将将PC–4的值保存到LR里,但是值是否正确还要看异常类型才能决定。
其中,各模式的返回地址说明如下:
(a)一般/快速中断请求:
快速中断请求和一般中断请求返回处理是一样的。
通常处理器执行完当前指令后,查询FIQ/IRQ中断引脚,并查看是否允许FIQ/IRQ中断,如果某个中断引脚有效,并且系统允许该中断产生,处理器将产生FIQ/IRQ异常中断,当FIQ/IRQ异常中断产生时,程序计数器PC的值已经更新,它指向当前指令后面第3条指令(对于ARM指令,它指向当前指令地址加12字节的位置;对于Thumb指令,它指向当前指令地址加6字节的位置),当FIQ/IRQ异常中断产生时,处理器将值(pc-4)保存到FIQ/IRQ异常模式下的寄存器LR中,它指向当前指令之后的第2条指令,因此正确返回地址可以通过下面指令算出:
SUBSPC,LR,#4;一般中断
SUBSPC,LR,#4;快速中断
(b)预取指中止异常:
在指令预取时,如果目标地址是非法的,该指令被标记成有问题的指令,这时,流水线上该指令之前的指令继续执行,当执行到该被标记成有问题的指令时,处理器产生指令预取中止异常中断。
发生指令预取异常中断时,程序要返回到该有问题的指令处,重新读取并执行该指令,因此指令预取中止异常中断应该返回到产生该指令预取中止异常中断的指令处,而不是当前指令的下一条指令。
指令预取中止异常中断由当前执行的指令在ALU里执行时产生,当指令预取中止异常中断发生时,程序计数器pc的值还未更新,它指向当前指令后面第2条指令(对于ARM指令,它指向当前指令地址加8字节的位置;对于Thumb指令,它指向当前指令地址加4字节的位置)。
此时处理器将值(pc-4)保存到lr中,它指向当前指令的下一条指令,所以返回操作可以通过下面指令实现:
SUBSPC,LR,#4
未定义指令异常中断由当前执行的指令在ALU里执行时产生,当未定义指令异常中断产生时,程序计数器pc的值还未更新,它指向当前指令后面第2条指令(对于ARM指令,它指向当前指令地址加8字节的位置;对于Thumb指令,它指向当前指令地址加4字节的位置),当未定义指令异常中断发生时,处理器将值(pc-4)保存到lr_und中,此时(pc-4)指向当前指令的下一条指令,所以从未定义指令异常中断返回可以通过如下指令来实现:
MOVPC,LR
(d)软中断指令(SWI)异常:
SWI异常中断和未定义异常中断指令一样,也是由当前执行的指令在ALU里执行时产生,当SWI指令执行时,pc的值还未更新,它指向当前指令后面第2条指令(对于ARM指令,它指向当前指令地址加8字节的位置;对于Thumb指令,它指向当前指令地址加4字节的位置),当未定义指令异常中断发生时,处理器将值(pc-4)保存到lr中,此时(pc-4)指向当前指令的下一条指令,所以从SWI异常中断处理返回的实现方法与从未定义指令异常中断处理返回一样:
MOVPC,LR
(e)数据中止异常:
发生数据访问异常中断时,程序要返回到该有问题的指令处,重新访问该数据,因此数据访问异常中断应该返回到产生该数据访问中止异常中断的指令处,而不是当前指令的下一
条指令。
数据访问异常中断由当前执行的指令在ALU里执行时产生,当数据访问异常中断发生时,程序计数器pc的值已经更新,它指向当前指令后面第3条指令(对于ARM指令,它指向当前指令地址加12字节的位置;对于Thumb指令,它指向当前指令地址加6字节的位置)。
此时处理器将值(pc-4)保存到lr中,它指向当前指令后面第2条指令,所以返回操作可以通过下面指令实现:
SUBSPC,LR,#8
上述每一种异常发生时,其返回地址都要根据具体异常类型进行重新修复返回地址,再次强调下,被打断程序的返回地址保存在对应异常模式下的LR里。
4.异常向量表
异常向量表是一段特定内存地址空间,每种ARM异常对应一个字长空间(4Bytes),正好是一条32位指令长度,当异常发生时,CPU强制将PC的值设置为当前异常对应的固定内存地址。
异常向量表的初始化
Trap_init()通过调用entry_amv.S中的(一一trap_init)函数段——由汇编语言编写的一段代码。
用于在系统的0x00地址处安装ARM的异常向量表,然后在0x200处建立各个异常(如irq,fiq,data,undefined等)的分类处理路线,以建立起完整的异常处理表。
中断发生时处理器的动作如下。
①拷贝CPSR到SPSR一;
②设置适当的CPSR位:
.改变处理器状态进入ARM状态
.改变处理器模式进入相应的异常模式
.设置中断禁止位禁止相应中断;
③更新LR一;
④设置PC到相应的异常向量。
具体代码实现如下:
无论在何种工作模式发生异常,系统都将切换到SVC模式下处理.主要的响应流程为:
保护现场,获得中断号(get_irqnr_and_base),强制切换到(SVC)模式,再执行相应的处理.获碍中断号的处理函数如下:
其中INTC~FNLSTS是GarfieldSEP3203的中断控制器中的最终状态寄存器,在linux-2.4.x\include\asm-armnommu\arch-gfd\hardware.h中定义。
获得中断控制器中的最终状态寄存器的值后,采用移位判断法来确定最终的中号。
在DO一IRQ中,根据中断号获得相应处理函数的入口指针地址,执行中断处理。
中断处理完成后,进行一次调度,如果没有其它进程需要执行,则系统返回中断前的用户现场。
(2)中断请求队列的初始化
start—kernel通过执行上面的两个函数来建立两级中断向量表.但第二级向量表是一堆空的数组结构,每个中断服务队列都是空的。
虽然从中断源的硬件以及中断控制器的角度来看,似乎已经得到服务了,但是从逻辑角度、功能角度来看,他并没有执行到具体的中断服务例程,没有得到具体的中断服务。
具体设备初始化时会将其中断处理程序通过request_irq()向系统”登记”,调用setup_arm_irq()挂入某个中断请求队列,参数irq是中断请求号,对应于中断控制器为每个中断源配置的中断号。
中断处理例程结束时通过free-irq来释放断。
(3)ARM的例外优先级从高到低依次为:
Reset→Dataabort→FIQ→IRQ→Prefetchabort→Undefinedinstruction/SWI
跳入异常向量表操作是异常发生时,硬件自动完成的,剩下的异常处理任务完全交给了程序员。
由上表可知,异常向量是一个固定的内存地址,我们可以通过向该地址处写一条跳转指令,让它跳向我们自己定义的异常处理程序的入口,就可以完成异常处理了。
正是由于异常向量表的存在,才让硬件异常处理和程序员自定义处理程序有机联系起来。
异常向量表里0x00000000地址处是reset复位异常,之所以它为0地址,是因为CPU在上电时自动从0地址处加载指令,由此可见将复位异常安装在此地址处也是前后接合起来设计的,其后面分别是其余7种异常向量,每种异常向量都占有四个字节,正好是一条指令的大小,最后一个异常是快速中断异常,将其安装在此也有它的意义,在0x0000001C地址处可以直接存放快速中断的处理程序,不用设置跳转指令,这样可以节省一个时钟周期,加快快速中断处理时间。
我们可以通过简单的使用下面的指令来安装异常向量表:
breset;跳入reset处理程序
bHandleUndef;跳入未定义处理程序
bHandSWI;跳入软中断处理程序
bHandPrefetchAbt;跳入预取指令处理程序
bHandDataAbt;跳入数据访问中止处理程序
bHandNoUsed;跳入未使用程序
bHandleIRQ;跳入中断处理程序
bHandleFIQ;跳入快速中断处理程序
通常安装完异常向量表,跳到我们自己定义的处理程序入口,这时我们还没有保存被打断程序的现场,因此在异常处理程序的入口里先要保存打断程序现场。
保存执行现场:
异常处理程序最开始,要保存被打断程序的执行现场,程序的执行现场无非就是保存当前操作寄存器里的数据,可以通过下面的栈操作指令实现保存现场:
STMFDSP,{R0–R12,LR}
需要注意的是,在跳转到异常处理程序入口时,已经切换到对应异常模式下了,因此这里的SP是异常模式下的SP了,所以被打断程序现场(寄存器数据)是保存在异常模式下的栈里,上述指令将R0~R12全部都保存到了异常模式栈,最后将修改完的被打断程序返回地址入栈保存,之所以保存该返回地址就是将来可以通过类似:
MOVPC,LR的指令,返回用户程序继续执行。
异常发生后,要针对异常类型进行处理,因此,每种异常都有自己的异常处理程序,异常处理过程通过下节的系统中断处理来进行分析。
5.异常处理的返回
异常处理完成之后,返回被打断程序继续执行,具体操作如下:
(1)恢复被打断程序运行时寄存器数据
(2)恢复程序运行时状态CPSR
(3)通过进入异常时保存的返回地址,返回到被打断程序继续执行
异常发生后,进入异常处理程序时,将用户程序寄存器R0~R12里的数据保存在了异常模式下栈里面,异常处理完返回时,要将栈里保存的的数据再恢复回原先R0~R12里,毫无疑问在异常处理过程中必须要保证异常处理入口和出口时栈指针SP要一样,否则恢复到R0~R12里的数据不正确,返回被打断程序时执行现场不一致,出现问题,虽然将执行现场恢复了,但是此时还是在异常模式下,CPSR里的状态是异常模式下状态,因此要恢复SPSR里的保存状态到CPSR里,SPSR是被打断程序执行时的状态,在恢复SPSR到CPSR的同时,CPU的模式和状态从异常模式切换回了被打断程序执行时的模式和状态。
此刻程序现场恢复了,状态也恢复了,但PC里的值仍然指向异常模式下的地址空间,我们要让CPU继续执行被打断程序,因此要再手动改变PC的值为进入异常时的返回地址,该地址在异常处理入口时已经计算好,直接将PC=LR即可。
上述操作可以一步一步实现,但是通常我们可以通过一条指令实现上述全部操作:
LDMFDSP,{r0-r12,pc}
以上操作可以用图2来描述:
图2异常处理的返回
参考文献:
[1]时龙兴.嵌入式系统-基于SEP3203微处理器的应用开发.电子工业出版社.
[2]邱铁.ARM嵌入式系统结构与编程[M].北京:
清华大学出版社.
[3]毛德操胡希明.嵌人式系统一采用公开源代码和strong一ARM/XScale处理器[M].浙江大学出版社.
[4]严菊明.基于ARM嵌入式系统的通用bootloader的设计与实现[D].2005.