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