中断
中断与异常在多种方式上有所不同,但它们的操作和使用在很大程度上是相似的,并且它们也由相同的中断控制器处理。异常是由 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;
}
有关此处演示的机制的更详细描述,请参阅 异常部分。