07-中断

中断(Interrupts)

译文 · 基于 The Embedded Rust Book

中断

原文链接: https://doc.rust-lang.org/stable/embedded-book/start/interrupts.html

中断与异常在多个方面不同,但它们的操作与使用大体相似,并且也由同一中断控制器处理。异常由 Cortex-M 架构定义,而中断始终是厂商(往往甚至是芯片)特定的实现,无论是命名还是功能。

中断允许很大的灵活性,在尝试以高级方式使用它们时需要加以考虑。本书不会涵盖那些用法,但记住以下几点是个好主意:

  • 中断有可编程优先级,决定其处理函数的执行顺序
  • 中断可以嵌套与抢占,即一个中断处理函数的执行可能被另一个更高优先级的中断打断
  • 一般而言,需要清除导致中断触发的原因,以防止无限地反复进入中断处理函数

运行时的一般初始化步骤始终相同:

  • 设置外设,使其在期望的时机生成中断请求
  • 在中断控制器中设置中断处理函数的期望优先级
  • 在中断控制器中启用中断处理函数

与异常类似,cortex-m-rt crate 暴露 interrupt 属性用于声明中断处理函数。不过,该属性仅在启用 device 特性时可用。也就是说,该属性不打算直接使用——直接使用会导致编译错误。

相反,你应使用设备 crate(通常用 svd2rust 生成)重新导出的 interrupt 属性版本。这确保编译器能验证该中断确实存在于目标设备上。可用中断列表——以及它们在中断向量表中的位置——通常由 svd2rust 从 SVD 文件自动生成。

use lm3s6965::interrupt; // 设备 crate 重新导出的属性

// Timer2 中断的中断处理函数
#[interrupt]
fn TIMER2A() {
    // ..
    // 清除生成中断请求的原因
}

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

与异常处理函数类似,也可以在中断处理函数内部声明 static mut 变量,以安全地保持状态。

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

    // `COUNT` 的类型是 `&mut u32`,可以安全使用
    *COUNT += 1;
}

关于此处演示机制的更详细描述,请参阅异常一节。

最后修改 August 11, 2026: 更新 (70a5af133)