04-Intertupt
Exceptions and Interrupts
Interrupt or Exception Processing Sequence
• Other code (background) is running.
• Interrupt trigger occurs.
• Processor does some hard-wired processing
• Processor executes the ISR (foreground), including the
return-from-interrupt instruction at the end.
• Processor resumes other code.
中断服务程序(Interrupt Service Routine)
• Hardware-triggered(硬件触发) asynchronous software routine
• Triggered by hardware signal from peripheral or external device
• Asynchronous - can happen anywhere in the program (unless interrupt is disabled)
• Interrupt service routine runs in response to the interrupt
微控制器的基本原理
•提供高效的基于事件的处理,而不是轮询
•提供对事件的快速响应,无论程序状态,复杂性,位置
•允许许多多线程嵌入式系统在没有操作系统的情况下进行响应
Entering Exception Handler
进入异常处理
在异常处理开始前,MSP或PSP的数值会相应地被自动调整。PC也会被更新为异常处理的起始地址,而链接寄存器(LR)则会被更新为名为EXCRETURN的特殊值。该数值为32位,且高27位为1。低5位中有些部分用于保存异常流程的状态信息(如压栈时使用的哪个栈)。该数值用于异常返回。
一旦产生异常,微处理器
– 首先现场保护
• 将当前R0‐R3、R12、LR、PC、xPSR压入当前栈中
– 接着读取异常向量
• 根据异常的类型号n,计算出异常处理程序的入口地址(也称为异常向量)的存放偏移地址n*4,将该地址处的一个字读出。
– 将LR置为EXC_RETURN,将读取的异常向量值加载至PC。
1. Finish Current Instruction
Most instructions are short and finish quickly
Some instructions may take many cycles to execute
Load Multiple (LDM), Store Multiple (STM), Push, Pop, MULS (32 cycles for some CPU core implementations) 延迟中断响应
If one of these is executing when the interrupt is requested, the processor:
• abandons the instruction
• responds to the interrupt
• executes the ISR
• returns from interrupt
• restarts the abandoned instruction
2. Push Context onto Current Stack
使用
sp - #offset
的模式来执行,推入8个Regs
可能使用两种SPs,Main (MSP), process (PSP)
- 具体用那种看
CONTROL
register的bit 1
而定 - Which is active depends on operating mode, CONTROL register bit 1(由CONTROL寄存器控制是MSP(0)还是PSP(1))
大R先存大地址
进入ISR时SP指向R0
3. Switch to Handler/Privileged Mode
Handler mode always uses MSP
Thread 模式主要适用于用户的程序代码,Handler 模式主要适用于异常处理代码以及内核代码。可以通过 IPSR 寄存器查看处理器所处的状态。
Cortex-M 系列处理器有两种模式
- Thread Mode
- Handler Mode
Cortex 系列处理器有两种访问级别
Privileged
Unprivileged
CONTROL
register是特殊寄存器
其中第0位定义线程的特权等级: 0-Privileged Mode,1-非特权
第1位定义指针选择:0-主栈指针,1-进程指针:在处理模式时,该位始终为0
在系统 Reset之后,处理器默认是 Privileged 级别。访问级别由寄存器 control[0] 控制,当且仅当处理器运行在 Thread 模式下,该位才有效。Handler 模式只能运行在 Privileged 模式。
4. Load PC With Addr of Exception Handler
是根据出现的 Exception 来选特定的 Memory Address 来存入 ==PC== 中的
- 这些Memory Addr分别对应着不同的处理方式,也就是不同的 Value。
- 这个对应表存在 Vector table 中
向量地址的LSB设置为“1”表示该处理程序使用Thumb代码
IRQ中断编号,每个异常地址为四个字节,记录异常处理程序在内存中的位置
Exception num =IRQ+16
5. Load LR With EXC_RETURN Code
EXC_RETURN
码决定了要使用那种模式以及那种栈指针
restoreSP: MSP (0) or PSP (1) / return到哪个模式:Handler (0) or Thread (1)
- Handler模式还是Thread模式(Handler模式时候一定是MSP,所以三种状态)
- MSP还是PSP
EXC_RETURN value generated by CPU to provide information on how to return
6. Start Executing Exception Handler
Exception handler starts running, unless preempted(抢占) by a higher-priority exception
异常处理程序可能会在堆栈上保存额外的寄存器,例如,如果处理程序可能会调用subroutine,LR和R4必须保存
Exiting an Exception Handler
Execute instruction triggering exception return processing 执行指令触发异常返回处理
Select return stack, restore context from that stack 选择返回堆栈,从堆栈中恢复上下文
Resume execution of code at restored address 在恢复的地址恢复代码的执行
1. Return from Exception
没有“从中断返回”指令
• BX LR - Branch to address in LR by loading PC with LR contents
• POP {…, PC} - Pop address from stack into PC
使用特殊值EXC_RETURN加载到PC中以触发异常处理处理
•如果EXC_RETURN仍然在LR中,则使用BX LR
•如果EXC_RETURN已保存在堆栈中,则使用POP
2. Select Stack, Restore Context
Check EXC_RETURN (bit 2) to determine from which SP to pop the context
从堆栈中取出寄存器
Resume Executing Previous Main Thread Code
Exception handling registers have been restored: R0, R1, R2, R3, R12, LR, PC, xPSR
SP is back to its previous value.
Back in thread mode
Timing Analysis
Interrupt Response Latency 异常响应延时
Latency = time delay
切换到中断处理程序有开销,而且浪费时间。这随着中断率的上升而增加。这会延迟我们对外部事件的响应,这对于应用程序来说可能是可接受的,也可能是不可接受的,例如对模拟波形进行采样
需要多长时间?
完成当前指令的执行或放弃该指令,将各种寄存器推到堆栈上,获取向量
Maximum Interrupt Rate
我们每秒只能处理有限数量的中断
We can only handle so many interrupts per second
- $F_{Max_Int}$ : maximum interrupt frequency
- $F_{CPU}$ : CPU clock frequency
- $C_{ISR}$ : Number of cycles ISR takes to execute
- $C_{Overhead}$: Number of cycles of overhead for saving state, vectoring, restoring state, etc.
$$
F_{Max_Int} = \frac{F_{CPU}}{C_{ISR}+C_{Overhead}}
$$
Note that model applies only when there is one interrupt in the system
==Utilization==
当处理器响应中断时,它不执行任何其他代码
- $U_{Int}$ : Utilization (fraction of processor time) consumed by interrupt processing
$$
U_{Int} = F_{Int} * \frac{C_{ISR}+C_{Overhead}}{F_{CPU}} * 100%
$$
Fint/MAX Fint
CPU looks like it’s running the other code with CPU clock speed of
$$
(1-U_{Int})*F_{CPU}
$$
以这么多的时钟频率运行其他代码
Program Design with Interrupts
如何在ISR和其他线程之间通信?
•数据缓冲
•数据完整性和竞态条件
权衡(Trade-off):ISR代码更快的响应将延迟其他代码的完成
在有多个短期限ISR的系统中,在ISR中执行关键工作,并缓冲部分结果以供后续处理
The Volatile Directive
Need to tell compiler which variables may change outside of its control
使用volatile关键字强制编译器每次使用时从内存中重新加载这些变量
volatile unsigned int num_ints;
volatile int * var; // or
int volatile * var;
对变量(例如状态寄存器)的每一次C源读取都将导致一条汇编语言LDR指令