嵌入式学习小组
直播中

潘琳

8年用户 180经验值
私信 关注

采用μC/OS-II实现时间片调度法设计

引言

μC/OS-II嵌入式实时操作系统采用的是基于优先级的可剥夺调度法[1]。基于优先级的可剥夺调度法是指,CPU总是让处于就绪态的、优先级最高的任务运行;最高优先级的任务一旦就绪,总能得到CPU的使用权,当一个运行着的任务使一个比它优先级高的任务进入了就绪态时,当前任务的CPU使用权就被剥夺了,更高优先级的任务立刻得到了CPU的使用权。除非最高优先级的任务主动放弃CPU的使用权(通过调用OStimeDly()、OSSemPend()等函数),否则低优先级的任务是没机会获得CPU使用权的。对于一个实际应用系统中耗时比较长的任务,为了让其他任务能够得到实时调度,可以用两种方法来处理。第一种方法是把该任务的优先级设为最低(当然还是比空闲任务要高);第二种方法就是让该耗时任务运行一段时间后延时一下再继续运行,即把整个任务划分为若干步骤来执行,如以下的示例代码:








回帖(6)

李子崴

2019-7-24 14:42:25
很多情况下,耗时长的任务并不能设置为最低优先级任务,而划分步骤来执行的方法不但繁琐而且每一步执行的时间也是不确定的(其他低优先级任务获得CPU使用权的时间也会是不确定的)。笔者在用μC/OSII开发一款车载信息娱乐系统的时候就碰到了这样的问题,因此设计了一种优先级和时间片相结合的调度法(也就是基于μC/OSII的时间片调度法)。

1 调度原理

这种调度法给处于就绪态的每一个任务都分配一个时间片(优先级越高分配的时间片越长,空闲任务得不到时间片的分配),内核按照任务的优先级依次调度处于就绪态的任务,即当就绪态中最高优先级的任务用完自己的时间片后,CPU控制权转让给就绪态中优先级第二高的任务。该任务用完自己的时间片后,CPU控制权又转让给下一优先级的就绪态任务……当就绪态的每一个任务都被调度一次之后将重新为它们分配时间片,然后又开始新一轮的调度……[2]

其中要注意的是,在调度过程中如果有一个比当前任务优先级更高的任务由其他态变成了就绪态(被创建或获取了一个信号量等),当前任务的CPU控制权将被剥夺;空闲任务仍然是等到其他任务都退出就绪态才获得CPU的使用权。

图1解释了该调度法的调度过程(其中任务1优先级最高,任务2次之,任务3最低)。



图1 基于μC/OSII时间片调度过程
举报

李桂兰

2019-7-24 14:42:31
① 任务2和任务3都处于就绪态,任务1在等待一个信号量,优先级中的任务2获得CPU使用权。

② 任务2的时间片用完,优先级低的任务3获得CPU使用权。

③ 任务3的时间片用完,任务2重新获得CPU的使用权。

④ 任务2的时间片还没用完时中断来临,中断服务程序获得CPU使用权。

⑤ 中断服务程序发送了一个任务1等待的信号量,中断服务完成后优先级高的任务1获得CPU使用权。

⑥ 任务1的时间片用完,任务2继续运行。

⑦ 任务2的时间片用完,任务3获得CPU使用权。

⑧ 任务3的时间片用完,重新分配时间片,新一轮调度开始。
举报

李晨灵

2019-7-24 14:42:48
2 实现方法

在调度算法的实现过程中,力求做到3点:

① 尽可能少地改动μC/OSII原有的代码;

② 增加的代码在风格上保持与原有的相一致;

③ 兼容原有的优先级调度法(可以很方便地选择优先级调度法或是时间片调度法)。

注:对于该小节中出现的代码,如果是笔者增加的部分都用黑体表示。
举报

陈秀英

2019-7-24 14:42:55
2.1 数据结构中增加的变量

在进程控制块中增加两项:

Typedef struct os_tcb{

……

#if OS_TASK_TIME_SLICE_EN>0

/*条件编译,OS_TASK_TIME_SLICE_EN在os_cfg.h中定义,凡是涉及与时间片调度相关的代码都用条件编译。这样,可以通过更改配置文件很方便地选择任务调度法

*/INT16UOSTCBTimeSlice;

/*任务的时间片大小,在任务创建时被初始化,运行过程中保持不变*/

INT16UOSTCBCounter;

/*任务运行剩余时间计数器,每一轮调度开始时该变量被赋值(等于OSTCBTimeSlice),运行过程中不断递减。当其等于0时任务被剥夺CPU使用权*/

#endif

}

由于当前任务的时间片使用完时,该任务将被从就绪表OSRdyGrp以及OSRdyTbl[OS_RDY_TBL_SIZE]中清除;新一轮调度开始时它又必须被恢复,因此笔者在uCOS_II.h文件中增加以下变量(不妨把它们称为“时间片调度表”)分别用于保存OSRdyGrp和OSRdyTbl[OS_RDY_TBL_SIZE]。

OS_EXT INT8UOSTSSGrp;

OS_EXT INT8UOSTSSTbl[OS_RDY_TBL_SIZE];

另外,在uCOS_II.h文件中增加宏定义,用于表示任务时间片被用完这种状态:

#defineOS_STAT_TS_USEUP0x40
举报

更多回帖

发帖
×
20
完善资料,
赚取积分