查看: 2977|回复: 0

清风徐来——Zephyr实战篇(6)之中断

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3303

    主题

    6550

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32074
    最后登录
    2024-5-7
    发表于 2022-3-10 10:04:41 | 显示全部楼层 |阅读模式
    清风徐来——Zephyr实战篇(6)之中断


    这次小编为大家介绍ZephyrOS里的中断。抱歉小编被中断了一段时间 :-)

    "清风徐来"前期回顾:
    新型物联网操作系统Zephyr介绍
    Zephyr实战篇(1)之环境搭建
    Zephyr实战篇(2)之西(工具)
    Zephyr实战篇(3)之DeviceTree

    Zephyr实战篇(4)之Kconfig
    Zephyr实战篇(5)之Shell


    ——————Zephyr中断系统一览——————
    首先我们来看下Zephyr中的中断系统有什么特别之处:
    1. 内核为所有未使用的中断提供了默认的中断服务程序,如果一个未定义中断被触发会产生一个系统错误
    2. 支持中断的嵌套
    3. 中断服务程序执行在内核中断上下文
        A.拥有自己的栈空间
        B.要注意,栈的容量要足够大,以支持中断的嵌套
    4. 软中断服务程序
       A.常规中断一般都通过一个叫做软中断的服务程序进行管理
       B.通过查找软中断向量表,能够获取实际要执行的中断服务程序(下文统称ISR)入口以及参数
       C.从ISR返回时,决定是否进行线程的切换
    5. 多数内核API只能在线程中使用,不能在ISR中使用,那些可以在ISR中使用的内核API往往都有一个isr_ok的属性。

    ——————Zephyr的ISR——————
    再来看下,Zephyr中的ISR类型,Zephyr中的中断服务类型大致分为3类:


    1. 常规ISR:
    由软中断服务程序所调用,不能直接运行
    简单,使用方便


    2. 直接ISR:
        A.不使用软中断服务程序,直接注册进硬件中断向量表中
        B.低延时,但是有很多限制,比如不能传入参数


    3. 零延时ISR:顾名思义就是延时最低的
        A.拥有最高的中断优先级,不受中断锁影响
        B.既可以是常规ISR也可以是直接ISR

    ——————Zephyr的中断向量表——————
    说完中断类型,介绍一下Zephyr中的中断向量表的概念,除了硬件中断向量表,Zephyr中还有一个较为新的概念,我们在上文中也有所提及,叫做软件中断向量表,那么他们都各自负责什么呢?我们来一一介绍。
    1. 硬件中断向量表:前16个位置固定给了内核服务,其他位置,如果没有被注册的话,填入的是通用的中断服务程序_isr_wrapper()
    2. 软件中断向量表:内部存储的是所注册的中断服务程序,以及想要传入的参数,所有所有未添加中断服务程序的地方,都会被写入z_irq_spurious()


    3. 通用中断服务程序_isr_wrapper()作用:
    中断函数第一入口,他是软件中断向量表的使用者
    负责取出真正的中断服务程序入口以及参数
    4. 直接中断:直接被装配到硬件中断向量表,当中断到来时,直接被执行


    下图是完整的中断服务注册逻辑:
    14.png
    如何定义一个中断
    了解了中断实现以及执行逻辑,我们来看看如何实际定义一个中断,首先是常规中断,只需要两个步骤:


    1. 使用宏IRQ_CONNECT进行中断定义,需要注意的是,所有参数的数值必须是编译期确定的,其原型是IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p),各参数说明如下:
    irq_p: 中断号
    priority_p: 中断优先级
    isr_p: 中断服务函数
    fags_p: 中断标志


    2. 使用irq_enable()使能中断
    当然,上述方式是在编译期进行中断的注册,Zephyr也同时支持运行期间通过调用函数irq_connect_dynamic()注册,但是需要配置CONFIG_DYNAMIC_INTERRUPTS
    下面是一段参考事例:
    1. #define MY_DEV_IRQ 24 /* device uses IRQ 24 */
    2. #define MY_DEV_PRIO 2 /* device uses interrupt priority 2 */
    3. /* argument passed to my_isr(), in this case a pointer to the device */
    4. #define MY_ISR_ARG DEVICE_GET(my_device)
    5. #define MY_IRQ_FLAGS 0 /* IRQ flags */

    6. void my_isr(void *arg)
    7. {
    8.    ... /* ISR code */
    9. }

    10. void my_isr_installer(void)
    11. {
    12.    ...
    13.    IRQ_CONNECT(MY_DEV_IRQ, MY_DEV_PRIO, my_isr, MY_ISR_ARG, MY_IRQ_FLAGS);
    14.    irq_enable(MY_DEV_IRQ);
    15.    ...
    16. }
    复制代码
    接下来是直接中断,实现方式略有不同,需要用户调用IRQ_DIRECT_CONNECT:
    1. #define MY_DEV_IRQ 24 /* device uses IRQ 24 */
    2. #define MY_DEV_PRIO 2 /* device uses interrupt priority 2 */
    3. /* argument passed to my_isr(), in this case a pointer to the device */
    4. #define MY_IRQ_FLAGS 0 /* IRQ flags */

    5. ISR_DIRECT_DECLARE(my_isr)
    6. {
    7.    do_stuff();
    8.    ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency */
    9.    return 1; /* We should check if scheduling decision should be made */
    10. }

    11. void my_isr_installer(void)
    12. {
    13.    ...
    14.    IRQ_DIRECT_CONNECT(MY_DEV_IRQ, MY_DEV_PRIO, my_isr, MY_IRQ_FLAGS);
    15.    irq_enable(MY_DEV_IRQ);
    16.    ...
    17. }
    复制代码
    ——————Zephyr的零延时中断——————
    最后聊聊零延时中断,上文说过,零延时中断的类型可以是直接中断也可以是常规中断,换句话说,他的实现方式与上述两种大致相同,唯一不同的是,中断标志位需要传入IRQ_ZERO_LATENCY以指示这是一个零延时中断。


    那么为什么要设计零延时中断呢?


    最主要的原因是,在程序设计时,我们往往会在程序中加入irq lock,保证代码运行不会被中断打断,但是这样一来,就可能提高系统的延时,对于一些时间敏感的应用案例,高延时往往是不可接受的。


    那么此时,零延时中断的作用就体现了,他自身运行在一个不会被lock的优先级,当然需要通过CONFIG_ZERO_LATENCY_IRQS使能。这样一来,一旦中断被触发,其对应的中断处理函数能够马上被执行,大大降低中断延时。
    ——————结语——————
    本期文章,小编主要给大家分享了Zephyr中的中断系统的一些基础概念,最特殊的地方在于,Zephyr引入了一个软件中断向量表的概念,使得我们的中断服务程序可以接收参数,但是弊端就在于会引入一点中断延时,这样在实际使用中,我们就要权衡利弊,各取所好了。


    好了,话说到这儿,小编就又要和大家说再见了,我们下期再见。







    签到签到
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-5-7 17:10 , Processed in 0.114284 second(s), 19 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表