什么是中断?
中断是一个需要CPU立刻处理的内部/外部事件
——内部事件:定时器时间到
AD变换结束
……
——外部事件:按键动作
发生外部通信
……
- 内部/外部事件请求CPU处理
- CPU停止正常流程,执行中断服务程序ISR
- ISR结束后,CPU返回正常流程
中断 VS 轮询
中断
-
适用于处理对响应要求非常高的事件
-
适用于处理持续事件非常短的事件
-
适用于低功耗的应用
-
程序设计较复杂
轮询
- 适用于处理对事件响应要求低的场合
- 程序设计简单
中断的工作流程
- 内部/外部事件请求CPU处理
- CPU停止正常流程,执行中断服务程序ISR
- ISR结束后,CPU返回正常流程
中断服务子程ISR
中断服务子程ISR的共同特点:
- 是被CPU硬件自动调用的,而不是其他程序代码中调用;
- 在ISR执行前、后,CPU自动进行了堆栈出入等操作;
- 写成C函数的参数和返回值都应为void;
中断向量表
- 中断向量表是一段连续的存储空间在复位后有默认的起始位置
- 每个中断在向量表中都有相应的表项,该表项的值为该中断对应的服务程序的地址(地址指针)
- 由程序代码确定中断向量表的每个表项
- 中断向量表的位置是可以通过改写中断向量基址寄存器重新定位的
中断优先级
-
多个中断同时出现时,高优先级中断先得到响应
-
中断优先级可以是固定的或编程指定的
-
固定优先级:根据中断向量表顺序
-
设定优先级:每个中断都有优先级设置位
-
相同优先级的中断,按先后顺序处理
中断嵌套规则
-
具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。
-
当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。
-
如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们抢占式优先级和响应优先级都相等,则根据他们在中断表排位顺序决定先处理哪一个。
-
响应优先级不可以中断嵌套。注意,中断优先级的概念针对“中断通道”,当中断通道的优先级确定后,该中断通道对应所有中断源都享有相同的中断优先级,至于该中断通道中对应多个中断源执行顺序,取决于用户的中断服务程序。
中断优先级分组
中断优先级分组是为了给抢占式优先级和响应优先级在中断优先级寄存器的高四位,分配各个优先级数字所占的位数,在一个程序中只能设定一次。
中断的具体行为
当CM3开始响应一个中断时,会做如下动作:
- 入栈:把8个寄存器的值压入栈
- 取向量:从向量表中找出对应的服务程序入口地址
- 选择堆栈指针MSP(主堆栈)/PSP(进程堆栈),更新堆栈指针SP,更新链接寄存器LR,更新程序计数器PC
入栈
响应异常的第一个动作,就是自动保存现场,依次把xPSR、PC,LR,R12以及R3-R0由硬件寄存器自动压入适当的堆栈中。
取向量
数据总线(系统总线)在执行入栈的时候,指令总线从向量表中找出正确的异常向量,然后在服务程序的入口处预取指。
更新寄存器
在入栈和取向量操作完成之后,执行服务例程之前,还要更新一系列的寄存器.
- SP:在入栈后会把堆栈指针更新到新的位置。在执行服务例程时,将由MSP负责对堆栈的访问。
- PSR:更新IPSR位段的值为新响应的异常编号。
- PC:在取向量完成后,PC将指向服务例程的入口地址,
- LR:在出入ISR ( Interrupt Service Routines)中断服务程序的时候,LR的值将得到更新
(在异常进入时由系统计算并赋给LR,并在异常返回时使用它)
导常/中断返回
当异常服务例程执行完毕后,需要恢复先前的系统状态,才能使被中断的程序得以继续执行。异常/中断处理完成后,执行如下处理:
出栈:恢复先前压入栈中的寄存器,堆栈指针的值也改回先前的值
更新NVIC寄存器:伴随着异常的返回,它的活动位也被硬件清除