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();
}

相关文章
|
6月前
|
数据采集 调度 C语言
嵌入式系统中的定时器中断与任务调度
嵌入式系统中的定时器中断与任务调度
338 0
|
API
FreeRTOS学习笔记—FreeRTOS移植
本文学习了如何移植FreeRTOS到自己的STM32工程。最后,根据正点原子提供的测试main函数,测试了移植效果。
508 0
FreeRTOS学习笔记—FreeRTOS移植
|
传感器 调度 开发者
【Freertos基础入门】freertos任务的优先级
【Freertos基础入门】freertos任务的优先级
511 0
|
IDE 调度 开发工具
如何在S32DS中使用SystemView分析FreeRTOS
如何在S32DS中使用SystemView分析FreeRTOS
如何在S32DS中使用SystemView分析FreeRTOS
|
6月前
|
消息中间件 算法 调度
|
5月前
|
消息中间件 算法 编译器
【FreeRTOS(一)】FreeRTOS新手入门——初识FreeRTOS
【FreeRTOS(一)】FreeRTOS新手入门——初识FreeRTOS
|
5月前
|
存储 安全 算法
从0入门FreeRTOS之第二节FreeRTOS的体系结构
FreeRTOS的体系结构设计精巧且高效,专为嵌入式系统量身打造。理解FreeRTOS的体系结构对开发高效、稳定的嵌入式应用至关重要。下面,我们详细介绍FreeRTOS的核心组件、内核机制、中断管理和内存管理等内容。
191 0
|
6月前
|
算法 API 调度
【FreeRTOS】多任务创建
【FreeRTOS】多任务创建
|
存储 算法 调度
FreeRTOS多任务系统
FreeRTOS多任务系统
132 0
|
6月前
|
存储 API 调度
FreeRTOS深入教程(任务创建的深入和任务调度机制分析)
FreeRTOS深入教程(任务创建的深入和任务调度机制分析)
301 0