本文在uCOS II上增加时间片任务调度的的原理:

对设置为同优先级的任务使用时间片调度,不同优先级任务仍然使用uCOS II的优先级调度策略。在同优先级任务的时间片调度中,所有任务暂时时间片长度固定,时间片的调度使用FIFO(先进先出)队列。

整体的描述参看下图。

上图中假设有3个优先级为5的任务,3个优先级为8的任务。纵向,第一列的OS_TCB形成OSTCBList双向链表(通过OSTCBNext和OSTCBPrev指针,这是原uCOS II系统已经有的部分)。横向,通过OSPSPrev和OSPSNext指针形成时间片链表(实际上是FIFO),这部分是我们在uCOS II上要增加的内容。第一列的任务每当有任务时间片用完后将挪到队列尾,从FIFO中选择下一个任务,这就是本文的时间片调度的过程。总体上看来,不同优先级使用了uCOS II原有的优先级调度策略,相同优先级之间增加了时间片调度策略,因此本文称为“优先级+时间片”联合调度。

下面我们列出实现时间片调度要修改的一些结构和函数,我们可以通过调试跟踪了解uCOS II的机理,从而理解为什么要这么做。

1 修改结构体OS_TCB(ucos_ii.h文件中)

增加4个成员变量用于时间片调度。

struct os_tcb {
... /* 增加下面4个成员 */
struct os_tcb *OSPSNext; /* 同一优先级下,每个任务的后向指针 */
struct os_tcb *OSPSPrev; /* 同一优先级下,每个任务的前向指针 */
INT8U OSPSLen; /* 该任务分配的时间片 */
INT8U OSPSCurLen; /* 该任务当前剩下的时间片 */
} OS_TCB;

2 修改OS_TCBInit任务结构体初始化函数(os_core.c文件)

在OS_TCBInit中增加时间片长度的初始化,我们可以先在os_cfg_r.h中宏定义一个时间片长度用于不同情况下的配置,

#define TIME_SLICE_LEN            10

OS_TCBInit函数中增加结构体成员初始化

ptcb->OSPSLen = TIME_SLICE_LEN;
ptcb->OSPSCurLen = TIME_SLICE_LEN;
ptcb->OSPSNext = (OS_TCB*)0;
ptcb->OSPSPrev = (OS_TCB*)0;

当出现同优先级的情况时,任务控制块插入到时间片链表中而不是优先级链表中,OS_TCBInit函数中要增加将任务插入到时间片链表的过程,我写的一个示例如下:

if (ptcb != (OS_TCB *)0) {
... OSTCBPrioTbl[prio] = ptcb;
if (OSTCBList != (OS_TCB *) 0) { /* 不存在同优先级任务, 按照uCOS ii方法链接到OSTCBList */
ptcb->OSTCBNext = OSTCBList; /* Link into TCB chain */
ptcb->OSTCBPrev = (OS_TCB *)0;
if (OSTCBList != (OS_TCB *)0) {
OSTCBList->OSTCBPrev = ptcb;
}
OSTCBList = ptcb;
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
} else { /* 出现同优先级情况,链接到时间片链表 */
while(ptcb1->OSPSNext!=(OS_TCB*) 0)
{
ptcb1=ptcb1->OSPSNext; /* move to the rear of time slice list */
}
ptcb1->OSPSNext = ptcb;
ptcb->OSPSPrev = ptcb1;
ptcb->OSPSNext=(OS_TCB*) 0; ptcb->OSTCBNext = (OS_TCB *)0;
ptcb->OSTCBPrev = (OS_TCB *)0;
} OSTaskCtr++; /* Increment the #tasks counter */
OS_EXIT_CRITICAL();
return (OS_ERR_NONE);
}

3 修改时钟中断函数OSTimeTick(os_core.c文件)

增加时间片调度的内容,这是时间片调度的主要部分。给出一个示例:

