找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5793|回复: 0
收起左侧

任务控制块TCB

[复制链接]
ID:82781 发表于 2015-6-13 16:44 | 显示全部楼层 |阅读模式
  对于TCB控制块我的理解是:

任务控制块是记录任务的优先级,状态,堆栈指针等参数的一个链表,这个链表分为两部分,一个叫做空闲链表,一个叫做当前任务链表,空闲链表是人物创建的时候去申请,得到后设置参数,设置完了就把这个链表加载到当前链表中,下面看看任务建立的时候是怎么做的!!
     、、部分代码,不相关的略去
        psp = (void DT_XDATA *)OSTaskStkInit(task, ppdata, ptos, 0); /* Initialize the task's stack            
        err = OSTCBInit(prio, psp, (void DT_XDATA *)0, 0, 0, (void DT_XDATA *)0, 0);  
第一个是用来获得任务堆栈的基地址,任务堆栈这个东西,在开始的时候就建好了,其实就是个大数组,每个任务都有一个,当任务切换时这个数组用来存CPU相关的寄存器,比如累加器和8个寄存器,返回指针,任务的切换说白了就是人为的模仿了一次软件中断,
第二个用来获取任务的TCB控制块,并加载到当前任务控制块列表,
主要看第二个函数,第一个就是对堆栈的一个分配,决定那个字节些什么,初始化,关键是第二个TCB的创建
程序如下:

OS_TCB DT_XDATA * ptcb;//定义一个TCB的结构指针

    OS_ENTER_CRITICAL();//进入临界代码区
/* Get a free TCB from the free TCB list    */
    ptcb = OSTCBFreeList; //获取一个空的TCB块给PTCB
                     
      //判断TCB是否用完?用完了返回错误70            
    if (ptcb != (OS_TCB DT_XDATA *)0) {
        OSTCBFreeList        = ptcb->OSTCBNext;            /* Update pointer to free TCB list          */
        OS_EXIT_CRITICAL();//开中断

        ptcb->OSTCBStkPtr    = ptos;//任务堆栈指针写入                      /* Load Stack pointer in TCB                */
        ptcb->OSTCBPrio      = (INT8U)prio;  //任务优先级              /* Load task priority into TCB              */
        ptcb->OSTCBStat      = OS_STAT_RDY;//任务状态这个表示准备好了                /* Task is ready to run                     */
        ptcb->OSTCBDly       = 0;          //任务延时                /* Task is not delayed                      */


  /* Pre-compute X, Y, BitX and BitY          */
    //把优先级分解,计算出在就绪表中的位置
        ptcb->OSTCBY         = prio >> 3;                  
        ptcb->OSTCBBitY      = OSMapTbl[ptcb->OSTCBY];
        ptcb->OSTCBX         = prio & 0x07;
        ptcb->OSTCBBitX      = OSMapTbl[ptcb->OSTCBX];


        OS_ENTER_CRITICAL();
  /* OSTCBPrioTbl */
        OSTCBPrioTbl[prio]   = ptcb;  //写入OSTCBPrioTbl数组中对应的优先级的TCB指针地址

  /* Link into TCB chain. insert to the first of chain                     */
        ptcb->OSTCBNext      = OSTCBList;  //装载下一个链表地址               
        ptcb->OSTCBPrev      = (OS_TCB DT_XDATA *)0; //装载先前指针
  //如果 OSTCBList不为0 那么上一个指针就是当前的ptcb
        if (OSTCBList != (OS_TCB DT_XDATA *)0) {
            OSTCBList->OSTCBPrev = ptcb;
        }
        OSTCBList               = ptcb;


  //优先级写入就绪表
        OSRdyGrp               |= ptcb->OSTCBBitY;         /* Make task ready to run                   */
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        OS_EXIT_CRITICAL();
        return (OS_NO_ERR);


这里面的就是TCB的创建!大体上分为以下几个部分:
1,申请空链表
2.对申请到的空链表进行初始化,
3加载空链表到当前链表
4释放下一个链表的位置,


这里又有4个结构指针是核心分别是
OS_TCB DT_XDATA * ptcb
OS_EXT  OS_TCB DT_XDATA * DT_XDATA OSTCBFreeList;
OS_EXT  OS_TCB DT_XDATA * DT_XDATA OSTCBList;  
OS_EXT  OS_TCB DT_XDATA * DT_XDATA OSTCBPrioTbl[OS_LOWEST_PRIO + 1];
第一个是中间指针变量,第二个是空链表,第三个是当前TCB表,第四个是对应优先级的TCB表位置
对他们的操作如下:
第一歩:
       ptcb = OSTCBFreeList;
表示把指向空闲链表指针的地址给PTCB这个中间人
第二部:
       ptcb->OSTCBStkPtr    = ptos;//任务堆栈指针写入                      /* Load Stack pointer in TCB                */
        ptcb->OSTCBPrio      = (INT8U)prio;  //任务优先级              /* Load task priority into TCB              */
        ptcb->OSTCBStat      = OS_STAT_RDY;//任务状态这个表示准备好了                /* Task is ready to run                     */
        ptcb->OSTCBDly       = 0;

表示对空闲链表初始化操作
第三部:
OSTCBPrioTbl[prio]   = ptcb;
表示把申请到的当前TCB控制块的地址放到优先级里这样使得优先级和对应的TCB对应起来,比如优先级是20,那么他就在20那个结构数组里
存入优先级为20的任务TCB控制块,
第四部:
        ptcb->OSTCBNext      = OSTCBList;            
        ptcb->OSTCBPrev      = (OS_TCB DT_XDATA *)0;

          if (OSTCBList != (OS_TCB DT_XDATA *)0) {
            OSTCBList->OSTCBPrev = ptcb;
        }
        OSTCBList               = ptcb;

这一步表示下一个链表的地址是OSTCBList当前地址
并且吧当前申请到的TCB表写回到当前链表中,这是个加载,而上一个是释放
最后加载到入任务就绪表中就OK乐!!!!



回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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