学习笔记(五)——中断和异常

    cm3在内核水平上支持256个系统异常和外部中断,由内嵌向量中断控制器(NVIC)控制标号1-15位异常,16-255则为外部中断,由于性质类似,都是“中断”主程序,因此后续将使用中断来代表系统异常和外部中断。如果一个中断因为系统在执行 更高优先级中断服务历程或者被屏蔽导致除能,不能被立即响应,则称它被“悬起(pending)”,此时会有一个悬起状态寄存器保存其中断请求,直到中断能够被响应。

  256个中断类型如下图所示。

一、中断优先级

  中断优先级决定了中断否被立即执行,CM3中支持嵌套中断,更高级别中断可以抢占低优先级中断。优先级号越小则优先级越高,复位,NMI,硬fault的优先级为负数,因而是最高优先级的中断。虽然CM3支持8位可编程优先级,但是一般来说在设计时回裁掉几位低端有效位,减少级数,因为级数越多会带来额外的成本和能耗。

抢占优先级和子优先级(响应优先级,亚优先级):

  CM3中最多支持128位优先级,因为8位中至少1位需要分配给子优先级。抢占优先级是指新产生的中断优先级大于当前运行的中断优先级,则优先级高的将会进行抢占。抢占优先级相同的两个中断,若同时发生或者悬起,则子优先级高的先运行,若一个已经在运行,无论子优先级是否更高,都不会进行抢占。

  如下图所示,设置为有4个抢占优先级和2个子优先级。

  

  优先级由写入应用程序中断及复位控制寄存器(AIRCR)决定。例:0x05FA0500,则[7:6]两位为抢占优先级。

二、向量表

  向量表用于存储中断服务例程的入口地址,默认的向量表位于0地址处,各个向量占用3字节,其结构如下图:

  如图所示,对于MSP的初始值、复位向量、NMI服务历程入口地址、硬fault服务例程的入口地址是必须包含在向量表中的。为了灵活性,向量表支持重定位(一般重定位到SRAM的一块区域),修改NVIC中的向量表偏移量寄存器的值就能够重新定位向量表。但要注意的是向量表的起始地址是有要求的,需要求出向量总数并向上取整到最小的2的整数次幂。

三、中断输入和悬起

  中断输入脚被置为有效后,该中断就被悬起,即使撤销了中断请求,也会被记录下来,当优先级最高的时候得到响应,只有悬起状态清除了才会取消中断。悬起状态有两种清除方法,一种是硬件清除,即当IRQ完成后,硬件自动清除悬起状态并返回主程序,另一种是使用软件清除中断悬起状态。

四、fault类异常

  fault包括总线fault、存储器管理fault、用法fault、硬fault这几类。

4.1 总线fault

  AHB(高性能总线)传送数据时回复了一个错误信号,则会产生总线fault,一般是取指和数据读写时发生错误导致的,包括访问地址没有相应寄存器,SDRAM还未初始化就访问,数据类型不匹配,设备不能被传送数据(如用户级下试图访问特权级下才能访问的设备)。总线fault产生后,若优先级更高,则立即执行,否则被悬起。如果总线fault被除能,或者总线fault是由同优先级或者更高优先级中断所引发的,那么总线fault会上访称硬fault。通过NVIC提供的“总线fault寄存器(BFSR)”,可以判断fault出入栈,数据访问还是取指。

4.2 存储器管理fault

  存储器管理fault往往是因为触发了MPU的保护设置的保护规范引发的,访问空地址,往只读region写数据,用户级下访问只有特权级下才能访问的地址也可能触发存储器管理fault。其处理方法和总线fault类似,若硬fault和NMI的执行也导致了MemManage fault,那内核将被锁定。同样的,NVIC有一个“存储器管理fault状态寄存器(MFSR)”,通过MFSR可以知道导致fault 的原因。

4.3 用法fault

  产生的原因可能是:执行了协处理器指令,执行了未定义的指令,无效的中断返回,使用多重加载/存储指令时,地址没有对齐。其他的与存储器管理fault类似,有一个“用法fault状态寄存器(UFSR)”。

4.4 硬fault

  硬fault是以上三个处理器“上访”的结果,另外,取向量产生的总线fault也按硬fault处理,NVIC也有一个?硬fault状态寄存器(HFSR)来指明产生硬fault 的原因。

五、SVC和PendSV

  SVC(系统调用)和PendSV(可悬起系统调用)用于软件开发中,OS一般不会让用户程序直接访问硬件,而是提供SVC(类似于API),用户需要控制特定硬件时,通过产生一个SVC异常,执行SVC服务例程来间接访问硬件。这种方式使得用户无需复杂控制硬件程序,使系统更加健壮,见小了开发难度。SVC不能嵌套使用SVC,同优先级无法抢占自身,这样会产生一个用法fault,在NMI中也不能使用SVC,否则会触发硬fault。SVC异常必须在执行SVC指令后立即响应,即不可被悬起,否则也将上访称硬fault。

  PendSV则是可以被悬起的异常,在PendSV悬起寄存器中写入1,若优先级不够高,则将缓期执行。典型的使用场合是在上下文切换中。如图所示,即使SysTick抢占了ISR,PendSV会在ISR执行完毕后再进行上下文切换。

 

 六、NVIC中断控制

  每个中断都使用了NVIC中的以下几个寄存器:使能与除能寄存器、悬起和解悬寄存器、优先级寄存器、活动状态寄存器。还有一些特殊功能寄存器对中断可能有影响:异常掩蔽寄存器(PRIMASK,FAULTMASK,BASEPRI)、向量表偏移量寄存器、软件触发中断寄存器、优先级分组位段。

