当多个任务有相同的优先级时,UCOSIII允许每个任务运行规定的时间片,当任务没有用完分配给它的时间片时,它可以自愿地放弃CPU,当它的时间片已耗尽但任务还没执行完,CPU会剥夺它当前的使用,下一个任务开始执行。同时,UCOSIII允许任务在运行时开启或者关闭循环轮调度。
原理
由最上面的Tick ISR(滴答定时器中断、时基中断)可知,时间片的长度为四个时基,滴答定时器中断在每个时基结束都会发生,时间片轮转调度可以设置时基的整数倍作为时间片的长度。
任务1、2、3为相同优先级的三个任务,在在时间片轮转的调度下有序执行,至于他们的执行顺序,这是由调度队列来调控的,一个任务出队(执行)后会被插入到队尾,这样就实现了多个任务的循环执行。
(1)任务3正在执行,时基中断发生,但任务3还没有到期
(2)任务3主动放弃剩下的时间片
(3)UCOSIII恢复任务1,因为它是调度队列中任务3的下一个任务
(4)任务1执行直到它的时间片到期
(5)、(6)、(7)、(8)同上
API函数
在使用API函数之前,要先在os_cfg.h中使能时间片轮转调度,将OS_CFG_SCHED_ROUND_ROBIN_EN定义为1,这样有关时间片轮转调度的代码才会被编译。
OSSSchedRoundRobinCfg()用来使能或失能时间片轮转调度
函数原型:
void OSSchedRoundRobinCfg (CPU_BOOLEAN en,
OS_TICK dflt_time_quanta,
OS_ERR *p_err)
en:设置打开或关闭时间片轮转调度,DEF_ENABLED表示打开DEF_DISABLED表示关闭
dflt_time_quanta:设置时间片长度,系统时钟节拍(时基)的个数,若设置为0,使用默认的时间片长度,系统频率/10
*p_err:错误码
错误码:
OS_ERR_NONE:设置成功
OSSchedRoundRobinYield()一个任务想放弃本次时间片,把CPU使用权让给同优先级下的另外一个任务执行
函数原型:
void OSSchedRoundRobinYield (OS_ERR *p_err)
*p_err:错误码
错误码:
OS_ERR_NONE:放弃时间片成功
OS_ERR_ROUND_ROBIN_1:该优先级只有一个任务
OS_ERR_ROUND_ROBIN_DISABLED:时间片轮转未使能
OS_ERR_SCHED_LOCKED:该任务已加锁
OS_ERR_YIELD_ISR:在中断中执行该功能