uC/OS-II学习笔记(2012.12.11)任务就绪表之如何理解OSUnMapTbl[]

uC/OS-II学习笔记(2012.12.11)任务就绪表之如何理解OSUnMapTbl[]



1).OSUnMapTbl[]表,就绪表找出优先级最高的任务:

 y = OSUnMapTbl[OSRdyGrp ];

x = OSUnMapTbl[ OSRdyTbl[y] ];

 Prio = y<<3+x;

 

我们知道,在查找最高级就绪任务时,如果使用编写一个循环程序在就绪表中进行查找的方法。有2个缺点:一是耗时,二是运算时间不可预测--这可是犯了实时系统的大忌.赫赫。

所以Jean J.Labrosse 在设计的时候设置了这样一个数组,在查找最高级就绪任务时,只要以变量OSRdyGrp为下标,就可直接在数组OSUnMapTbl[]得到就绪任务的y值了;

这里,OSUnMapTbl[]是uC/OS-II为提高查找速度定义的一个数组,它共有256个元素(256这么来的:以变量OSRdyGrp为数组的下标,而OSRdyGrp是个8位二进制数,值域是2^8=256),其定义如下

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

};

由于在使用数组OSUnMapTbl[]时是以OSRdyGrp为下标的因此这个数组一共有256个元素。也就是说,无论OSRdyGrp是多少,在数组OSUnMapTbl[]中总能找到对应的元素值,而且这个元素值就是最高级就绪任务优先级别的y。因为数组OSUnMapTbl[]各个元素的值是基于这样一个思想来设置的:表示任务组的变量OSRdyGrp是一个8位二进制数,从这个数的最低位向高位查找,碰到的第一个为1的位所对应的就绪任务足一定是最高优先级别任务所在的组,所以它的组号一定是最高优先级别就绪任务的级别(6位数)的高3位。例如:OSRdyGrp中第一个为1的位为D3,那么最高优先级别就绪任务级别的高3位一定为011(十进制的3),于是在数组OSUnMapTbl[]德256个元素中,凡是其下标的D3位1,且D2,D1,D0都为0的元素值均定义为3。


同样,这个数组也用来查找最高级就绪任务的x值。当然,这时是以OSRdyTbl[y]为下标来进行查找的。


2).那我们看看这个OSUnMapTbl[] 表是如何建立起来的

假设 OSRdyGrp=0x68 , 即二进制: 01101000

 根据低位优先级高,可知OSRdyGrp 中bit3 优先级最高。在OSRdyTbl[3] 中查找,如果OSRdyTbl[3]=0xE4 ,即二进制 1110 0100 ,可知 bit2 优先级最高。 于是乎Prio = 3<<3+2=26

 当OSRdyGrp= =0bxxxx xxx1 时,最高优先级在OSRdyTbl[0]中 ,即OSUnMapTbl[OSRdyGrp] = 0

同理

当OSRdyGrp= =0bxxxx xx10 时,最高优先级在OSRdyTbl[1]中 ,即OSUnMapTbl[OSRdyGrp] = 1  , 以此类推


接下来我们画一个表格来总结一下

 

OSRdyGrp

OSUnMapTbl[OSRdyGrp]

 个数

0b xxxx xxx1

0

2^7

0b xxxx xx10

1

2^6

0b xxxx x100

2

2^5

0b xxxx 1000

3

2^4

0b xxx1 0000

4

2^3

0b xx10 0000

5

2^2

0b x100 0000

6

2^1

0b 1000 0000

7

2^0

 

个数总和为255个 ,另外加上无法计算的OSUnMapTbl [0 ]  ,一共256个。

 //下面是生成OSUnMapTbl[256]的代码  

#include<stdio.h>

voidmain(void)
{
    int i,t;
    int tab[256]={0};
    for(i=0;i<8;i++)
        for(t=1;(t<<i)<256;t++)       //算法有重复的部分
        {
            tab[t<<i]=i;
        }

}


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 由于ATmega16的RAM资源很少,所以在OS_CFG.H中关闭所有不必要的功能,同时优化代码,减少RAM占用 在os_core.c中,有两个数组: INT8U const OSMapTbl[8]与 INT8U const OSUnMapTbl[256],虽然声明为const类型,但是avr-gcc并不会将其放置在flash中,必须加以修改为INT8U const OSMapTbl[8] PROGMEM 与INT8U const OSUnMapTbl[256] PROGMEM ,同样的,该文件中访问这些数组的语句也必须做相应的修改。这样的结果是速度会受到影响,但是由于仍然是查表操作,任务切换的时间还是确定的。 2. 任务说明 系统中一共有5个用户任务:Task1-Task5,其优先级依次为1,2,3,5,4。每个用户任务的堆栈均为OS_USER_TASK_STK_SIZE(定义于os_cfg.h,目前为64字节)。 系统中建立有一个信号量T2sem与一个邮箱Tmbox。 Task1完成了Timer0的初始化,并打开了定时器中断,使得任务调度可以正常进行。此后,该任务只隔一个很短的时间使得变量t1增加,同时取反PORTB.1。 Task2初始化了Timer2,并使能了Timer2中断,然后任务挂起,等待信号量T2sem,如果等到且无错误,则使得变量t2增加。 Task3使得PD2上出现一个脉冲,以触发INT0,并使得变量t3增加。 Task4使得PD3上出现一个脉冲,以触发INT1,并使得变量t4增加。 Task5使得该任务挂起等待邮箱中有一条消息,如果取得消息,就将t5的值更新。 3. 中断系统 需要引用系统服务的中断,其底层部分被定义于AVRect.S中,中断的处理函数被定义于AVRisr.c中,例如例子中外部中断0与外部中断1的服务函数。 对于无需引用系统服务的中断函数,比如例子中的Timer2比较匹配中断,可以全部定义于AVRisr.c中。 Timer2的中断只是使得变量t6增加。 INT0的中断向任务发出信号量。 INT1的中断发送一个消息到信箱。 由于AVR的RAM有限,移植并未考虑中断重入的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值