Zephyr中断系统-概述

Creative Commons
本作品采用知识共享署名

本文概览Zephyr中断系统的功能和技术手段。

Zephyr中断系统用于抽象和管理不同架构的芯片的中断,向内核使用者提供统一的接口。本系列文章预计3篇,用于介绍Zephyr中断系统的功能,实现和使用。本篇是第一篇概述Zephyr的功能和技术手段。

中断服务程序

中断系统的一个大功能就是管理中断服务程序(ISR), ISR是在响应硬件或者软件中断时以高优先级中断当前线程操作,在完成ISR所有操作后,恢复到线程操作。对于中断服务程序的管理Zephyr主要使用下面3技术手段

1.注册特定ISR

和所有的嵌入型软件一样,Zephyr可以将注册的ISR地址放入到硬件指向的中断向量表中,这种方式比软件中断向量表方式有更低ISR延迟。退出ISR时是否引发调度由ISR的返回值决定。

2.软件中断表

更一般的情况下,Zephyr内核提供了软中断列表,将注册的ISR保存在软中断表中,在硬件的中断向量表中放入统一的ISR,当IRQ发生时进入统一的ISR,进行查表,找到对应的ISR并执行,软中断表比特定的ISR会多一些检查,在退出ISR时会引发调度。

3.内核提供默认ISR

通常需要用户为特定的IRQ测试ISR,如果用户没有注册ISR,Zephyr会给予未注册的IRQ一个默认的ISR, 当IRQ发生时会该ISR会去主动触发fatal error 异常。

多级中断

Zephyr内核支援多级中断,从目前Zephyr的实现来看只有xtense和riscv内核的部分芯片在硬件上有多级中断,手上没板子,因此先不分析。有兴趣的朋友可以研究,关注下面宏相关的代码:

1
2
3
CONFIG_MULTI_LEVEL_INTERRUPTS
CONFIG_2ND_LEVEL_INTERRUPTS
CONFIG_3RD_LEVEL_INTERRUPTS

阻止中断

在线程执行一些动作时,出于动作的原子性和数据的完整性不希望被ISR打断,此时可以通过阻止中断来达到该目的。阻止中断有下面技术手段。

1. IRQ锁

IRQ锁会让所有IRQ都不执行,但只对执行锁的线程有效,例如A线程执行IRQ锁后,通过sem或者sleep引发调度,切换到B线程执行,B线程下IRQ是可以响应的。

2. IRQ禁止

IRQ禁止是全局的,后对所有线程都适用,一旦禁止无论在那个线程下将不会再响应任何IRQ。

3. 0延迟中断

IRQ锁会造成IRQ响应延迟,不满足一些要求ISR低延迟的特殊情况,Zephyr内核提供了一个不会被IRQ Lock的优先级,被用于该优先级的IRQ不会被lock。

ISR功能转移(offload ISR)

ISR的处理时间越短越好,对于一些复杂的ISR处理程序,在实现手段上可以将其分为两段处理,在ISR中处理最少的必要流程(必须在中断中处理的),其它流程被转移到辅助线程中处理。严格意义上这是一种普遍的设计手段,并不是Zephyr特有的,Zephyr也没有专门为该功能采用什么技术手段,我们可以采用下面两种方式实现该功能:

  • ISR处理完后通过内核对象(sem, fifo,lifo)向辅助线程发信息,辅助线程收到信号后执行需要转移的动作
  • ISR指示工作列队完成需要转移的动作

参考

https://docs.zephyrproject.org/latest/reference/kernel/other/interrupts.html