uC/OS-ii内核理解(六)初始化TCB-OS_TCBInit函数

OS_TCBInit是创建任务函数OSTaskCreateExt时调用的一个函数。"OS_TCBInit"时与系统内核紧密相关的一个函数。

OS_TCBInit和OS_InitTCBList区别:OS_InitTCBList主要是初始化TCB链表。"OS_InitTCBList"函数体内容相当于将TCB链表复位。

OS_TCBInit是在创建任务时初始化一个任务的TCB,要将优先级、堆栈等信息初始化。"OS_TCBInit"函数体内容相当于对任务的TCB里面对应的内容落实到具体的参数上。

OS_TCBInit(void)函数位于os_core.c文件的第1917行。

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

1.第一个参数prio 任务的优先级。

这个参数是从"OSTaskCreateExt"函数参数中传递下来的。

2.第二个参数ptos 指向栈顶的指针。

创建任务中利用"OSTaskStkInit"初始化堆栈得到栈顶的指针psp,将该指针传递给OS_TCBInit函数的参数。

这个参数和pbos一样 根据栈的增长方向" OS_STK_GROWTH "来决定。

3.第三个参数pbos 指向栈底的指针

4.第四个参数id 任务ID号

5.第五个参数stk_size

堆栈大小,就是分配堆栈空间(定义堆栈数组)的大小。

6.第六个参数pext

pext指向用户提供的内存(指针)。

7.第七个参数opt

用户操作选项参数

"OS_TCBInit"函数的参数基本是继承"OSTaskCreateExt"函数的参数。从这里可以看出"OS_TCBInit"函数才是创建任务的重要函数。


OS_TCBInit函数体内容详解