OSTimeTick (void)
{
...
OS_TCB *ptcb1; if (OSRunning == TRUE)
{
ptcb = OSTCBList; /* Point at first TCB in TCB list */
while (ptcb->OSTCBPrio != OS_IDLE_PRIO)
{ /* Go through all TCBs in TCB list */
OS_ENTER_CRITICAL (); /* delay time out */
... /* time slice count down */
if (ptcb->OSPSCurLen != 0) {
--ptcb->OSPSCurLen;
} else { /* time slice out */
/* reload time slice */
ptcb->OSPSCurLen = ptcb->OSPSLen; ptcb1 = ptcb->OSPSNext;
if (ptcb1 != (OS_TCB*) 0) { /* there are some tasks with the same priority */
/* (1) link new to priority-level list */
ptcb1->OSTCBNext = ptcb->OSTCBNext;
ptcb1->OSTCBPrev = ptcb->OSTCBPrev;
if (ptcb->OSTCBNext != (OS_TCB *)0) {
ptcb->OSTCBNext->OSTCBPrev = ptcb1;
}
if (ptcb->OSTCBPrev != (OS_TCB *)0) {
ptcb->OSTCBPrev->OSTCBNext = ptcb1;
}
ptcb->OSTCBPrev = (OS_TCB *)0;
ptcb->OSTCBNext = (OS_TCB *)0; /* (2) update OSTCBList if TCBcur is OSTCBList*/
if (ptcb == OSTCBList) {
OSTCBList = ptcb1;
} /* (3) Compute X, Y, BitX and BitY */
ptcb1->OSTCBY = ptcb1->OSTCBPrio >> 3;
ptcb1->OSTCBBitY = OSMapTbl[ptcb1->OSTCBY];
ptcb1->OSTCBX = ptcb1->OSTCBPrio & 0x07;
ptcb1->OSTCBBitX = OSMapTbl[ptcb1->OSTCBX]; /* (4) set task to be ready */
if (ptcb1->OSTCBDly == 0) {
OSRdyGrp |= OSMapTbl[ptcb1->OSTCBY];
OSRdyTbl[ptcb1->OSTCBY] |= OSMapTbl[ptcb1->OSTCBX];
} /* (5) move ptcb to the rear of queue */
while(ptcb1->OSPSNext!=(OS_TCB*) 0)
{
ptcb1=ptcb1->OSPSNext;
}
ptcb1->OSPSNext = ptcb;
ptcb->OSPSPrev = ptcb1;
ptcb->OSPSNext=(OS_TCB*) 0; /* (6) set OSTCBPrioTbl for Context switch */
OSTCBPrioTbl[ptcb1->OSTCBPrio]=ptcb1;
} else {
// do nothing
}
} /*
* (7) don't forgot that after time slice
* schedule, ptcb->OSTCBNext==NULL
*/
if (ptcb->OSTCBNext != (OS_TCB*)0) {
ptcb = ptcb->OSTCBNext;
} else if (ptcb1->OSTCBNext != (OS_TCB*)0) {
ptcb = ptcb1->OSTCBNext;
} else {
break;
} OS_EXIT_CRITICAL ();
}
}
}

OK,修改好上面的内容就大致实现了在uCOS II上增加时间片调度的过程,通过修改时间片长度TIME_SLICE_LEN可以验证时间片长度对任务调度的影响。本文
最后在硬件平台STM32F103RB上测试通过,但因为时间片的引入而且未对程序做相关优化,因此时间片调度的实时性提高上还有待完善。

