串口中断的相关概念和原理一、问题上一篇讲述了串口轮询方式的发送和接收流程和相关寄存器。
通过发送和接收函数的编程实践,我们发现轮询发送和接收时,应用程序需要不停息地轮询:轮询发送缓冲区是否为空可以发送新数据,或者接收缓冲区是否有新数据可接收。
一旦发送轮询中止,发送动作也无法开启;一旦接收轮询中止、或者接收被打断或不及时,新到的大量数据可能因接收缓冲区溢出而遭丢失。
故轮询访问方式只是一种试验性的粗糙访问方式,其适用场景很有限,且占用CPU和应用程序的大量时间、让设备忙得团团转。
要想从容不迫和得心应手地访问串口,还得采用中断方式。
中断机制的采用既是迫不得已的应用需要,也是CPU设计大师们为满足现实需求而积极主动创造发明的一个妙招。
对中断的深入理解直至完美掌控可以说是IT人员绝技中的必备一招,把它掌控好了,就一切如羽扇纶巾运筹于帷幄之中,就可以像浪尖上的弄潮儿一样风里来雨里去流连于浪花里之中蓝天白云之间如庄子一样逍遥;否则,就好比一个人只会紧抱着泳圈在岸边的浑水里趟着和摸着什么;而许多疑难杂症的出现大致都与中断的控制不善有着千丝万缕的干系。
这一篇就讲述串口中断的有关概念和基本原理,但不会涉及具体的操作(留待下一讲)。
这些概念和原理中,有的是串口模块特有的,有的是所有中断模块通用的。
对于我们测试人员来说,深入理解中断的技术细节、概念的来龙去脉、明白其中哪些地方容易出现设计错误,将有助于我们制定更完备的测试方案、牢牢地把控测试重点、恰当分配测试时间和精力、提高测试效率。
二、中断的类型以不同的角度或层次来划分,一个事物的分类就不一样,中断的分类也是如此。
不同体系的CPU技术手册中,对中断的分类均按照有利于自身、与自身的硬件结构相匹配的方式来进行。
这丰富了世界的多样性,却使得很多这个行当里初来乍到的人昏头转向、如理乱麻剪不断理还乱。
而有些行当里,有才能和雄心的管事者们就制定一个本行当的标准,以避免或结束混乱局面。
51系列(如A T89C51)的8位单片机中,只是简单地将中断分为片内中断和片外中断两种,片内中断又仅包括两路定时器中断和一路串口中断。
51系列单片机曾经如日中天、不可一世,却已是这一时代的遗老遗少,在此就一笔带过。
这里重点讲述S80CPU ZA9L0的中断分类。
ZA9L0使用的是ARM9处理器(由英国ARM公司提供),该处理器文档将我们通常所称的中断命名为exception(异常),而不是interrupt。
我们还是以常规的“中断”来称呼吧。
该处理器将中断划分成如下7类:1.复位硬件复位引起的中断,用于系统重启。
2.数据中止(Data Abort)非法访问不允许访问的地址或者非对齐的地址时,就产生该中断。
所谓不允许访问的地址,是指MMU配置表中未列出的供当前模式访问的地址区间。
非对齐的地址,是针对短整数和长整数而言的地址。
ARM规定,短整数(2字节)应从2的整数倍位置开始存取,长整数(4字节)应从4的整数倍位置开始存取。
3.快速中断请求(FIQ,Fast Interrupt Request)用于发起比IRQ能得到更快响应的中断请求。
ARM规定,系统中最多只为一个模块开这样的小灶。
FIQ由谁来触发呢?这是可以设定的,即可软件配置从32个触发通道中的某一个来触发,例如:定时器0通道。
4.中断请求(IRQ,Interrupt Request)用于发起常规的内部设备或外部设备的中断请求,它是我们最需要关注的一类中断。
由于总线宽度是32位,很自然地,最多可支持固定的32个通道的子中断请求。
请注意,这里说的是32个通道/channel。
由于单个GPIO中断通道(GPIO0A~GPIO2B)是很多口线合用的中断,即多个模块可合用一个GPIO中断通道,故实际的最大中断源模块个数大于32。
除IC卡以外的常见模块(如:串口、定时器、打印机、MODEM、以太网控制器)的中断都包含在这一中断类型中。
ZA9L0的32种IRQ中断列示如下:图1:ZA9L0的32种IRQ 中断在上面的表格中,能看到9个定时器中断(TM0~TM8)、三个串口中断(UART0~UART2),却没有看到打印机、MODEM 、以太网控制器等模块的中断。
这三个模块难道不需要中断吗?其实,这三个模块的中断主要是以GPIO (GPIO0A ~GPIO2B )的形式存在的,根据实际的硬件连接对应到相应的GPIO 端口上。
此外,这些模块还同时使用到了定时器中断,这也是ZA9L0大手笔地设计了9个定时器中断的原因。
由于GPIO 中断是很多口线合用的中断、不像各定时器中断均是独用的中断,串口中断还可进一步细分为发送中断、接收中断、状态中断等,其它子中断也可能有类似细分,故从IRQ 来看,ARM 的中断层次最多分为三层。
每一层均可再进行分类。
图2:IRQ 的三个中断层次示意图 复位 IRQ FIQ ...... TMR0 UART0GPIO1A GPIO1发送中断 ......接收中断状态变化中断5.预取指中止(Prefetch Abort)当程序带错误运行时,就可能因预取指地址非法而出现预取指中止的错误和中断。
因ARM取指是采用流水线的机制,所以取指都是比实际运行超前几条指令的预取指。
6.未定义指令当程序带错误运行或故意执行ARM未定义或不能处理的机器指令时,就可能或必定出现未定义指令的错误和中断。
7.软中断(SWI,Software Interrupt)软中断是非常实用和重要的一个中断。
软中断基本上被众多API函数用来进行安全、受限、可控的系统调用,从而间接地、有限度地访问CPU内核资源(如:各种模块的内部寄存器、核心内存)。
故,有些CPU直接将这种中断命名为SysCall,即系统调用。
发起软中断的各API函数,在发起该中断之前,需要在系统约定的内存区域填写上API编号以及对应入口参数;接着,就通过一条asm("SWI")的嵌入式汇编指令触发一次软中断;CPU硬件探测到软中断后,就调用软中断服务例程。
在软中断服务例程中,先到约定的内存区域读取请求相关信息:是哪个API请求、它的参数是哪些。
再携着这些参数调用相应模块的API服务函数。
最后,软中断执行完毕,程序返回到之前系统调用处的下句继续执行。
这7类中断的划分,是第一层次上的划分,不仅是逻辑概念上的划分,更是硬件结构上的划分;后面将要看到:ARM的硬件中断向量表中有7行,每行即对应各个中断的入口代码。
当出现数据中止、预取指、未定义指令等中断时,相应的中断服务程序可通过串口、屏幕等输出断点信息(如:断点地址、断点指令、断点工作模式、有关变量等),以便分析和追踪出错原因。
三、中断的并发、嵌套与优先级单个中断的响应过程有些中断是应用程序通过API有意发起的,如:软中断、串口的发送中断,发起后CPU 将跳转到相关中断服务程序中运行;更多的中断不是应用程序直接发起的,而是人机接口、某些模块或外部设备触发的。
中断触发后,CPU一旦执行完当前的机器指令,就开始从软硬件上响应该中断。
先是硬件上的响应(由ARM内核自动完成):1.保存断点地址到专用的断点寄存器中。
2.保存CPU的断点状态到专用的状态备份寄存器中。
3.切换到中断模式;对于IRQ、FIQ来说,还要关闭相应IRQ或FIQ总中断控制位(位于状态寄存器中)。
4.固定地跳转到相应的中断服务程序首句。
之前总结了第一层次上ARM共有7类中断,“固定地”意味着每类中断都规定着一个唯一的中断服务程序首句地址,不可由软件来重设置和更改,该地址上只能存放相应中断服务程序的首个语句,不能作其它任何用途。
这一点是ARM CPU的特有固定规则。
这个中断向量表的地址列示如下:图3:ARM中断向量表可见,中断向量表是从0地址开始顺序存放的,有7个可用的,另外1个保留未用的。
特别提请注意和区别,ARM的中断向量表中不像其他CPU那样是存放中断服务程序的入口地址,而是存放的语句;由于对每个中断均只有一个语句的空间,不可能把中断服务程序的整体放进来,故存放的语句只能是跳转语句。
例如,复位中断对应的汇编语句为:LDR PC, ResetHandler这句话等同于C语言中的:ResetHandler();其中,ResetHandler()是复位中断的服务函数名。
接着,软件上的响应即是中断服务程序的执行过程,一般有如下内容:1.对于IRQ来说,打开相应IRQ总中断控制位(位于状态寄存器中),便于更高子优先级的IRQ中断能被响应。
对于FIQ来说,在该服务期间相应FIQ总中断控制位一直处于关闭状态、不会打开。
2.执行数据的搬移,操作对象为:数据缓冲区、模块寄存器等。
3.对于IRQ和FIQ来说,响应和确认中断,以便从中断控制器中解除该中断的挂置(Pending)状态、确定本次中断服务结束。
4.从中断服务中跳回到断点。
对于FIQ来说,相应FIQ总中断控制位会同时被复原和打开。
●并发中断的响应对于任何CPU来说,可以执行的最小指令单位是一条机器指令,机器指令好比一个原子,不可再切分,即使中断也无法切分它。
这意味着,中断可以切割和打断一个进程的执行、一个函数的执行、一条高级语言语句的执行,但是,当一条机器码正在执行时,中断也只能眼睁睁地等着它执行完毕后才能被响应。
在CPU执行一条机器码的期间,也许有两个中断源先后(例如相差0.5个纳秒)触发了中断,我们认为这样的两个中断源相对于一个机器指令的整体来说是并发的。
ARM规定,对并发的中断先响应固定级别更高的中断。
以下是ARM规定的优先响应级别(从高到低排列):图4:ARM的固定中断优先级这里,7种中断只有6个优先级,是因为未定义中断和软中断是不会同时发生的中断。
●中断的抢占与嵌套当一个中断正在响应尚未结束时,另一个中断是否可被响应?注意,这里仅从第一层为着眼点来考虑。
有如下两种情况需要考虑:⏹不同中断源一个中断正响应时,另一不同的中断是否可被响应?按照上述图3所示的优先级,一个中断响应时,另一更高优先级的中断会被响应,而同等和更低优先级的中断不会被响应。
例如:IRQ(优先级4)中断期间,FIQ中断(优先级3)可被响应,而软中断(优先级6)却不会被响应。
这种更高优先级的不同中断打断更低优先级中断的执行,称为中断的抢占。
同一中断源一个中断正响应时,同一中断是否可再被响应?对于7种中断中除IRQ和FIQ之外的其它5种中断,正响应时,同一中断源不会再引起触发。
对于IRQ,由于它包含32个通道的子中断请求、且这些子中断也有优先级,故在相应IRQ总中断控制位被开启后,更高优先级的子中断会被响应、同等和更低的不会被响应。
对于FIQ,由于它只能包含1个通道的中断请求,故只有在该中断被响应和确认且FIQ 总中断控制位被开启后,同一FIQ中断才能再被响应。