Cortex M3异常
Cortex M3异常
定义与类型
所有能够打断正常执行的事件都称为异常
异常是编号为1到15的系统异常,而余下的240个是外部中断输入。外加在0位置的栈顶指针,总共构成中断向量表中的256条。
当前运行的异常编号,是由特殊寄存器IPSR或者NVIC的中断控制状态寄存器。
异常是另一种形式的中断,他是由内部Fault引起的或者内核的SysTick、SVCall等,而中断是有随机的外部事件引发的。(因此异常可以理解为系统级的中断)
下面是TM4C129的中断向量表中异常
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
中文列表
异常号 | 异常类型 | 优先级 | 描述 |
---|---|---|---|
0 | N/A | N/A | 没有异常在运行 |
1 | 复位 | -3(最高) | 复位 |
2 | NMI | -2 | 不可屏蔽中断(外部NMI输入) |
3 | 硬件fault | -1 | 各种fault情况 |
4 | 内存管理fault | 可编程 | 内存管理fault,MPU访问非法地址 |
5 | 总线fault | 可编程 | 总线fault,比如预取中止 |
6 | 使用fault | 可编程 | 由于程序fault或尝试方位协处理器导致的异常 |
7-10 | 保留 | N/A | – |
11 | SXCall | 可编程 | 系统服务调用 |
12 | 调试监视器 | 可编程 | 调试监视器 |
13 | 保留 | N/A | – |
14 | PendSV | 可编程 | 可挂起系统设备申请 |
15 | SYSTICK | 可编程 | 系统时钟定时器 |
优先级
优先级数值越小,则优先级越高。CM3支持中断嵌套,使得高优先级异常会抢占(preempt)低优先级异常。
复位,NMI,和硬件fault特定的优先级,其他均可编程。CM3支持256级可编程异常。
软件优先级与硬件优先级
所有的异常均自带硬件优先级,通过软件设置的优先级成为软件优先级,异常一旦指定了软件优先级,则硬件优先级无效。
若两个异常的有相同的软件优先级,则根据硬件优先级来决定处理器**中断的顺序。
优先级的配置
减少优先级数可以通过减少优先级配置寄存器的一些低位来实现。
使用3位的优先级,则优先级为0x00 0x20 0x40 0x60 … 0xE0
使用4位的优先级,则优先级为0x00 0x10 0x20 0x30 … 0xF0
使用8为的优先级,则优先级为0x00 0x01 0x02 … 0xFF
抢占优先与次优先
这8位寄存器又可以分为2部分:抢占优先和次优先*
定义优先组,值x取0-7,代表寄存器的低x+1位 为次优先级字段,剩下的高7-x位 为抢占优先
1. 高抢占式优先级的中断事件可以打断当前的主程序/中断程序的运行——抢断式优先响应,俗称中断嵌套。
2. 在抢占式优先级相同的情况下,高子优先级的中断优先被响应;
3. 在抢占式优先级相同的情况下,如果有低子优先级中断正在执行,高子优先级的中断要等待已被响应的低子优先级中断执行结束后才能得到响应——非抢断式响应(不能嵌套)。
中断是否响应
- 规则一:
多个中断源在它们的抢占式优先级相同的情况下,子优先级不论是否相同,如果某个中断已经在服务当中,则其它中断源都不能打断它(可以末尾连锁);只有抢占式优先级高的中断才可以打断其它抢占式优先级低的中断。 - 规则二:
多个中断源在它们的抢占式优先级相同的情况下,同时产生中断,则子优先级高的中断被响应。 - 规则三:
多个中断源在抢占式优先级与子优先级均相同的情况下,按中断矢量号的大小为优先级,即中断矢量号小的中断优先被响应,即SYSTICK优先于UART0中断。
例
有两个中断源,A中断的中断优先级级置成INTA = b011,即0x60, B中断的中断优先级设置成INTB = b001,即0x20。单单依靠这两个设置我们是无法判断A,B是如何进行中断调度的,我们首先要看中断的组别管理设置。这里我们假设两种不同的组别管理方法,来说明如何分析中断的优先级管理
1) 假设我们设置PRIGROUP = 0x02, 我们按下面来分析中断是如何调度的:
通过查上面的表我们可以看出,INTn的优先级按照bxx.y来划分
a. INTA的中断优先级就被划分为 INTA = b01.1
组优先级 = 01;子优先级 = 1
b. INTB的中断优先级也被分为 INTB = b00.1
组优先级 = 00;子优先级 = 1
由此可见,B的组优先级比A的优先级要高(注意,数字越小,级别越高),B的中断可以打断A的中断处理。
2) 假设我们设置PRIGROUP = 0x01, 我们按下面来分析中断是如何调度的:
通过查上面的表我们可以看出,INTn的优先级按照bx.yy来划分
a. INTA的中断优先级被划分成INTA = b0.11.
组优先级 = 0; 子优先级 = 11
b. INTB的优先级被划分为INTB = b0. 01
组优先级 = 0; 子优先级 = 01
由此可见,A和B处于同一个组优先级,他们两个互相不能打断对方的中断处理。B中断的子优先级高,当两个中断同时发生时,会先进B中断处理,但如果A先发生,在未处理结束前,B是不能打算A进行处理的。