嵌入式实时操作系统uC/os-II(六)-任务调度

uC/OS-II的任务调度的思想是:“近似地每时每刻让优先级最高的就绪任务处于运行状态”。

 调度器的定义在多任务系统中,令CPU中止当前正在运行的任务转而去运行另一个任务的工作叫做任务切换,而按照某种规则进行任务切换的工作叫做任务的调度。

uC/OS-II中,任务调度由任务调度器来完成。任务调度器的主要工作有两项:一是在任务就绪表中查找具有最高优先级别的就绪任务;二是实现任务的切换。

  • 调度器的种类
  1. 任务级:函数OSSched()实现。
  2. 中断级:函数OSIntExt()实现。

调度器把任务切换的工作分为两个步骤:第一步是获得待运行任务的TCB指针;第二步进行断点数据的切换。

获得待运行就绪任务控制块的指针

        由于操作系统是通过任务的任务控制块TCB来管理任务,因此调度器真正实施任务切换之前的主要工作就是要获得待运行任务的任务控制块指针和当前任务的任务控制块指针。

  1. 因为被中止的任务的任务控制块指针就存放在全局变量OSTCBCur中,所以调度器这部分的工作主要是获得待运行任务的任务控制块指针。
    1. 任务级调度器OSSched()的源代码如下:

void OSSched(void)

{

         #if OS_CRITICAL_MOTHOD == 3

                   OS_CPU_SR cpu_sr;

         #endif

        

         INT8U y;

        

OS_ENTER_CRITICAL();

if((OSLockNesting | OSIntNesting ) == 0)

{

         y = OSUnMapTbl[OSRdyGrp];  //得到最高优先任务

         OSPrioHighRdy = (INT8U) ((y<<3) + UnMapTbl[OSRdyTbl[y]]); //得到任务控制块指针

         if(OSPrioHighRdy != OSPrioCur)

         {

                   OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];

                   OSCtxSwCtr++;        //统计任务切换次数的计数器加1

                   OS_TASK_SW();     //任务切换

           }

}

         OS_EXIT_CRITICAL();

}

调度器OSSched在确认未被上锁并且不是中断服务程序调用调度器的情况下,首先从任务就绪表中查得最高优先级别就绪任务的优先级别OSPrioHighRdy;然后在确认这个就绪任务不是当前正在运行的任务(OSPrioCur是存放正在运行任务的优先级别的变量)的条件下,用OSPrioHighRdy作为下标去访问数组OSTCBPrioTbl[],把数组元素OSTCBPrioTbl[OSPrioHighRdy]的值(即待运行就绪任务的任务控制块指针)赋给指针变量OSTCBHighRdy。接下来就依据OSTCBHighRdyOSTCBCur这两个指针分别指向待运行任务控制块和当前任务控制块,从而在宏OS_TASK_SW中实施任务切换。过程如下图所示

                                         

                                    调度器在任务切换前获得的两个指针OSTCBCurOSTCBHighRdy 

任务切换宏OS_TASK_SW

        简单来说,任务切换就是中止正在运行的任务(当前任务),转而去运行另一个任务的操作。 如果把任务被中止运行时的位置叫做断点,把当时存放在CPUPCPSW和通用寄存器等各寄存器中的数据叫做断点数据,那么任务恢复运行时,必须在断点处以断点数据作为初始数据接着运行,才能实现“无缝”的接续运行。

       任务在被中止运行时保护断点数据的动作如图2-11所示。 

                                           

                                                                     任务保护断点时的压栈动作

  • 如何实现使被中止运行的任务在恢复运行时可以实现“无缝”的接续运行?

要实现“无缝”的接续运行,则必须在任务被中止时就把任务的断点数据保存到堆栈中;而在被重新运行时,则要把堆栈中的这些断点数据恢复到CPU的各寄存器中

由上图可知,一个被中止的任务能否正确地在断点处恢复运行,其关键在于是否能正确的在CPU各寄存器中恢复断点数据;而能够正确恢复断点数据的关键是CPU的堆栈指针SP是否有正确的指向。为了防止被中止任务堆栈指针的丢失,被中止任务在保存断点时,要把当时CPUSP的值保存到该任务控制块的成员OSTCBStkPtr中。

综上所述,任务的切换就是断点数据的切换,断点数据的切换也就是CPU堆栈指针的切换,被中止运行任务的任务堆栈指针要保护到任务的任务控制块中,待运行任务的任务的任务堆栈指针要由该任务控制块转存到CPUSP中。

调度器在任务切换时工作过程如图2-12所示。

                                                

                                                                             图2-12 调度器进行任务切换的动作

为了完成上述操作,OSCtxSw要依次做如下工作:

  1. 把被中止任务的断点指针保存到任务堆栈中;
  2. CPU通用寄存器的内容保存到任务堆栈中;
  3. 把被中止任务的任务堆栈指针当前值保存到该任务的任务控制块的OSTCBStkPtr中;
  4. 获得待运行任务的任务控制块;
  5. 使CPU通过任务控制块获得待运行任务的任务堆栈指针
  6. 把待运行任务的任务堆栈指针中通用寄存器的内容恢复到CPU的通用寄存器中;
  7. 使CPU获得待运行任务的断点指针。
  • 断点的保护和恢复

想办法引发一次中断,并让中断向量指向OSCtxSw(),利用系统在跳转到中断服务程序时会自动把断点指针压入堆栈的功能,把断点指针存入堆栈,而利用中断返回指令IRET能把断点指针推入CPUPC寄存器的功能,恢复待运行任务的断点,这样就可以实现断点的保存和恢复了。

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式实时操作系统uc/os-ii是一款常用于单片机和嵌入式系统的操作系统。其原理基于事件驱动,采用优先级调度策略,具有快速响应和可靠性高的特点。 在uc/os-ii中,任务是程序的基本执行单位。每个任务都有自己的优先级和任务控制块(TCB)来存储任务的状态信息。任务的切换是通过调度器根据优先级来实现的,优先级高的任务会被优先执行。 uc/os-ii还提供了一系列的内核服务,包括任务管理、时间管理、事件管理、信号量管理等。任务管理主要负责任务的创建、删除和切换,时间管理用于定时操作和延时等待,事件管理用于任务间的同步与通信,信号量管理则用于提供资源和互斥访问。 应用方面,uc/os-ii嵌入式系统中广泛应用于实时任务的处理。例如,可以将传感器数据读取作为一个任务,数据处理和决策作为另一个任务,控制指令输出作为第三个任务。通过uc/os-ii来管理这些任务,可以保证数据的准确性和实时性。 此外,uc/os-ii还可以应用于物联网设备、智能家居、工业自动化等领域。例如,在物联网设备中,可以使用uc/os-ii来实现设备的状态监测、数据传输和远程控制等功能。 总之,uc/os-ii是一款功能强大的嵌入式实时操作系统,能够提供可靠的任务管理和事件处理机制,广泛应用于各种嵌入式系统中,提高系统的可靠性和实时性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值