Bootstrap

UCOSIII 时间片轮调度接口OS_SchedRoundRobin详解

        时间片轮调度(Round-Robin Scheduling)是一种常见的任务调度算法,它将CPU时间片均匀地分配给每个任务,确保每个任务在一定时间内能够获得CPU资源。这种调度方式适用于需要公平分配CPU时间的系统,特别是在有多个相同优先级的任务时,片轮调度能有效防止某个任务长期占用CPU资源。本文将详细介绍uCOS-III中的片轮调度的配置使用及实现原理。

 1. 片轮调度的配置及使用

1.1 编译前配置宏定义使能

在配置片轮调度之前,需要在配置文件 os_cfg.h 中使能相关宏定义:

#define OS_CFG_SCHED_ROUND_ROBIN_EN  1u  /* Enable (1) or Disable (0) Round Robin scheduling */

1.2 运行时配置使能及片轮时间

void OSSchedRoundRobinCfg(CPU_BOOLEAN en, OS_TICK dflt_time_quanta, OS_ERR *p_err);

参数解释:

  • en:确定是否启用片轮调度,当值为 OS_TRUE 时启用,为 OS_FALSE 时禁用。
  • dflt_time_quanta:默认的时间片长度(单位为系统时钟节拍),如果设置为0,则默认值为 OSCfg_TickRate_Hz / 10
  • p_err:指向错误代码变量的指针,函数返回时会通过该变量报告错误状态。

2. 时间片轮调度的使用场景

多任务环境:系统中有多个相同优先级的任务需要公平地分配CPU时间。

任务并发:提高任务的响应速度,确保系统的实时性和公平性

3. 片轮调度的实现原理

        片轮调度的核心实现包括 OS_SchedRoundRobinOSSchedRoundRobinYield 函数。OS_SchedRoundRobin 函数在每个系统时钟节拍(tick)中被调用,用于更新当前任务的时间片计数器并决定是否需要切换任务。而 OSSchedRoundRobinYield 函数允许任务在完成当前时间片之前主动放弃CPU。

3.1 OS_SchedRoundRobin 调用流程图

3.1 OS_SchedRoundRobin 实现流程图

4. 如何配置任务时间片长度 

可以通过以下方式配置任务的时间片长度:

全局配置:使用 OSSchedRoundRobinCfg 函数设置所有任务的默认时间片长度。

void OSSchedRoundRobinCfg(CPU_BOOLEAN en, OS_TICK dflt_time_quanta, OS_ERR *p_err);

任务创建时配置:在创建任务时,通过 OSTaskCreate 函数的 time_quanta参数设置特定任务的时间片长度。

p_tcb->TimeQuanta = time_quanta; /* Save the #ticks for time slice (0 means not sliced) */
if (time_quanta == 0u) {
    p_tcb->TimeQuantaCtr = OSSchedRoundRobinDfltTimeQuanta;
} else {
    p_tcb->TimeQuantaCtr = time_quanta;
}

运行时配置:使用 OSTaskTimeQuantaSet 函数在任务运行期间动态修改特定任务的时间片长度。

void OSTaskTimeQuantaSet(OS_TCB *p_tcb, OS_TICK time_quanta, OS_ERR *p_err);

5. 任务主动放弃时间片

  当前任务调用OSSchedRoundRobinYield, 主动放弃剩余的时间片,让出CPU,以便调度器能切换到其他任务执行。

6. 时间片轮调度的缺点

  • 效率问题:时间片轮调度需要频繁地切换任务,这会带来一定的上下文切换开销,尤其是在任务切换频繁的情况下。
  • 锁竞争问题:在多任务环境中,不同任务对资源的竞争可能导致死锁的问题。
  • 临界资源问题:在多任务环境中,临界资源竞争问题可能会破坏数据的完整性及可视化

总结

        片轮调度是一种有效的任务调度策略,能够确保同优先级任务之间的公平性。在uCOS-III中,通过配置和使用片轮调度,可以在多任务环境中实现高效的任务管理。然而,需要根据系统的具体情况合理配置时间片长度,以避免潜在的效率问题、临界资源竞争问题。

;