uC/OS-II是Jean J. Labrosse设计的完整的、可移植、可固化、可裁剪的抢占式实时多任务内核,绝大部分代码都是用标准的C语言编写的,开源、规模不大,比较适合初次接触嵌入式操作系统的人员学习和使用。2000年7月,uC/OS-II在一个航空项目中得到了美国联邦航空管理局(FAA)对用于商用飞机的、符合RTCA DO-178B标准的认证。

(一)在就绪表(Reday List)中作标记

每个任务的就绪标记都会被放入就绪表中,与就绪表相关的变量有两个,即OSRdyGrp和OSRdyTbl[]。

OSRdyGrp定位的是任务所在的行,OSRdyTbl[]定位的是任务所在的列。

OSRdyGrp的每一位都分别对应一个行(行号从0到7),OSRdyTbl[i]的每一位分别对应第i行的一个列(列号从0到7)。

1、OSRdyGrp

就绪任务所在的组,其定义位于UCOS_II.H,是一个8位无符号整型。OSRdyGrp哪个位为1就说明哪一行有就就绪的任务,源代码中的定义如下:

OS_EXT  INT8U        OSRdyGrp;                        /* Ready list group                              */

2、OSRdyTbl[]

就绪表,其定义位于UCOS_II.H,是一个一维数组。源代码中的定义如下:

#define  OS_RDY_TBL_SIZE   ((OS_LOWEST_PRIO) / 8 + 1)   /* Size of ready table                         */
OS_EXT  INT8U        OSRdyTbl[OS_RDY_TBL_SIZE];       /* Table of tasks which are ready to run         */

上面代码中的OS_LOWEST_PRIO的宏定义位于OS_CFG.H,对于uC/OS_II,该值最大为63。源代码中的定义如下:

#define OS_LOWEST_PRIO           60    /* Defines the lowest priority that can be assigned ...         *//* ... MUST NEVER be higher than 63!                            */

3、OSMapTbl[]

映射表,其定义位于OS_CORE.C,是一个一维数组,包含8个元素。源代码中的定义如下:

/*
*********************************************************************************************************
*                              MAPPING TABLE TO MAP BIT POSITION TO BIT MASK
*
* Note: Index into table is desired bit position, 0..7
*       Indexed value corresponds to bit mask
*********************************************************************************************************
*/INT8U const OSMapTbl[]   = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

以下代码用于将任务放入就绪表,prio为任务的优先级。

OSRdyGrp            |= OSMapTbl[prio >> 3];
OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];

举例:假如只有一个任务,该任务的优先级prio = 11 = 00 001 011,高三位为001,低三位为011,则

OSRdyGrp = OSMapTbl[prio >> 3] = OSMapTbl[1] = 0x02 = 0000 0010

OSRdyTbl[prio >> 3] = OSRdyTbl[1] = OSMapTbl[3] = 0x08 = 0000 1000

这样,向任务就绪表的第1行第3列写1,即完成了该任务的就绪标记写入。

(二)找出进入就绪状态的优先级最高的任务

4、OSUnMapTbl[]

优先级判定表,其定义位于OS_CORE.C,是一个一维数组,包含256个元素。源代码中的定义如下:

/*
*********************************************************************************************************
*                                       PRIORITY RESOLUTION TABLE
*
* Note: Index into table is bit pattern to resolve highest priority
*       Indexed value corresponds to highest priority bit position (i.e. 0..7)
*********************************************************************************************************
*/INT8U const OSUnMapTbl[] = {0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};

算法如下:

y    = OSUnMapTbl[OSRdyGrp];
x    = OSUnMapTbl[OSRdyTbl[y]];
prio = (y << 3) + x; 

举例:假设有3个任务,优先级分别为10、21、53

对于优先级为10的任务:

prio = 00 001 010

OSRdyGrp = OSMapTbl[prio >> 3] = OSMapTbl[1] = 0x02 = 0000 0010

OSRdyTbl[prio >> 3] = OSRdyTbl[1] = OSMapTbl[2] = 0x04 = 0000 0100

对于优先级为21的任务:

prio = 00 010 101

OSRdyGrp = OSMapTbl[prio >> 3] = OSMapTbl[2] = 0x04 = 0000 0100

OSRdyTbl[prio >> 3] = OSRdyTbl[2] = OSMapTbl[5] = 0x04 = 0010 0000

对于优先级为53的任务:

prio = 00 110 101

OSRdyGrp = OSMapTbl[prio >> 3] = OSMapTbl[6] = 0x40 = 0100 0000

OSRdyTbl[prio >> 3] = OSRdyTbl[6] = OSMapTbl[5] = 0x04 = 0010 0000

最后OSRdyGrp的值就是将所有的OSMapTbl[prio>>3]进行按位或运算:

OSRdyGrp = 0000 0010 | 0000 0100 | 0100 0000 = 0100 0110 = 70

同理,OSRdyTbl[1] = 0000 0100,OSRdyTbl[2] = 0010 0000,OSRdyTbl[6] = 0010 0000

然后,根据优先级判定表OSUnMapTbl[],可以确定优先级最高的任务

OSRdyGrp = 70

y = OSUnMapTbl[OSRdyGrp] = OSUnMapTbl[70] = 1

x = OSUnMapTbl[OSRdyTbl[y]] = OSUnMapTbl[OSRdyTbl[1]] = OSUnMapTbl[4] = 2

prio = (y << 3) + x = 10,即处于就绪状态的优先级最高的任务是优先级为10的任务。

