ucos-ii 任务调度

简介: (1)任务级的任务切换原理  μC/OS-II是一个多任务的操作系统,在没有用户自己定义的中断情况下,任务间的切换步骤是这样的:任务间的切换一般会调用OSSched()函数。
(1)任务级的任务切换原理
  μC/OS-II是一个多任务的操作系统,在没有用户自己定义的中断情况下,任务间的切换步骤是这样的:任务间的切换一般会调用OSSched()函数。函数的结构如下:
  void OSSched(void){
  关中断
  如果(不是中断嵌套并且系统可以被调度){
  确定优先级最高的任务
  如果(最高级的任务不是当前的任务){
  调用OSCtxSw();
  }
  }
  开中断
  }

 

void OSSched (void)
{
    INT8U y;


    OS_ENTER_CRITICAL();
    if ((OSLockNesting | OSIntNesting) == 0) { (1)
        y             = OSUnMapTbl[OSRdyGrp]; (2)
        OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); (2)
        if (OSPrioHighRdy != OSPrioCur) { (3)
            OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; (4)
            OSCtxSwCtr++;                                              (5)
            OS_TASK_SW();                                              (6)
        }
    }
    OS_EXIT_CRITICAL();
}

  我们把这个函数称作任务调度的前导函数。它先判断要进行任务切换的条件,如果条件允许进行任务调度,则调用OSCtxSw()。这个函数是真正实现任务调度的函数。由于期间要对堆栈进行操作,所以OSCtxSw()一般用汇编语言写成。它将正在运行的任务的CPU的SR寄存器推入堆栈,然后把R4~R15压栈。接着把当前的SP保存在TCB->OSTCBStkPtr中,然后把最高优先级的TCB->OSTCBStkPtr的值赋值给SP。这时候,SP就已经指到最高优先级任务的任务堆栈了。然后进行出栈工作,把R15~R4出栈。接着使用RETI返回,这样就把SR和PC出栈了。简单地说,μC/OS-II切换到最高优先级的任务,只是恢复最高优先级任务所有的寄存器并运行 中断返回指令(RETI),实际上,所作的只是人为地模仿了一次中断。
  (2)中断级的任务切换原理
  μC/OS-II的中断服务子程序和一般前 后台的操作有少许不同,往往需要这样操作:
  保存全部CPU寄存器
  调用OSIntEnter()或OSIntNesting++
  开放中断
  执行用户代码
  关闭中断
  调用OSIntExit();
  恢复所有CPU寄存器
  RETI

  OSIntEnter()就是将全局变量OSIntNesting加1。OSIntNesting是中断嵌套层数的变量。μC/OS-II通过它确保在中断嵌套的时候,不进行任务调度。执行完用户的代码后,μC/OS-II调用OSIntExit(),一个与OSSched()很像的函数。在这个函数中,系统首先把OSIntNesting减1,然后判断是否中断嵌套。如果不是的话,并且当前任务不是最高优先级的任务,那么找到优先级最高的任务,执行OSIntCtxSw()这一出中断任务切换函数。因为,在这之前已经做好了压栈工作;在这个函数中,要进行R15~R4的出栈工作。而且,由于在之前调用函数的时候,可能已经有一些寄存器被压入了堆栈。所以要进行堆栈指针的调整,使得能够从正确的位置出栈。

void OSIntExit (void)
{
    OS_ENTER_CRITICAL();                                             (1)
    if ((--OSIntNesting | OSLockNesting) == 0) {                     (2)
        OSIntExitY    = OSUnMapTbl[OSRdyGrp];                        (3)
        OSPrioHighRdy = (INT8U)((OSIntExitY << 3) +
                        OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
        if (OSPrioHighRdy != OSPrioCur) {
            OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
            OSCtxSwCtr++;
            OSIntCtxSw();                                            (4)
        }
    }
    OS_EXIT_CRITICAL();
}

相关文章
|
存储 移动开发 数据库
构建高效Android应用:探究LiveData和ViewModel的最佳实践
【4月更文挑战第20天】 在动态演化的移动开发领域,构建一个既响应迅速又能够在用户界面保持稳定的Android应用是至关重要的。近年来,随着Android架构组件的推出,特别是LiveData和ViewModel的引入,开发者得以更有效地管理应用状态并优化用户界面的响应性。本文将深入探讨LiveData和ViewModel的实现机制,并通过案例分析展示如何结合它们来构建一个高效且健壮的Android应用架构。我们将重点讨论如何通过这些组件简化数据绑定过程、提高代码的可维护性和测试性,同时确保用户界面的流畅性。
227 4
|
7月前
|
存储 安全 搜索推荐
时统设备:构建精准时间体系的关键力量​
在现代科技中,时间精准同步至关重要。时统设备作为核心装备,广泛应用于国防、通信、电力和金融等领域。文章聚焦同步天下品牌的SYN012型设备及B码时统设备,解析其功能、特点与应用场景。SYN012型设备支持多种信号输入输出,适应复杂环境;B码设备则具备高精度授时和多样化输出能力。两者为各领域提供可靠时间保障,推动科技进步。文章强调原创保护,禁止未经授权转载。
|
开发者 Python
【python圣诞树的实现】
【python圣诞树的实现】
320 0
|
存储 缓存 固态存储
ZNS SSD前途是否一片光明?
ZNS SSD虽然有很大的优势,想要创出一片天地,依然需要多方面的努力。期待ZNS SSD可以早日实现美好的愿景。
|
存储 边缘计算 运维
|
22天前
|
人工智能 前端开发 安全
AI 最先替代的开发工作:从重复劳动到人机协同的新范式
AI正加速替代基础开发工作:CRUD页面、样板代码、简单Bug修复、文档生成与基础测试等重复性任务已可通过低代码平台与AI工具高效完成,显著提升生产力。据Gartner报告,70%企业内部系统已采用AI辅助开发,人力投入减少60%-80%。GitHub Copilot等工具更让开发者节省45%编码时间。然而,产品需求分析、系统架构设计、复杂交互体验及创新研发等需深度判断与创造力的工作,仍依赖人类智慧。未来开发者将转型为“AI指挥官”,聚焦问题定义、提示工程与人机协同,核心竞争力转向系统思维、业务理解与技术创新。
220 15
|
SQL 存储 缓存
MySQL执行流程
本文介绍了MySQL的执行流程,分为server层和引擎层。server层包含连接器、查询缓存、解析器、预处理器、优化器等组件,负责SQL的接收、解析、优化及执行;引擎层负责数据的存储与读取。文章详细解释了各组件的功能,如连接器负责用户身份认证,查询缓存提高查询效率,解析器进行SQL的词法和语法分析,预处理器验证表和字段的存在性,优化器选择最优执行计划,最终由查询执行引擎完成查询并将结果返回给客户端。
261 0
MySQL执行流程
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
335 2
Sentinel学习圣经:从入门到精通 Sentinel,最全详解 (40+图文全面总结)
尼恩给大家做一下系统化、体系化的梳理,联合社群小伙伴,来一个Sentinel学习圣经:从入门到精通Sentinel。
|
SQL Oracle 关系型数据库
关系型数据库Oracle结束 RMAN 会话:
【7月更文挑战第25天】
413 1