zoukankan      html  css  js  c++  java
  • UCOS任务切换详解

    1 UCOS知识点

    (1) UCOS是可剥夺型的多任务内核。当一个高优先级的任务准备就绪,并且此时发生了任务调度,那么高优先级的任务就会获得CPU的使用权。

    (2) 任务调度就是终止当前正在运行的任务转而去执行其他的任务。

    (3) 每个任务都有自己的任务控制块:OS_TCB类型(结构体类型)。用来维护任务相关的信息,比如任务栈顶地址、栈的容量、任务当前状态等信息。OS_TCB存储于RAM中。

    (4) 每个任务都有自己的:OS_STK类型(数组)。栈可以静态分配,也可以使用malloc()函数从堆中动态分配。由于频繁创建和删除任务会导致内存碎片产生,因此一般栈空间不需要被释放掉。栈作用一是保存任务的局部变量;二是当任务挂起时保存CPU寄存器的值(也就是现场)。

    (5) 任务可以访问全局变量,但是全局变量会被多个任务共享,且任务是可剥夺型的,因此这样做不安全,UCOS提供了保护机制(信号量,互斥信号量)。

    2 UCOS任务切换

    (1) 任务处于休眠态(指任务已存在存储器中,但还不受UCOS管理);

    (2) 通过OSTaskCreate()函数,任务处于就绪态;任务就绪表保存已经就绪的的任务。

    (3) 此时发生了任务调度。任务调度有两种:1.任务级调度器OSSched();2.中断级调度器OSIntExit()

      OSSched():

      (1)扫描就绪任务表中就绪任务中优先级最高的任务;

      (2)获取到优先级最高任务的控制块;

      (3)把当前任务CPU寄存器里的值保存到栈里面,并把CPU堆栈指针寄存器(TSP)的值存放到OS_TCB中;

      (4)把新任务OS_TCB中保存的TSP值载入到CPU堆栈指针寄存器(TSP);

      (5)从新的堆栈中恢复CPU寄存器的值,此时新的任务就运行了

      OSIntExit():

      (1)中断嵌套计数器OSIntNestingCtr减1

      (2)如果OSIntNestingCtr=0,也就是最后一层嵌套的中断(再返回就到任务级了),并且调度器没有上锁

      (3)获取到优先级最高任务的控制块;

      (4)因为在进入中断服务程序前任务的现场已经保存了,因此这里不用再保存;

      (5)把新任务OS_TCB中保存的TSP值载入到CPU堆栈指针寄存器(TSP);

      (6)从新的堆栈中恢复CPU寄存器的值,此时新的任务就运行了

    备注:

    OSSched()实际是调用了OS_TASK_SW(),OS_TASK_SW()是调用了OSCtxSw(),而OSCtxSw()实质是进入异常中断服务程序OS_CPU_PendSVHandler

    3 任务调度点

    3.1 会调用OSSched()的情况:

      (1)给另一个任务发送消息或信号量,OS??? Post()

      (2)任务调用延时函数OSTimeDly()或OSTimeDlyHMSM()

      (3)任务在等待一个时间的发生(消息或者信号量)OS??? Pend()

      (4)任务取消等待OS??? PendAbord()

      (5)创建一个更高优先级的任务OSTaskCreate()

      (6)当前任务被删除OSTaskDel()

      (7)任务自身被挂起OSTaskSuspend()

      (8)用户直接调用OSSched()

    3.2 会调用OSIntExit()的情况:

      当所有的中断嵌套结束时,在返回任务前要调用OSIntExit()函数

  • 相关阅读:
    k8s service定义与创建
    k8s service存在的意义
    k8s job控制器-执行一次性任务
    k8s CronJob定时任务
    k8s Daemonset功能
    k8s deployment控制器Replicaset
    k8s deployment删除
    k8s deployment控制器水平扩容
    k8s deployment发布失败回滚
    k8s deployment控制器:滚动升级 平滑过渡 零停机
  • 原文地址:https://www.cnblogs.com/Mike2019/p/12548536.html
Copyright © 2011-2022 走看看