中断

虽然中断和异常在很多方面都不一样,但是它们的操作和使用几乎是一样的,且它们也能被同一个中断控制器处理。然而异常是由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;
}

关于这里所说的机制的更多细节描述,请参考异常章节