【嵌入式】uC/OS-II学习笔记——OSUnMapTbl、OSRdyGrp、OSRdyTbl用法解读

关于这三个系统变量,研究了好一阵子,也在网上查了不少资料,感觉挺乱的,就按自己的理解写得详细一点。

希望能让人只看一篇博文就能搞懂这个是怎么用的。

首先给出这三个变量的定义:


INT8U const OSUnMapTbl[256] = {
    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                             */
};

INT8U OSRdyGrp;
INT8U OSRdyTbl[8];



他们3个用的都是INT8U的变量,也就是无符号的8bit变量。

那么现在来一个个解释它们代表的意思:

OSRdyGrp,它将64个优先级分为8组,恰好就是与这个变量的8bit一一对应;


举个例子,假设OSRdyGrp = 00000100B 那么就可以说明第2组存在一个就绪任务,也就是说优先级为16~23中有一个或多个任务已就绪。



OSRdyTbl[8],就是对应的8个分组了;

继续刚刚的例子,在OSRdyGrp = 00000100B 的情况下,我们可以肯定OSRdyTbl[2] 中一定有一位或者多位为1

那么OSRdyTbl[2]的作用就是记录究竟哪一个优先级的任务已就绪,假设OSRdyTbl[2] = 10000001B ,那么我们就可以知道,应该是这一组第0和7的任务就绪了


最后就剩下 OSUnMapTbl[256],它其实就是用于查找为1的最低位,他是一个数组,而数组记录的数字是事先写好的,那么它有什么意义呢?

我们继续刚刚的例子,已知OSRdyGrp = 00000100B ,OSRdyTbl[2] = 10000001B ,现在有一段这样的查表代码


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

y = OSUnMapTbl[OSRdyGrp]; 将 00000100B 转换为十进制后是4,也就是 y = OSUnMapTbl[4] , 即 y = 2;其代表的含义就是 4 转换为二进制后为1的最低位在第二位。

这就告诉了我们,第二组是有就绪任务的组中的最高优先级的组

然后x = OSUnMapTbl[OSRdyTbl[y]]; , x = OSUnMapTbl[OSRdyTbl[3]], 即 x = OSUnMapTbl[10000001B] ----> x = OSUmMapTbl[129] -----> x = 0

这又告诉了我们,第二组中,就绪的最高优先级任务是第二组的第0个任务

prio = y << 3 + x 就是 y * 8 + x, 就是我们想要找的所有任务中已就绪的最高优先级任务


其实归根结底这是一种典型的用空间换取时间的方法,在设置就绪任务时设置一个标记,就能以O(1)的时间查找出已就绪的最高优先级任务,这个方法在这个系统里其他地方还有应用,以切合系统的实时性。



  • 15
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
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有限,移植并未考虑中断重入的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值