中断
虽然中断和异常在很多方面都不一样,但是它们的操作和使用几乎是一样的,且它们也能被同一个中断控制器处理。然而异常是由Cortex-M微架构定义的,中断在命名和功能上总是由特定厂商(经常甚至是芯片)实现的。
中断提供了更多的灵活性,当尝试用一种高级的方法使用它们时,我们需要对这种灵活性进行解释。但我们将不会在这本书里涵盖这些内容,最好把下面的东西记在心里:
- 中断有可以编程的优先级,其决定了它们的处理函数的执行顺序。
- 中断能嵌套且抢占,i.e. 一个中断处理函数的执行可以被其它更高优先级的中断打断。
- 通常需要清除掉导致中断被触发的原因,避免无限地再次进入中断处理函数。
运行时的初始化步骤总是相同的:
- 设置外设在想要的事件发生时产生中断请求
- 在中断控制器中设置需要的中断处理函数的优先级
- 在中断控制器中使能中断处理函数
与异常相似,cortex-m-rt
crate提供了一个interrupt
属性去声明中断处理函数。可用的中断(及它们在中断向量表中的位置)通常由svd2rust
从一个SVD描述文件自动地生成。
// Timer2中断的中断处理函数
#[interrupt]
fn TIM2() {
// ..
// 清除生成中断请求的原因
}
中断处理函数和异常处理函数一样看起来像是普通的函数(除了没有入参)。然而由于特殊的调用规定,它不能被固件的其它部分直接调用。然而,可以在软件中生成中断请求,转移到中断处理函数中。
与异常处理函数一样,也能在中断处理函数中声明static mut
变量且保持 safe 状态。
#[interrupt]
fn TIM2() {
static mut COUNT: u32 = 0;
// `COUNT` 的类型是 `&mut u32` 且它用起来安全
*COUNT += 1;
}
关于这里所说的机制的更多细节描述,请参考异常章节。