uC/OS 的进程调度(上)

操作系统最重要的任务之一就是进程调度,它涉及三个主要方面:

  1. 何时进行调度
  2. 如何选择下一个活动进程
  3. 如何实现进程切换

每种操作系统差别很大,本文对uC/OS的进程调度机制进行一些细致分析。

何时进行调度

uC/OS是嵌入式实时操作系统,实时操作系统的重点就是给定事件的响应时间尽可能短。因此任务调度的发生时机比较多,包括:

  1. 操作系统启动时,会发生调度;
  2. 高优先级任务建立后,会发生调度;
  3. 通过调整优先级将一个低优先级任务变为当前最高优先级任务后,该任务会立即执行;
  4. 主动挂起的高优先级任务被恢复后,会立即执行;
  5. 调用延时函数的高优先级任务到期后,或被取消延时后,会立即执行;
  6. 因等待某一事件(信号量、邮箱、事件、队列等)而挂起的高优先级任务,当事件到来时会立即执行;
  7. 当最高优先级任务等待某个事件而挂起时,会选择当前就绪态的最高优先级任务,该任务立即执行;
  8. 锁定任务调度功能后,解锁时会发生调度;
  9. 任务删除时,会发生调度;

具体来说,这几个时机完成调度的细节是:

  1. 在调用OSStart()启动操作系统时,uC/OS会选择当前的一个最高优先级任务,然后调用OSStartHighRdy()切换到该任务。
  2. 在调用OSTaskCreate()或OSTaskCreateEx建立一个任务时,在完成TCB的基本初始化后,会调用OS_Sched()进行任务切换。
  3. 在调用OSTaskChangePrio()改变一个任务优先级时,在完成优先级变化后,符合一定条件下会调用OS_Sched()进行任务切换。
  4. 在某个任务调用OSTaskResume()恢复某个任务的执行时,符合一定条件下会调用OS_Sched()进行任务切换。
  5. 延时函数的正常到期是由定时中断触发的,在中断的恢复阶段,会调用OSIntCtxSw()切换到最高优先级任务。延时函数的非正常到期是由OSTimeDlyResume()的调用触发的,在其中会主动调用OS_Sched()进行任务切换。
  6. 在各种信号量、邮箱、事件和队列等的Post、PendAbort和Del函数中,都会调用OS_Sched()进行任务切换。
  7. 在各种信号量、邮箱、事件和队列等的Pend函数中,若当前任务需挂起,会调用OS_Sched()进行任务切换。
  8. 在OSSchedUnlock()函数解锁任务调度后,若任务调度已经使能,则会调用OS_Sched()进行任务切换。
  9. 在调用OSTaskDel()删除某个任务时,会调用OS_Sched()进行任务切换。

可见调度时机总结成一句话就是:满足调度条件,就毫不犹豫立即调度,绝不会等待和迟疑。从这里可以体现出uC/OS作为实时操作系统的重要特点。

如何选择下一个活动进程

uC/OS是实时操作系统,它划分了64个优先级(uC/OS-II),每个任务的优先级均不同,在发生调度时,永远都会选择处于就绪态的最高优先级的任务。

为了在有限时间内快速选择出一个就绪任务,uC/OS-II建立了两级就绪表,每个任务(即每个优先级)在一级就绪表OSRdyTbl中占一个比特,每8个比特又组成成一位形成OSRdyGrp。这样先从OSrdyGrp中找到最高优先级任务所在组,再从OSRdyTbl的该组找到该任务。

OSRdyGrp

为了加速,又预先准备了一张优先级判定表OSUnMapTbl,从该表中可以一步直接寻址到最高优先级所在的比特。

================ os_core.c 38 55 ==================
INT8U  const  OSUnMapTbl[256] = {
    0u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值