首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

UCOS之任务调度机制(2)

UCOS之任务调度机制(2)

四. 就绪表(Ready List):
      uCOS II采用内存映射的方式来实现READY队列的加入,查找,删除功能,效率非常高。但是也因此只能支持64个任务,每个任务都有自己的优先级,不能和其他任务优先级相同。
  
      每个任务的就绪态标志都放入就绪表中的,就绪表中有两个变量OSRdyGrp和OSRdyTbl[]。(OSRdyGrp占用一个字节:8位,每位代表一个优先级组;OSRdyTbl[]占8个字节,共64位,每位代表一个优先级)在OSRdyGrp中,任务按优先级分组,8个任务为一组。OSRdyGrp中的每一位表示8组任务中每一组中是否有进入就绪态的任务。任务进入就绪态时,就绪表OSRdyTbl[]中的相应元素的相应位也置位。就绪表OSRdyTbl[]数组的大小取决于OS_LOWEST_PRIO(见文件OS_CFG.H)。
       为确定下次该哪个优先级的任务运行了,内核调度器总是将OS_LOWEST_PRIO在就绪表中相应字节的相应位置1。OSRdyGrp和OSRdyTbl[]的关系见图3.3,是按以下规则给出的: 当OSRdyTbl[0]中的任何一位是1时,OSRdyGrp的第0位置1,
      当OSRdyTbl[1]中的任何一位是1时,OSRdyGrp的第1位置1,
      当OSRdyTbl[2]中的任何一位是1时,OSRdyGrp的第2位置1,
      以些类推。。。。。
  任务就绪的掩码表:
       INT8U const OSMapTbl[]   = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};//定位优先级所用

  任务优先级的低三位用于确定任务在总就绪表OSRdyTbl[]中的所在位。接下去的[5:3]三位用于确定是在OSRdyTbl[] 数组的第几个元素。 OSMapTbl[]是在ROM中的(见文件OS_CORE.C)屏蔽字,用于限制OSRdyTbl[]数组的元素下标在0到7之间,见表3.1
  
                
IndexBit Mask (Binary)
000000001
100000010
200000100
300001000
400010000
500100000
601000000
710000000

     
   程序清单3.5中的代码用于将任务放入就绪表。Prio是任务的优先级。

程序清单 L3.5 使任务进入就绪态 (这两行代码简直是神来之笔啊!!!)
  
这行代码功能是找到组, 把组上的值置为1
不妨假设prio的值为13, 即优先级为13. prio>>3 右移3位后值为1, 可以查表T3.1找出 OSMapTbl[1] 的值为 0000 0010. 再用 0000 0010 和 OSRdyGrp 进行异或运算:
OSRdyGrp |= OSMapTbl[prio >> 3];   //先根据高3位[5:3]找到所在的组
OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07]; //再由低3位把该组的具体某一位置1

  如果一个任务被删除了,则用程序清单3.6中的代码做求反处理。
  程序清单 L3.6 从就绪表中删除一个任务
  
  
if ((OSRdyTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0)         OSRdyGrp &= ~OSMapTbl[prio >> 3];
继承事业,薪火相传
返回列表