uC/OS-II源码分析(五)

简介:

每个任务被赋予不同的优先级等级,从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。
目录
相关文章
|
Web App开发 调度 消息中间件
|
Web App开发 消息中间件 存储
|
Web App开发 调度 消息中间件
|
Web App开发 调度 消息中间件
|
消息中间件 Web App开发 存储
|
2月前
|
Web App开发 缓存 Rust
|
2月前
|
Ubuntu Unix Linux
操作系统的最强入门科普(Unix/Linux篇)
下期文章,小枣君会重点聊聊Windows和macOS那条线。敬请关注! 如果大家觉得文章不错,还请帮忙多多转发!谢谢!
|
11月前
|
安全 Linux 数据安全/隐私保护
Vanilla OS:下一代安全 Linux 发行版
【10月更文挑战第30天】
464 0
Vanilla OS:下一代安全 Linux 发行版
|
8月前
|
运维 自然语言处理 Ubuntu
OS Copilot-操作系统智能助手-Linux新手小白的福音
OS Copilot 是阿里云推出的一款操作系统智能助手,专为Linux新手设计,支持自然语言问答、辅助命令执行和系统运维调优等功能。通过简单的命令行操作,用户可以快速获取所需信息并执行任务,极大提升了Linux系统的使用效率。安装步骤简单,只需在阿里云服务器上运行几条命令即可完成部署。使用过程中,OS Copilot不仅能帮助查找命令,还能处理文件和复杂场景,显著节省了查找资料的时间。体验中发现,部分输出格式和偶尔出现的英文提示有待优化,但整体非常实用,特别适合Linux初学者。
390 10

热门文章

最新文章

  • 1
    【独家揭秘2025】VMware Workstation Pro虚拟机:免费安装教程大放送,一键解锁操作系统模拟神器!
    500
  • 2
    【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
    285
  • 3
    追踪隐式资源,巧解内存难题!阿里云操作系统控制台上线
    160
  • 4
    云产品评测|操作系统智能助手OS Copilot新功能获奖名单公布!
    231
  • 5
    Harmony OS开发-ArkTS三
    345
  • 6
    docker快速部署OS web中间件 数据库 编程应用
    211
  • 7
    【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
    324
  • 8
    操作系统控制台体验测评
    336
  • 9
    【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
    359
  • 10
    【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
    367
  • 推荐镜像

    更多