每个任务被赋予不同的优先级等级,从0 级到最低优先级OS_LOWEST_PR1O,包括0 和

OS_LOWEST_PR1O 在内。当μC/OS-Ⅱ初始化的时候,最低优先级OS_LOWEST_PR1O 总是被赋给空闲任务idle task 。注意,最多任务数目OS_MAX_TASKS 和最低优先级数是没有关系的。用户应用程序可以只有10 个任务,而仍然可以有32 个优先级的级别(如果用户将最低优先级数设为31 的话)。

每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量OSRedyGrp 和OSRdyTbl[]。在OSRdyGrp 中,任务按优先级分组,8 个任务为一组。OSRdyGrp 中的每一位表示8 组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl[] 中的相应元素的相应位也置位。就绪表OSRdyTbl[] 数组的大小取决于OS_LOWEST_PR1O。当用户的应用程序中任务数目比较少时,减少OS_LOWEST_PR1O 的值可以降低μC/OS-Ⅱ对RAM(数据空间)的需求量。

为确定下次该哪个优先级的任务运行了,内核调度器总是将OS_LOWEST_PR1O 在就绪表中相应字节的相应位置1。OSRdyGrp 和OSRdyTbl[] 之间的关系见图3.3,是按以下规则给出的:

当OSRdyTbl[0] 中的任何一位是1 时,OSRdyGrp 的第0 位置1,

当OSRdyTbl[1] 中的任何一位是1 时,OSRdyGrp 的第1 位置1,

当OSRdyTbl[2] 中的任何一位是1 时,OSRdyGrp 的第2 位置1,

当OSRdyTbl[3] 中的任何一位是1 时,OSRdyGrp 的第3 位置1,

当OSRdyTbl[4] 中的任何一位是1 时,OSRdyGrp 的第4 位置1,

当OSRdyTbl[5] 中的任何一位是1 时,OSRdyGrp 的第5 位置1,

当OSRdyTbl[6] 中的任何一位是1 时,OSRdyGrp 的第6 位置1,

当OSRdyTbl[7] 中的任何一位是1 时,OSRdyGrp 的第7 位置1,

用于将任务放入就绪表,Prio 是任务的优先级。

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

OSMapTbl[] 的值:

任务优先级的低三位用于确定任务在总就绪表OSRdyTbl[] 中的所在位。接下去的三位用于确定是在OSRdyTbl[] 数组的第几个元素。OSMapTbl[] 是在ROM 中的屏蔽字,用于限制OSRdyTbl[] 数组的元素下标在0 到7 之间,如果一个任务被删除了,则用 下面代码做求反处理。

