中断

中断与异常在多种方式上有所不同,但它们的操作和使用在很大程度上是相似的,并且它们也由相同的中断控制器处理。异常是由 Cortex-M 架构定义的,而中断始终是供应商(通常甚至芯片)特定的实现,包括命名和功能。

中断确实允许很大的灵活性,在尝试以高级方式使用它们时需要考虑这一点。本书不会涵盖这些用法,但请记住以下几点:

  • 中断具有可编程的优先级,这决定了其处理程序的执行顺序。
  • 中断可以嵌套和抢占,即中断处理程序的执行可能会被另一个更高优先级的中断打断。
  • 通常,导致中断触发的根本原因需要被清除,以防止无限次地重新进入中断处理程序。

运行时的通用初始化步骤始终相同。

  • 设置外设以在所需情况下生成中断请求。
  • 在中断控制器中设置中断处理程序的所需优先级。
  • 在中断控制器中启用中断处理程序。

与异常类似,cortex-m-rt crate 提供了一个 interrupt 属性来声明中断处理程序。可用的中断(及其在中断处理程序表中的位置)通常通过 svd2rust 从 SVD 描述中自动生成。

// Interrupt handler for the Timer2 interrupt
#[interrupt]
fn TIM2() {
    // ..
    // Clear reason for the generated interrupt request
}

中断处理程序看起来像普通的函数(除了没有参数),类似于异常处理程序。但是,由于特殊的调用约定,它们不能被固件的其他部分直接调用。但是,可以在软件中生成中断请求,以触发对中断处理程序的转移。

与异常处理程序类似,也可以在中断处理程序中声明 static mut 变量,以进行安全状态保存。

#[interrupt]
fn TIM2() {
    static mut COUNT: u32 = 0;

    // `COUNT` has type `&mut u32` and it's safe to use
    *COUNT += 1;
}

有关此处演示的机制的更详细描述,请参阅 异常部分