中断

虽然中断和异常在很多方面都不一样,但是它们的操作和使用几乎一样,且它们也能被同一个中断控制器处理。然而异常是由Cortex-M微架构定义的,中断在命名和功能上总是由特定厂商(经常甚至是芯片)实现的。

中断提供了更多的灵活性,当尝试用一种高级的方法使用它们时,我们需要对这种灵活性进行解释。但我们将不会在这本书里涵盖这些内容,最好把下面的东西记在心里:

  • 中断有可以编程的优先级,其决定了它们的处理函数的执行顺序。
  • 中断能嵌套且抢占,i.e. 一个中断处理函数的执行可以被其它更高优先级的中断打断。
  • 通常需要清除掉导致中断被触发的原因,避免无限地再次进入中断处理函数。

运行时的常规初始化步骤始终相同:

  • 设置外设在遇到想要的事故发生的时候产生中断请求
  • 在中断控制器中设置需要的中断处理函数的优先级
  • 在中断控制器中使能中断处理函数

与异常相似,cortex-m-rt crate提供了一个interrupt属性去声明中断处理函数。可用的中断(及它们在中断向量表中的位置)通常由svd2rust从一个SVD描述文件自动地生成。

  1. // Timer2中断的中断处理函数
  2. #[interrupt]
  3. fn TIM2() {
  4. // ..
  5. // 清除生成中断请求的原因
  6. }

中断处理函数和异常处理函数一样看起来像是普通的函数(除了没有入参)。然而由于特殊的调用规定,它不能被固件的其它部分直接调用。但是,可以在软件中生成中断请求,触发一个控制权的转移。

与异常处理函数一样,它也能在中断处理函数中声明static mut变量且保持 safe 状态。

  1. #[interrupt]
  2. fn TIM2() {
  3. static mut COUNT: u32 = 0;
  4. // `COUNT` 的类型是 `&mut u32` 且它用起来安全
  5. *COUNT += 1;
  6. }

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