修改uCOS_II以实现“优先级+时间片”联合调度的更多相关文章

  1. Android中通过进程注入技术修改广播接收器的优先级

    前言 这个周末又没有吊事,在家研究了如何通过进程的注入技术修改广播接收器的优先级,关于这个应用场景是很多的,而且也很重要,所以就很急的去fixed了. Android中的四大组件中有一个广播:Broa ...

  2. RT-Thread相同优先级线程的调度

    /* 静态线程的 线程堆栈*/ ]; ]; /* 静态线程的 线程控制块 */ static struct rt_thread thread_test1; static struct rt_threa ...

  3. Win10:如何修改双网卡的优先级?

    很多使用双网卡的IT之家网友可能遇到一种情况,比如笔记本电脑在插上网线后还是用WiFi,得手动关闭无线连接才能转换到有线连接.如何才能调整合适的网络优先级呢?一般来说,有两种方法比较常用. 一.调整网 ...

  4. 【数据库_Mysql】MySQL—修改表时给表添加联合主键约束

      添加语法如下: “ALTER TABLE table_name ADD CONSTRAINT pk_table_name PRIMARY KEY(列名1,列名2):” [示例1]假设订房信息表(O ...

  5. RTX——第8章 任务优先级修改

    以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 任务优先级设置注意事项RTX 操作系统任务优先级的设置要注意以下几个问题: 设置任务的优先级时,数值越 ...

  6. 10.深入k8s:调度的优先级及抢占机制源码分析

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 上一篇我们将了获取node成功的情况,如果是一个优先pod获取nod ...

  7. Windows核心编程 第七章 线程的调度、优先级和亲缘性(上)

    第7章 线程的调度.优先级和亲缘性 抢占式操作系统必须使用某种算法来确定哪些线程应该在何时调度和运行多长时间.本章将要介绍Microsoft Windows 98和Windows 2000使用的一些算 ...

  8. C#夯实基础之多线程三:线程的优先级

    一.为什么需要优先级--线程调度的问题 在现实生活中,优先级是一个很常见的现象:在火车站,如果你是孕妇,你是可以走进站中的专门绿色通道的,可以提前上火车以免拥挤:火警119匪警110出警的时候,都是人 ...

  9. Linux IO Scheduler(Linux IO 调度器)

    每个块设备或者块设备的分区,都对应有自身的请求队列(request_queue),而每个请求队列都可以选择一个I/O调度器来协调所递交的request.I/O调度器的基本目的是将请求按照它们对应在块设 ...

随机推荐

  1. FreeBSD系统更新与软件安装方法

    一.系统更新 freebsd-update fetch freebsd-update install 二.软件源更新(类似yum update.apt-get update) 1.取回源 portsn ...

  2. nginx介绍及安装

    nginx(Engine x)      静态的www软件    特点:        配置简单        高并发,1-2w,基于异步IO模型(epoll,kqueue)        占用资源少 ...

  3. Andriod中WebView加载登录界面获取Cookie信息并同步保存,使第二次不用登录也可查看个人信息。

    Android使用WebView加载登录的html界面,则通过登录成功获取Cookie并同步,可以是下一次不用登录也可以查看到个人信息,注:如果初始化加载登录,可通过缓存Cookie信息来验证是否要加 ...

  4. C#语法糖之第五篇: 泛型委托- Action<T>

    因为工作的原因(其实还是个人的惰性)昨天没有给大家分享文章,然后这几天也有很多园友也提出了他们报告的意见及指导,再次感谢这些兄弟们的照顾我 和支持,这个分类的文章我当时想的是把我的学习经验和工作中用到 ...

  5. Python编写相关注意事项

    1.# -*- coding: utf-8 -*-代码首部添加这个,不然会报Non_ASCII charater错误 python闭包:实际应用场景1.保持闭包运行完后的环境: 2.根据外部作用域的局 ...

  6. FXBlurView用法

    FXBlurView是UIView的子类,它实现毛玻璃效果的原理其实就是覆盖上一层FXBlurView的实例对象. - (void)viewDidLoad { [super viewDidLoad]; ...

  7. JavaScript DOM编程艺术第二版学习(1/4)

    接下来项目需要网页相关知识,故在大牛的指引下前来阅读本书. 记录方式:本书分四部分阅读,完成阅读之后会多写一篇包括思维导图的算是阅读指南的东西,浏览的童鞋看着指南可以跳过一些不必要的坑~ 当前水平:H ...

  8. Python:元组(tuple)

    #!/usr/bin/python3 #元组 tup1 = ('Google', 'Runoob', 1997, 2000) print(type(tup1)) print("tup1 &q ...

  9. java.net.ServerSocket和java.net.Socket

    个人博客地址:http://www.cnblogs.com/wdfwolf3/ java.net.ServerSocket 1.构造函数 a.ServerSocket() 创建一个无连接的server ...

  10. 【清橙A1094】【牛顿迭代法】牛顿迭代法求方程的根

    问题描述 给定三次函数f(x)=ax3+bx2+cx+d的4个系数a,b,c,d,以及一个数z,请用牛顿迭代法求出函数f(x)=0在z附近的根,并给出迭代所需要次数. 牛顿迭代法的原理如下(参考下图) ...