6.1中断配置

(1)中断使能和除能分别使用各自的寄存器来控制,若要使能和除能,只需要在写1到相应的SETENA和CLRENA中,写0没有任何影响。写0无效的的好处是每个中断只需要去简单设置就可以了,不必担心破坏其他中断的中断设置。共240对使能位/除能位,分布在8对32位寄存器中。可以按字/半字/字节访问。

(2)中断的悬起状态可以通过“中断设置悬起寄存器(SETPEND)”和“中断悬起清除寄存器(CLRPEND)”来读取。悬起和解悬寄存器可以有8对,用法和使能除能寄存器差不多。

(3)优先级前面讲过了。

(4)活动状态由活动状态寄存器(ACTIVE)来决定,执行ISR第一条指令后,活动位就被置1,直到ISR返回时才硬件清0。中断被更高优先级抢断时,该中断活跃状态仍然为1。该寄存器用法和使能除能寄存器差不多,只是不是成对的。

(5)特殊功能寄存器PRIMASK和FAULTMASK用于除能异常,PRIMASK将当前优先级设为0(可编程优先级的最高优先级),从而除能所有NMI和硬fault之外的异常。FAULTMASK则改为-1,将硬fault也除能。它们通过MRS和MSR或者CPS来访问。

(6)BASEPRI也用于掩蔽异常,用于设定一个值,优先级低于这个值的都被屏蔽。

6.2 中断设置示例

6.3软件中断和SysTick定时器

  软件中断最简单的方法是使用相应的SETPEND寄存器,更好的方法即使使用软件触发中断寄存器(STIR),将相应的位写入1,则该编号的外部中断被悬起。

  NVIC中还有一个SysTick定时器,产生SysTick异常,该定时器用于产生“滴答”中断的时基,也是整个系统的时基。定时器将时间片分配给各个任务,实现任务的切换。有四个寄存器控制SysTick定时器,SysTick控制及状态寄存器,SysTick重载数值寄存器,SysTick当前数值寄存器,SysTick校准数值寄存器。

七、中断具体行为

7.1 中断产生

  中断产生后,将会发生以下三个操作:

(1)入栈。为了保存现场,按顺序把xPSR,PC,LR,R12,R3-R0由硬件自动压入堆栈中,若在使用PSP,则压入PSP,使用进程堆栈,否则压入MSP,使用主堆栈。进入ISR后,将一直使用主堆栈。堆栈顺序和空间顺序并不是对应的:

(2)取向量。CM3采用哈佛结构,即取指和数据操作使用不同的总线,因此在入栈的同时,I-Code总线正在从向量表中找出正确的向量,然后在入口地址处取指。

(3)更新寄存器。SP:把堆栈指针(PSP或MSP)更新到新位置。PSR:更新IPSR位段(PSR的最低部分)的值为新响应的异常编号。PC:取向量后,PC将指向ISR的入口地址。LR:出入ISR过程中,LR代表的是“EXC_RETURN”,异常进入时由系统计算赋值给LR,方便异常返回时使用LR。

7.2 异常返回

  在执行完ISR后,需要进行异常返回,以便回到被中断的程序。异常返回的方式有三种:

 

  异常返回后,CM3将执行以下操作使被中断的程序再次被执行:

(1)出栈:和前面入栈相对应,将保存的值恢复到寄存器。

(2)更新NVIC寄存器:将活动位清除。

7.3嵌套中断,咬尾中断,晚到中断

  前面讲到,CM3支持嵌套中断,嵌套中断发生时,被中断的ISR的8个(或以上)寄存器值需要被保存到MSP,因此若嵌套过多,可能会导致栈溢出,因此计算MSP容量的最小安全值是很重要的。另外,相同的异常不允许重入(我觉得重入应该是指同一个ISR未完成又再次被调用,使得同一个ISR占用两个内存空间),只能等一个ISR执行完成后,方可响应新的IRQ。

  咬尾中断是为了缩短中断延迟而设置的,咬尾中断就是指若CM3执行完一个中断,接着发生另一个中断时,不再进行异常返回中的出栈和中断发生时的入栈操作,因为被中断的程序再次被中断,得不到执行,也就没有必要把恢复出来又保存进去。

  晚到中断是指若在中断产生的入栈阶段,ISR尚未执行,又来了更高优先级的中断,那么入栈后,将执行高优先级的中断。

 7.4 异常返回值

  前面讲到,中断发生的第三步中LR将更新为“EXC_RETURN”,高28全为1,低四位有意义:

  可以看出,EXC_RETURN有以下三个合法值:

 

7.5 中断响应延迟

  中断延迟是指收到中断请求,到执行ISR第一条指令时需要的时间。一般来说是12个周期,进行了上述的一系列操作,咬尾中断则只需要6个周期。但是有些进行中的指令需要较多周期,包括除法指令、双字传送指令LDRD/STRD以及多重数据传送指令LDM/STM。对于前两者,CM3为了保证中断的响应直接取消操作,这样会丧失部分性能(因为中断返回后需要从头运行这个指令)。对于后者,CM3支持LDM/STM的中止和继续,单这样需要在xPSR中开出若干个ICI位,带ISR返回后,CM3可以从中获取LDM/STM执行的进度。

  另外,中断响应期间可能产生多个种类的fault,这里不再赘述。

 

 

  

 

转载于:https://www.cnblogs.com/catinblack/p/8550357.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值