3566|1

15

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

uC/OS II学习《三》—uC/OS II内核完全解析之任务控制块的初始化 [复制链接]

好长时间没更新我的博客了,接着前两节的写,上次写到任务控制块的初始化。任务控制块是一个数据结构,当任务的CPU使用权被剥夺时,μC/OS-Ⅱ用它来保存该任务的状态。当任务重新得到CPU使用权时,任务控制块能确保任务从当时被中断的那一点丝毫不差地继续执行。OS­­_TCBs全部驻留在RAM中。

先看任务控制块的组织结构:

typedef struct os_tcb

{

    OS_STK        *OSTCBStkPtr; //指向当前任务栈顶的指针

 

#if OS_TASK_CREATE_EXT_EN //以下参数只有在任务控制块扩展标

                             //志 使能OS_TASK_CREATE_EXT_EN才有用

    void          *OSTCBExtPtr;

    OS_STK        *OSTCBStkBottom;

    INT32U         OSTCBStkSize;

    INT16U         OSTCBOpt;

    INT16U         OSTCBId;

#endif

 //下面两个变量用于任务控制块OS_TCBs的双重链接,该链表在时钟节拍函数OSTimeTick()中使用,用于刷新各

//个任务的任务延迟变量.OSTCBDly,每个任务的任务控制块OS_TCB在任务建立的时候被链接到链表

//中,在任务删除的时候从链表中被删除。双重连接的链表使得任一成员都能被快速插入或删除。

    struct os_tcb *OSTCBNext;

    struct os_tcb *OSTCBPrev;

 

#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_SEM_EN

    OS_EVENT      *OSTCBEventPtr;// OSTCBEventPtr是指向事件控制块的指针

#endif

 

#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN

    void          *OSTCBMsg;// OSTCBMsg是指向传给任务的消息的指针。

#endif

 

    INT16U        OSTCBDly;//当需要把任务延时若干时钟节拍时要用到这个变量

    INT8U          OSTCBStat;// 任务的状态字

    INT8U          OSTCBPrio;// 任务优先级

 // .OSTCBX, .OSTCBY, .OSTCBBitX .OSTCBBitY用于加速任务进入

//就绪态的过程或进入等待事件发生状态的过程(避免在运行中去计算这些

//值)。

    INT8U          OSTCBX;

    INT8U          OSTCBY;

    INT8U          OSTCBBitX;

    INT8U          OSTCBBitY;

 

#if OS_TASK_DEL_EN

    BOOLEAN        OSTCBDelReq;// .OSTCBDelReq是一个布尔量,用于表示

                           //该任务是否需要删除

#endif

} OS_TCB;

 

 

下面来看新建任务的TCB初始化,先说该函数的七个参数:

INT8U prio, ……………..任务优先级

 OS_STK *ptos, ……………..任务堆栈栈顶指针

OS_STK *pbos, ……………..任务堆栈栈低指针

INT16U id, ……………..任务ID号(以后扩展用)

 INT16U stk_size, ……………..任务任务堆栈长度

void *pext, ……………..任务扩展指针

INT16U opt…………….可选项

其中必不可少的是前两个参数,其他注释在程序里

INT8U OSTCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT16U stk_size, void *pext, INT16U opt)

{

    OS_TCB *ptcb;  //定义TCB变量

 

    OS_ENTER_CRITICAL(); //关中断

    ptcb = OSTCBFreeList; //从空闲TCB列表中取出一个TCBOSTCBFreeList

//指向的那个)

if (ptcb != (OS_TCB *)0) //检查上一步取到的TCB存不存在

{

        OSTCBFreeList = ptcb->OSTCBNext;//OSTCBFreeList指向下一个空

//TCB

        OS_EXIT_CRITICAL();//关中断

        ptcb->OSTCBStkPtr    = ptos;   //将传递进来的七个参数放入TCB

        ptcb->OSTCBPrio      = (INT8U)prio;

        ptcb->OSTCBStat      = OS_STAT_RDY; 

        ptcb->OSTCBDly       = 0;   

 

#if OS_TASK_CREATE_EXT_EN    //其中有五个参数用于任务扩展

        ptcb->OSTCBExtPtr    = pext;          

        ptcb->OSTCBStkSize   = stk_size;    

        ptcb->OSTCBStkBottom = pbos; 

        ptcb->OSTCBOpt       = opt;       

        ptcb->OSTCBId        = id; 

#else   // 如果OS_TASK_CREATE_EXT_EN=0,执行下面为了防止编译器警告

        pext                 = pext;    

        stk_size             = stk_size;

        pbos                 = pbos;

        opt                  = opt;

        id                   = id;

#endif

 

#if OS_TASK_DEL_EN //如果任务删除功能使能,对相应变量赋值,此语句可视//为为无关代码

        ptcb->OSTCBDelReq    = OS_NO_ERR;

#endif

 

//下面四个变量是用于加速任务进入就绪态的过程或进入等待事件发生状态的

//过程(避免在运行中去计算这些值)。这些值是在任务建立时算好的,或者是在//改变任务优先级时算出的

ptcb->OSTCBY         = prio >> 3;

        ptcb->OSTCBBitY      = OSMapTbl[ptcb->OSTCBY];

        ptcb->OSTCBX         = prio & 0x07;

        ptcb->OSTCBBitX      = OSMapTbl[ptcb->OSTCBX];

//下面这几句也不是必须的,涉及到任务间的通讯,先不管

#if     OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_SEM_EN

        ptcb->OSTCBEventPtr  = (OS_EVENT *)0;   

#endif

 

#if     OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2))

        ptcb->OSTCBMsg       = (void *)0;  

#endif

 

        OS_ENTER_CRITICAL(); //关中断

        OSTCBPrioTbl[prio]   = ptcb; //将新建的TCB放到TCB优先级表中

//下面语句是将新建的任务TCB放到已建立的任务TCB链表中

        ptcb->OSTCBNext      = OSTCBList;   

        ptcb->OSTCBPrev      = (OS_TCB *)0;

        if (OSTCBList != (OS_TCB *)0) {

            OSTCBList->OSTCBPrev = ptcb;

        }

        OSTCBList               = ptcb;

//下面两句是将就绪表中相应位置位,表示该新建任务进入就绪状态

        OSRdyGrp               |= ptcb->OSTCBBitY;    

        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;

        OS_EXIT_CRITICAL();

        return (OS_NO_ERR);

    } else {

        OS_EXIT_CRITICAL();

        return (OS_NO_MORE_TCB);

    }

}

    这样加上上面一篇文章,uC/OS II的空闲任务算是建立起来,总结一下任务的建立主要做两件事情:一是任务堆栈的初始化,二是任务控制块(TCB)的初始化。

这样《一》《二》《三》加起来就把uC/OS II的系统初始化完成了,下面就要说说系统的心率——时钟节拍了……下章再写。

最新回复

谢谢分享  :)  详情 回复 发表于 2010-6-24 08:22
点赞 关注

回复
举报

2万

帖子

74

TA的资源

管理员

沙发
 

回复 楼主 416561760 的帖子

谢谢分享  :)
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表