OS_TCBInit的参数其实传递进来的参数保存在TCB链表中用于保存一个任务重要的信息,具体如下:

    OS_ENTER_CRITICAL(); //进临界区(关中断)
    ptcb = OSTCBFreeList;                                  /* Get a free TCB from the free TCB list获取空TCB指针*/
    if (ptcb != (OS_TCB *)0) { //如果缓冲区有空余TCB,这个TCB将被初始化
        OSTCBFreeList            = ptcb->OSTCBNext;        /* Update pointer to free TCB list更新空TCB列表指针(指向下一空TCB)*/
        OS_EXIT_CRITICAL(); //出临界区(开中断)
        ptcb->OSTCBStkPtr        = ptos;                   /* Load Stack pointer in TCB当前PTCB栈顶的指针(输入)*/
        ptcb->OSTCBPrio          = prio;                   /* Load task priority into TCB往TCB装入任务优先级(输入)*/
        ptcb->OSTCBStat          = OS_STAT_RDY;            /* Task is ready to run任务准备好运行(就绪态)*/
        ptcb->OSTCBStatPend      = OS_STAT_PEND_OK;        /* Clear pend status 清除PEND状态*/
        ptcb->OSTCBDly           = 0u;                     /* Task is not delayed任务不延时*/


#if OS_TASK_CREATE_EXT_EN > 0u //若创建任务扩展功能
        ptcb->OSTCBExtPtr        = pext;                   /* Store pointer to TCB extension存储TCB扩展指针*/
        ptcb->OSTCBStkSize       = stk_size;               /* Store stack size 存储堆栈大小*/
        ptcb->OSTCBStkBottom     = pbos;                   /* Store pointer to bottom of stack存储栈底指针*/
        ptcb->OSTCBOpt           = opt;                    /* Store task options存储任务选项*/
        ptcb->OSTCBId            = id;                     /* Store task ID存储任务ID*/
#else //若未使用任务扩展功能
        pext                     = pext;                   /* Prevent compiler warning if not used     */
        stk_size                 = stk_size;
        pbos                     = pbos;
        opt                      = opt;
        id                       = id;
#endif


#if OS_TASK_DEL_EN > 0u //若允许删除任务
        ptcb->OSTCBDelReq        = OS_ERR_NONE;
#endif


#if OS_LOWEST_PRIO <= 63u                                         /* Pre-compute X, Y 预处理任务优先级 */
        ptcb->OSTCBY             = (INT8U)(prio >> 3u);
        ptcb->OSTCBX             = (INT8U)(prio & 0x07u);
#else                                                             /* Pre-compute X, Y                  */
        ptcb->OSTCBY             = (INT8U)((INT8U)(prio >> 4u) & 0xFFu);
        ptcb->OSTCBX             = (INT8U) (prio & 0x0Fu);
#endif
                                                                  /* Pre-compute BitX and BitY         */
        ptcb->OSTCBBitY          = (OS_PRIO)(1uL << ptcb->OSTCBY);
        ptcb->OSTCBBitX          = (OS_PRIO)(1uL << ptcb->OSTCBX);

(1)链表节点及参数

OSTCBFreeList是当前空闲TCB链表,相当于每初始化一个任务就要将OSTCBFreeList指向下一个没有使用的Freelist,保证每次创建任务的时候有OSTCBFreeList可用。

 if (ptcb != (OS_TCB *)0)    这个条件就是判断还有没有空闲TCB链表,如果没有空闲TCB链表就返回"错误"。

OSTCBFreeList            = ptcb->OSTCBNext;        /* Update pointer to free TCB list更新空TCB列表指针(指向下一空TCB链表)*/

下面就是其他参数赋值(堆栈、优先级、任务状态就绪等)。

(2)任务参数

这里的任务参数是传递过来的参数信息,归为到对应的空间,也就是参数赋值。

 ptcb->OSTCBDelReq        = OS_ERR_NONE; 任务可以删除(当使能了删除任务功能,在创建任务之后就可以删除创建的任务)。

#if (OS_EVENT_EN)
        ptcb->OSTCBEventPtr      = (OS_EVENT  *)0;         /* Task is not pending on an  event将事件控制块指向空*/
#if (OS_EVENT_MULTI_EN > 0u)
        ptcb->OSTCBEventMultiPtr = (OS_EVENT **)0;         /* Task is not pending on any events将任务多事件控制块指向空*/
#endif
#endif


#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u) && (OS_TASK_DEL_EN > 0u)
        ptcb->OSTCBFlagNode  = (OS_FLAG_NODE *)0;          /* Task is not pending on an event flag将事件标志节点指向空*/
#endif


#if (OS_MBOX_EN > 0u) || ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u))
        ptcb->OSTCBMsg       = (void *)0;                  /* No message received 将消息指向空*/
#endif


#if OS_TASK_PROFILE_EN > 0u
        ptcb->OSTCBCtxSwCtr    = 0uL;                      /* Initialize profiling variables初始化(性能分析)变量*/
        ptcb->OSTCBCyclesStart = 0uL;
        ptcb->OSTCBCyclesTot   = 0uL;
        ptcb->OSTCBStkBase     = (OS_STK *)0;
        ptcb->OSTCBStkUsed     = 0uL;
#endif

(1)优先级

UCOS优先级实现其功能具体的部分使用了"优先级表",查找优先级的算法为ucos优先级调度算法。

(2)事件

需要结合事件(信号量、消息邮箱等)分析。

(3)性能分析参数

"性能分析"就是对系统运行的性能,CPU使用率等分析。OS_TaskIdle空闲任务时 函数体中有一条语句:OSIdleCtr++;也就是统计空闲任务的计数次数。


3.

#if OS_TASK_REG_TBL_SIZE > 0u                              /* Initialize the task variables初始化任务变量*/
        for (i = 0u; i < OS_TASK_REG_TBL_SIZE; i++) {
            ptcb->OSTCBRegTbl[i] = 0u;
        }
#endif


        OSTCBInitHook(ptcb);


        OSTaskCreateHook(ptcb);                            /* Call user defined hook                   */


        OS_ENTER_CRITICAL(); //进临界区(关中断)
        OSTCBPrioTbl[prio] = ptcb; /*更新TCB优先级列表*/
        ptcb->OSTCBNext    = OSTCBList;            /* Link into TCB chain调用用户定义的HOOK函数*/
        ptcb->OSTCBPrev    = (OS_TCB *)0;
        if (OSTCBList != (OS_TCB *)0) { //如果不是首次创建任务
            OSTCBList->OSTCBPrev = ptcb;
        }
        OSTCBList               = ptcb;
        OSRdyGrp               |= ptcb->OSTCBBitY;         /* Make task ready to run使任务进入"就绪"状态*/
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        OSTaskCtr++;                                       /* Increment the #tasks counter任务计数器+1*/
        OS_EXIT_CRITICAL();
        return (OS_ERR_NONE);
    }
    OS_EXIT_CRITICAL();
    return (OS_ERR_TASK_NO_MORE_TCB);
}

上部分的"准备"工作完成之后,就剩下"就绪"工作了。

 OSTCBInitHook(ptcb) 和 OSTaskCreateHook(ptcb);  这两个函数一般成对出现,是用户自己的HOOK函数,用户自己要实现某些功能就写在这里。

OSTCBPrioTbl[prio] = ptcb; /*更新TCB优先级列表*/ 这条语句将该任务在TCB表中有一个对应的位置。

ptcb->OSTCBNext    = OSTCBList;  指向TCB链表。

OSTaskCtr++;   任务也有一个统计计数的变量。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值