if ((OSRdyTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0) 
OSRdyGrp &= ~OSMapTbl[prio >> 3]; 

以上代码将就绪任务表数组OSRdyTbl[] 中相应元素的相应位清零,而对于OSRdyGrp, 只有当被删除任务所在任务组中全组任务一个都没有进入就绪态时,才将相应位清零。也就是说OSRdyTbl[prio>>3] 所有的位都是零时,OSRdyGrp 的相应位才清零。为了找到那个进入就绪态的优先级最高的任务,并不需要从OSRdyTbl[0] 开始扫描整个就绪任务表,只需要查另外一张表,即优先级判定表OSUnMapTbl([256]) 。

OSRdyTbl[] 中每个字节的8 位代表这一组的8 个任务哪些进入就绪态了,低位的优先级高于高位。利用这个字节为下标来查OSUnMapTbl 这张表,返回的字节就是该组任务中就绪态任务中优先级最高的那个任务所在的位置。这个返回值在0 到7 之间。确定进入就绪态的优先级最高的任务是用以下代码完成的,

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

例如,如果OSRdyGrp 的值为二进制01101000,查OSUnMapTbl[OSRdyGrp] 得到的值是3, 它相应于OSRdyGrp 中的第3 位bit3,这里假设最右边的一位是第0 位bit0 。类似地,如果OSRdyTbl[3]的值是二进制11100100, 则OSUnMapTbl[OSRdyTbc[3]]的值是2,即第2 位。于是任务的优先级Prio 就等于26(3*8+2)。利用这个优先级的值。查任务控制块优先级表OSTCBPrioTbl[],得到指向相应任务的任务控制块OS_TCB 的工作就完成了。

INT8U  const  OSMapTbl[]   = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
INT8U  const  OSUnMapTbl[] = {
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F                             
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x10 to 0x1F                             
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x20 to 0x2F                             
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x30 to 0x3F                             
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x40 to 0x4F                           
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x50 to 0x5F                             
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x60 to 0x6F                             
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x70 to 0x7F                             
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x80 to 0x8F                             
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x90 to 0x9F                             
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xA0 to 0xAF                             
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xB0 to 0xBF                             
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xC0 to 0xCF                             
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xD0 to 0xDF                             
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xE0 to 0xEF                             
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        /* 0xF0 to 0xFF                             
}; 

作者:洞庭散人

出处:http://phinecos.cnblogs.com/    

本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。

uC/OS-II源码分析(五)的更多相关文章

  1. Vue系列---理解Vue.nextTick使用及源码分析(五)

    _ 阅读目录 一. 什么是Vue.nextTick()? 二. Vue.nextTick()方法的应用场景有哪些? 2.1 更改数据后,进行节点DOM操作. 2.2 在created生命周期中进行DO ...

  2. ABP源码分析五:ABP初始化全过程

    ABP在初始化阶段做了哪些操作,前面的四篇文章大致描述了一下. 为个更清楚的描述其脉络,做了张流程图以辅助说明.其中每一步都涉及很多细节,难以在一张图中全部表现出来.每一步的细节(会涉及到较多接口,类 ...

  3. MPTCP 源码分析(五) 接收端窗口值

    简述:      在TCP协议中影响数据发送的三个因素分别为:发送端窗口值.接收端窗口值和拥塞窗口值. 本文主要分析MPTCP中各个子路径对接收端窗口值rcv_wnd的处理.   接收端窗口值的初始化 ...

  4. vuex 源码分析(五) action 详解

    action类似于mutation,不同的是Action提交的是mutation,而不是直接变更状态,而且action里可以包含任意异步操作,每个mutation的参数1是一个对象,可以包含如下六个属 ...

  5. jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解

    $.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下: elems Array/Object类型 指定的需要处理的数组或 ...

  6. Vue.js 源码分析(五) 基础篇 方法 methods属性详解

    methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head&g ...

  7. java动态代理——代理方法的假设和验证及Proxy源码分析五

    前文地址 https://www.cnblogs.com/tera/p/13419025.html 本系列文章主要是博主在学习spring aop的过程中了解到其使用了java动态代理,本着究根问底的 ...

  8. motan源码分析五:cluster相关

    上一章我们分析了客户端调用服务端相关的源码,但是到了cluster里面的部分我们就没有分析了,本章将深入分析cluster和它的相关支持类. 1.clustersupport的创建过程,上一章的Ref ...

  9. MyBatis框架的使用及源码分析(五) DefaultSqlSessionFactory和DefaultSqlSession

    我们回顾<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用> 一文的示例 private static SqlSessionFactory getSessionF ...

  10. docker 源码分析 五(基于1.8.2版本),Docker容器的创建

    前面讲到了docker容器得镜像,镜像其实是docker容器的静态部分,而docker容器则是docker镜像的动态部分,即启动了一个进程来运行,本篇最要来分析一下怎样创建并运行一个容器. 创建一个容 ...

随机推荐

  1. c# emit 实现类的代理

    using System; using System.Linq; using System.Reflection; using System.Reflection.Emit; namespace Em ...

  2. PowerBuilder -- 条码打印

    # 使用ocx控件 使用微软的MSBCODE9.OCX,但是注册老不成功,需要安装office之后才能注册成功,不知道有没有好的处理方法?? # 使用字体 字体下载:http://download.c ...

  3. 最新精品 强势来袭 XP,32/64位Win7,32/64位Win10系统【电脑城版】

    随着Windows 10Build 10074 Insider Preview版发布,有理由相信,Win10离最终RTM阶段已经不远了.看来稍早前传闻的合作伙伴透露微软将在7月底正式发布Win10的消 ...

  4. activiti自己定义流程之Spring整合activiti-modeler实例(六):启动流程

    1.启动流程并分配任务是单个流程的正式開始,因此要使用到runtimeService接口.以及相关的启动流程的方法.我习惯于用流程定义的key启动,由于有多个版本号的流程定义时,用key启动默认会使用 ...

  5. Spring IOC源代码具体解释之容器依赖注入

    Spring IOC源代码具体解释之容器依赖注入 上一篇博客中介绍了IOC容器的初始化.通过源代码分析大致了解了IOC容器初始化的一些知识.先简单回想下上篇的内容 加载bean定义文件的过程.这个过程 ...

  6. NDK以及C语言基础语法(一)

    一.什么是NDK? Native Development Kit (本地开发工具包): NDK中提供了一系列的工具,帮助我们快速开发C/C++的动态库,并能自动将so文件和java文件一起打包成apk ...

  7. 【BZOJ1853/2393】[Scoi2010]幸运数字/Cirno的完美算数教室 DFS+容斥

    [BZOJ1853][Scoi2010]幸运数字 Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那 ...

  8. 使用T4模板技术

    1.右键->添加->新建项,选择“文本模板” 2.修改代码为: <#@ template debug="false" hostspecific="fal ...

  9. 【spring配置】——spring整合Quartz定时器

    第一种:为普通java类中的某个方法配置跑批任务 MethodInvokingJobDetailFactoryBean CronTriggerBean SchedulerFactoryBean 1.定 ...

  10. Ubuntu12.04如何修改窗口背景色为眼睛保护色来保护眼睛,强力推荐!!

    最近突然发现盯着屏幕看的久了,眼睛会非常的痛苦,因此想改变一下系统的窗口背景颜色.其实看代码主要是在Eclipse里面察看,因此一开始我就想改变Eclipse的文本编辑框的背景颜色,效果如下图所示. ...