这样做的好处其实就是以空间来换取时间,提高程序执行的效率。如果我们自己设计,首先想到的算法可能就是定义一个一维数组OSRdy[],包含64个元素,对应64个任务,当某个任务处于就绪状态时,就将相应的元素置1,比如优先级53的任务就绪,那么就令OSRdy[53] = 1,这样一来,通过查找法可以找到位于就绪状态的优先级最高的任务,其弊端就是当处于就绪状态的优先级最高的任务比较靠后时(比如优先级为63),查找所消耗的时间较多,效率相对较低,而uC/OS-II中采用的算法只用几行代码就可以快速找到优先级最高的任务,且对不同的任务所消耗的时间基本一致、相对公平。

uC/OS-II任务调度之就绪表及最高优先级任务判定算法相关推荐

  1. UART0串口编程(四):UART0串口编程之在UC/OS—II中遭遇的危机

    UART0串口编程之在UC/OS-II中遭遇的危机 一.潜在的危机 1.在uc/os操作系统中设计串口编程时,由于ISR和多个任务并发执行,情况比较复杂.尤其是接收状态为被动状态时,只能靠串行口中断来 ...

  2. Lab 6:uC/OS II

    为什么80%的码农都做不了架构师?>>>    目标: 移植uC/OS II到RPi上,实现两个任务的调度.这两个任务能轮流点亮LED,并通过串口发送消息表明自己正在运行 具体步骤: ...

  3. uc/OS II——多任务设计

    uc/OS II--多任务设计 (1)设计 开始任务 [1]/声明 开始任务 任务块 static OS_STK App_TaskStartStk[APP_TASK_START_STK_SIZE]; ...

  4. uC/OS 的任务调度解析

    1.任务调度器启动之后(初始化,主要是TCB的初始化),就可以创建任务,开始任务调度了,实际上第一个任务准确的说不是进行任务切换,而是进行启动当前最高优先级任务.uC/OS使用的是OSStartHig ...

  5. UC/OS II 任务管理(4)之任务创建

    任务的创建函数 ucosii之前的版本都只支持64个任务,但是V2.90版本支持的任务数量达到了256. 用法和原理都差不多.我这里就只介绍任务数不大于64的情况.当任务大于64的时候,只需要配置相关 ...

  6. 【 uC/OS II 】uC/OS II 源代码阅读(os_task.c)任务管理

    前言 这个任务管理源代码,是整个系统最核心的部分,也是最难的部分,多看几遍吧.其中的核心结构体是: typedef struct os_tcb {OS_STK *OSTCBStkPtr; /* Poi ...

  7. linux串口互斥,UART0串口编程之在UC/OS—II中遭遇的危机

    一.潜在的危机 1.在uc/os操作系统中设计串口编程时,由于ISR和多个任务并发执行,情况比较复杂.尤其是接收状态为被动状态时,只能靠串行口中断来接收数据. 2.在进行串行通信时,双方遵循相同的通信 ...

  8. uc os ii与linux,uC/OS-II嵌入式实时操作系统的几大特点

    uC/OS-II嵌入式实时操作系统的几大特点 出处:网络 发布于:2018-09-12 14:46:03 uC/OS-II的特点 1.uC/OS-II是由Labrosse先生编写的一个开放式内核,主要 ...

  9. 【 uC/OS II 】uC/OS II 源代码阅读(os_mbox.c)消息邮箱

    前言 关于消息邮箱,是一个消息邮箱里面,只能存储一条消息.核心结构体如下: #if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u) typedef s ...

最新文章

  1. (转载)Linux下pthread_once()函数
  2. “赋值”与“初始化”
  3. python学习-注释、语法、整数、浮点数初步接触
  4. html5 拖拽上传文件时,屏蔽浏览器默认打开文件
  5. bmon:一个强大的网络带宽监视和调试工具
  6. 计算机怎么远程桌面,电脑远程桌面如何连接 电脑远程桌面连接方法【详解】...
  7. linux创建更改目录,Linux中目录的创建与删除命令使用说明
  8. Qt实现表格内进度条展示数据
  9. loss曲线 pytorch_PyTorch应用:用ResNet进行交通标志分类
  10. 逻辑门的Verilog实现与仿真
  11. 【服务器】【个人网盘】宝塔安装NextCloud
  12. 湖北省地税应用灾备中心正式启用
  13. 服务器运算性能,服务器性能计算公式(20191116215459).pdf
  14. mysql存储多少_MySQL存储引擎你们知道多少?
  15. NPAPI插件开发记录(一)----- .rc文件 支持Chrome和FireFox
  16. 【laravel】切换语言包 中文,英文
  17. 更改浏览器语言(firefox, chrome)详细步骤
  18. 人体反应测试仪 c语言,有趣的人体反应速度测试电路
  19. win7计算机窗口左边被改了,win7电脑开始菜单变成经典模式?三种方法教你改回来...
  20. java模板方法模式_Java设计模式之模板方法模式

热门文章

  1. 电商平台满减活动需求分析
  2. 【转载】CSDI2018广州关于《Nginx》的分享(附文字速录与PPT)
  3. Gym - 101492 F. Hitting the target(几何)
  4. 新计算机是飞行模式怎么开,win10自己打开飞行模式,怎么处理
  5. PMU配置(RK808)
  6. 艾司博讯:拼多多一件代发操作步骤
  7. 参考文献起止页码怎么写_期刊作为参考文献要求有年卷期和起止页码,怎么查这些页码什么的...
  8. 【社会实践】红旗渠:青年洞
  9. mysql查询周数_MySQL如何获取一个指定日期所对应本年度的周数(WEEK函数)呢?
  10. 捣鼓openwrt不死bootloader (1)