跳到主要内容

RT-Thread中断管理

中断是什么

中断是指外部事件或CPU在执行过程中,需要CPU暂停当前执行,转而执行其他任务的机制。

打个比方,你正在工位上办公,你领导突然要你去办个很紧急的活儿,于是你放下手边的工作,处理完了领导的事情再着手做原来的事情。

这是一个很简单的异步思想机制,中断实际上属于一种异常,因为它是允许CPU脱离正常工作去处理紧急事务的机制。

信息

在这个过程中,申请CPU中断的请求源称为中断源,实现中断的系统称为中断系统。

但是我们在实际开发中,不仅要考虑中断的优先级,还要考虑中断的上下文,处理时间,会不会死锁等等,就像你要考虑领导给你的这个新活儿合不合适做,合不合适你现在做,多久能做完。

RT-Thread提供了一套中断管理系统,比较好用。在介绍中断管理之前,我们先来复习一下CPU架构。

Cortex-M CPU 架构基础

常见的移植对象有Cortex-M系列的CPU,比如STM32F407等。

Cortex-M 系列 CPU 的寄存器组里有 R0~R15 共 16 个通用寄存器组和若干特殊功能寄存器。

通用寄存器中,比较重要的寄存器有R13,它是作为堆栈指针寄存器(SP, Stack Pointer),用于指向当前堆栈的顶部。R14作为连接寄存器(LR, Link Register), 用于存储当前正在执行的指令的地址。R15作为程序计数寄存器(PC, Program Counter),用于存储下一条要执行的指令的内存地址。

其中为堆栈指针寄存器可以是主堆栈指针(MSP),也可以是进程堆栈指针(PSP)。

特殊功能寄存器中,包括程序状态字寄存器组(PSRs)、中断屏蔽寄存器组(PRIMASK, FAULTMASK, BASEPRI)、控制寄存器(CONTROL),可以通过 MSR/MRS 指令来访问特殊功能寄存器。

MRS R0, CONTROL ; 读取 CONTROL 到 R0 中
MSR CONTROL, R0 ; 写入 R0 到 CONTROL 寄存器中

操作模式和特权级别

何谓操作模式?Cortex-M 的操作模式是处理器内部的一种执行状态或权限级别,用于区分当前正在运行的是普通应用程序(线程模式)还是中断/异常处理程序(处理模式)。

Cortex-M有两个操作模式,如果进入异常或中断处理则进入处理模式,其他情况则为线程模式

它本质上是一个硬件层面的运行环境。

Cortex-M 有两个运行级别,分别为特权级和用户级,线程模式可以工作在特权级或者用户级,而处理模式总工作在特权级,可通过 CONTROL 特殊寄存器控制。

说回堆栈寄存器SP,对应两个物理寄存器MSP和PSP。

MSP 为主堆栈,PSP 为进程堆栈,处理模式总是使用 MSP 作为堆栈,线程模式可以选择使用 MSP 或 PSP 作为堆栈,同样通过 CONTROL 特殊寄存器控制。复位后,Cortex-M 默认进入线程模式、特权级、使用 MSP 堆栈。

嵌套向量中断控制器(NVIC)

在STM32栏目的外部中断中有讲到NVIC,这里不重复部分内容,仅作补充。

当一个中断触发并且系统进行响应时,处理器硬件会将当前运行位置的上下文寄存器自动压入中断栈中,涉及的是 PSR、PC、LR、R12、R3-R0 寄存器。

提示

但就算一个中断正在服务,这个时候有优先级更高的中断触发,那么处理器同样会打断当前运行的中断服务程序,然后把这个中断服务程序上下文的 PSR、PC、LR、R12、R3-R0 寄存器自动保存到中断栈中。

PendSV 系统调用

PendSV也称为可悬起的系统调用,顾名思义可以被挂起,而且是一种异常。

PendSV专门用来辅助操作系统进行上下文切换。但PendSV异常初始化后优先级最低。PendSV异常的处理程序必须在特权级下运行。

每次需要进行上下文切换的时候,会手动触发 PendSV 异常,PendSV 提供异常处理函数,在这个函数中进行上下文切换。

RT-Thread 中断工作机制

中断向量表

其实在Bootloader有提到过中断向量表,这里不重复部分内容,仅作补充。

有了这个中断向量表可以干嘛呢?处理器才能知道当发生某个异常或中断时,该跳转到哪里去执行对应的处理程序。简单说,它是中断与处理函数之间的“地图”。

有了它,就可以定位到中断源是谁。

中断处理过程

中断前导程序

用户中断服务程序

中断后续程序

中断嵌套

中断栈

中断的底半处理

RT-Thread 中断管理接口

中断服务程序挂接