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
3CONFIG_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