找回密码
 立即注册
查看: 389|回复: 0

CosyOS-II “中断挂起服务缓存” 为何必须先入先出?

[复制链接]
  • TA的每日心情
    奋斗
    3 小时前
  • 签到天数: 174 天

    [LV.7]常住居民III

    5

    主题

    580

    回帖

    2351

    积分

    荣誉版主

    积分
    2351
    发表于 2023-10-22 13:34:51 | 显示全部楼层 |阅读模式
    本帖最后由 CosyOS 于 2023-10-24 01:13 编辑

    “中断挂起服务”是 CosyOS 实现“零中断延迟”这一目标的关键技术之一,今天论证一下:

    CosyOS-II 中的“中断挂起服务缓存”为何必须先入先出?

    传统RTOS在中断中调用服务时,通常是先要关中断,而后执行服务,然后再开中断,以保证服务的“执行流”不会被打断。

    CosyOS 为了实现零中断延迟,采用了中断挂起服务的方案。
    所谓中断挂起服务,是指在中断中调用的服务不在本地直接执行,而是把服务的相关信息存入局部的结构体中,再把
    结构体指针存入中断挂起服务缓存,再触发PendSV,而后在PendSV中执行。PendSV是最低优先级中断,位于 CosyOS
    实时运行模型 中的服务层,所有服务(中断本地服务除外)均在本层执行,从而保证服务的“操作流”不会被打断。

    通常在中断中既有用户自己的代码又有服务调用,而中断又是高优先级抢占的,所以当多个中断并发时,服务的调用顺序
    不一定是中断的发生顺序或响应顺序,具有一定的随机性。从这个角度来说,
    CosyOS 的中断挂起服务,没有必要先入先出,顺序可以随意打乱,只要最后能够一个不落的执行完成所有服务即可。

    事实真的是这样吗?让我们来看下面这种情况。
    当多个中断并发时,由于PendSV优先级最低,导致PendSV迟迟未能进入(服务未执行)。此时,某个中断已经二次或多次进入,
    而每次进入时调用的服务又都是反操作。
    例如某个中断第一次进入时调用的服务是iSuspendTask(task_a),第二次进入时调用的服务是iResumeTask(task_a):
    (1)如果是传统RTOS,当然是先执行iSuspendTask(task_a),后执行iResumeTask(task_a),最终结果是task_a被恢复运行,符合用户的预期。
    (2)换做是CosyOS,如果中断挂起服务缓存是先入先出FIFO,则先执行iSuspendTask(task_a),后执行iResumeTask(task_a),符合用户的预期。
            如果是后入先出LIFO,则最终结果是task_a被挂起,与用户的初衷相违背。

    通过以上分析可知,
    对于零中断延迟的RTOS(CosyOS)来说,中断挂起服务缓存必须先入先出FIFO,才会完全符合用户的预期,否则可能会导致错误的结果。
    CosyOS-I 在这方面是有缺陷的,Arm为LIFO,51/251为按序查询。
    CosyOS-II 已实现所有内核(Arm、51/251)中断挂起服务缓存均为先入先出FIFO,从此再无遗憾。
    CosyOS-II 源码中,“中断挂起服务缓存”在 mcucfg文件 中定义,并命名为 “mPendSV_FIFO”

    另外再补充说明一点,中断挂起服务缓存要想实现先入先出FIFO,并非是一件容易的事情,原因是整个“入”和“出”的过程(操作流),
    必须是原子操作,不能被打断。那 CosyOS-II 又是如何实现这一过程的呢?有兴趣的朋友可自行阅读源码,一探究竟。



    回复 送花

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-18 14:13 , Processed in 0.054919 second(s), 28 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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