找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4509|回复: 0
打印 上一主题 下一主题
收起左侧

uC/OS-III 任务就绪表学习记录

[复制链接]
跳转到指定楼层
楼主
ID:82083 发表于 2015-6-6 02:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
       

这段时间利用上下班的时间在看 《嵌入式实时操作系统uC/OS-III》这本书,里面有很多很有意思的思想。如今看到第九章,想将之前的一些心得记录下来,本想今晚从第三章开始写笔记,敲了一段文字之后,感觉像是抄书,觉得没有太大意义。时间长了,连笔记都不知道如何写。先来个简单点的开始吧。

uC/OS-III 的任务就绪表和uC/OS-II的就绪表差别很大,简单的了很多。
拿8位的单片机,64级优先级来说。
// 优先级表
unsigned char OSPrioTbl[8] = {0};



每个元素的每bit位对应的优先级如下,优先级数值越低表示优先级越高:

OSPrioTbl[0]->bit0~bit7  优先级 0 ~ 7
OSPrioTbl[1]->bit0~bit7  优先级 8 ~ 15
OSPrioTbl[2]->bit0~bit7  优先级 16 ~ 23
OSPrioTbl[3]->bit0~bit7  优先级 24 ~ 31  
OSPrioTbl[4]->bit0~bit7  优先级 32 ~ 39  
OSPrioTbl[5]->bit0~bit7  优先级 40 ~ 47  
OSPrioTbl[6]->bit0~bit7  优先级 48 ~ 55     
OSPrioTbl[7]->bit0~bit7  优先级 56 ~ 63

当某一优先级的任务就绪,对于的bit位就会被置1,例如 优先级 7 的任务就绪,那么
OSPrioTbl[0] 的第bit7位将会被置位。

查找最高优先级的流程如下(原理实际上是计算零的个数,零的个数恰好对于优先级数):

OS_PRIO OS_PrioGetHighest()
{
        char i = 0,  char prio = 0;


        // 一次性比较 8位 由于空闲任务的存在,所以这个循环最终都会跳出而数组不会越界访问。
        while( 0 == OSPrioTbl[i++])
        {
                prio += 8;
        }
        // 这个函数实际上是计算前导零,即计算该元素的前面有几个零,再与prio相加即得到最高优先级。
        prio += CPU_CntLeadZeros(OSPrioTbl[i-1]);
        return (prio);
}       


有些CPU支持CLZ指令(即计算签导零数量),那么就可以充分利用该指令加速计算过程。

实际上,如果是在32位的单片机下需要64级优先级,那么这个算法还可以再优化成如下:

unsigned  int  OSPrioTbl[2] = {0};

OS_PRIO OS_PrioGetHighest()
{
        char i = 0,  char prio = 0;


        if( 0 != OSPrioTbl[0])
                prio = CPU_CntLeadZeros(OSPrioTbl[0]);
        else
                prio = CPU_CntLeadZeros(OSPrioTbl[1]) + 32;
       
        return (prio);
}       

上述代码并不是 uC/OS-III  的实现,只是我自己为了方便理解写了具备相同功能的代码。
书籍上所述代码如下:

OS_PRIO OS_PrioGetHighest()
{
        CPU_DATA         *p_tbl;
        OS_PRIO                prio;
        prio = (OS_PRIO)0;
        p_tbl = &OSPrioTbl[0];
        while(*p_tbl == (CPU_DATA)0)
        {
                 prio += DEF_INT_CPU_NBR_BITS;  //  DEF_INT_CPU_NBR_BITS : CPU 位宽
                p_tbl ++;
         }
        prio += (OS_PRIO)CPU_CntLeadZeros(*p_tbl);
        return(prio);
}       



太晚------- 明晚继续----------







分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶1 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表