Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1147277
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2279
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(241)

文章存档

2023年(8)

2022年(2)

2021年(3)

2020年(30)

2019年(11)

2018年(27)

2017年(54)

2016年(83)

2015年(23)

我的朋友

分类: 嵌入式

2015-07-21 21:56:52

/*
*********************************************************************************************************
*                                            INITIALIZE TCB
*
* Description: This function is internal to uC/OS-II and is used to initialize a Task Control Block when
*              a task is created (see OSTaskCreate() and OSTaskCreateExt()).
*
* Arguments  : prio          is the priority of the task being created
*
*              ptos          is a pointer to the task's top-of-stack assuming that the CPU registers
*                            have been placed on the stack.  Note that the top-of-stack corresponds to a
*                            'high' memory location is OS_STK_GROWTH is set to 1 and a 'low' memory
*                            location if OS_STK_GROWTH is set to 0.  Note that stack growth is CPU
*                            specific.
*
*              pbos          is a pointer to the bottom of stack.  A NULL pointer is passed if called by
*                            'OSTaskCreate()'.
*
*              id            is the task's ID (0..65535)
*
*              stk_size      is the size of the stack (in 'stack units').  If the stack units are INT8Us
*                            then, 'stk_size' contains the number of bytes for the stack.  If the stack
*                            units are INT32Us then, the stack contains '4 * stk_size' bytes.  The stack
*                            units are established by the #define constant OS_STK which is CPU
*                            specific.  'stk_size' is 0 if called by 'OSTaskCreate()'.
*
*              pext          is a pointer to a user supplied memory area that is used to extend the task
*                            control block.  This allows you to store the contents of floating-point
*                            registers, MMU registers or anything else you could find useful during a
*                            context switch.  You can even assign a name to each task and store this name
*                            in this TCB extension.  A NULL pointer is passed if called by OSTaskCreate().
*
*              opt           options as passed to 'OSTaskCreateExt()' or,
*                            0 if called from 'OSTaskCreate()'.
*
* Returns    : OS_ERR_NONE         if the call was successful
*              OS_ERR_TASK_NO_MORE_TCB  if there are no more free TCBs to be allocated and thus, the task cannot
*                                  be created.
*
* Note       : This function is INTERNAL to uC/OS-II and your application should not call it.
*********************************************************************************************************
*/
INT8U  OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)
{
    OS_TCB    *ptcb;
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr = 0;
#endif
 
    OS_ENTER_CRITICAL();
    ptcb = OSTCBFreeList;                                  /* Get a free TCB from the free TCB list    */
    if (ptcb != (OS_TCB *)0) {
        OSTCBFreeList        = ptcb->OSTCBNext;            /* Update pointer to free TCB list          */
//空任务链表更新 指向TCB的双向链接的后链接  我认为是FreeList 指向了原本那个TCB块的后面一个TCB块,
//即移除一个TCB给OSTCBList*/

        OS_EXIT_CRITICAL();
        ptcb->OSTCBStkPtr    = ptos;                       /* Load Stack pointer in TCB                */
        ptcb->OSTCBPrio      = prio;                       /* Load task priority into TCB              */
        ptcb->OSTCBStat      = OS_STAT_RDY;                /* Task is ready to run                     */
        ptcb->OSTCBStatPend  = OS_STAT_PEND_OK;            /* Clear pend status                        */
        ptcb->OSTCBDly       = 0;                          /* Task is not delayed                      */
#if OS_TASK_CREATE_EXT_EN > 0
        ptcb->OSTCBExtPtr    = pext;                       /* Store pointer to TCB extension           */
        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                            */
#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 > 0
        ptcb->OSTCBDelReq    = OS_ERR_NONE;
#endif
#if OS_LOWEST_PRIO <= 63
        ptcb->OSTCBY         = (INT8U)(prio >> 3);         /* Pre-compute X, Y, BitX and BitY          */
        ptcb->OSTCBBitY      = (INT8U)(1 << ptcb->OSTCBY);
        ptcb->OSTCBX         = (INT8U)(prio & 0x07);
        ptcb->OSTCBBitX      = (INT8U)(1 << ptcb->OSTCBX);
#else
        ptcb->OSTCBY         = (INT8U)((prio >> 4) & 0xFF);/* Pre-compute X, Y, BitX and BitY          */
        ptcb->OSTCBBitY      = (INT16U)(1 << ptcb->OSTCBY);
        ptcb->OSTCBX         = (INT8U)(prio & 0x0F);
        ptcb->OSTCBBitX      = (INT16U)(1 << ptcb->OSTCBX);
#endif
#if OS_EVENT_EN
        ptcb->OSTCBEventPtr  = (OS_EVENT *)0;              /* Task is not pending on an event          */
#endif
#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0)
        ptcb->OSTCBFlagNode  = (OS_FLAG_NODE *)0;          /* Task is not pending on an event flag     */
#endif
#if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0))
        ptcb->OSTCBMsg       = (void *)0;                  /* No message received                      */
#endif
#if OS_TASK_PROFILE_EN > 0
        ptcb->OSTCBCtxSwCtr    = 0L;                       /* Initialize profiling variables           */
        ptcb->OSTCBCyclesStart = 0L;
        ptcb->OSTCBCyclesTot   = 0L;
        ptcb->OSTCBStkBase     = (OS_STK *)0;
        ptcb->OSTCBStkUsed     = 0L;
#endif
#if OS_TASK_NAME_SIZE > 1
        ptcb->OSTCBTaskName[0] = '?';                      /* Unknown name at task creation            */
        ptcb->OSTCBTaskName[1] = OS_ASCII_NUL;
#endif
        OSTCBInitHook(ptcb);
        OSTaskCreateHook(ptcb);                            /* Call user defined hook                   */
        OS_ENTER_CRITICAL();
        OSTCBPrioTbl[prio] = ptcb;   //见OSTaskCreate的 if (OSTCBPrioTbl[prio] == (OS_TCB *)0)
        ptcb->OSTCBNext    = OSTCBList;                    /* Link into TCB chain                      */
将OSTCBList指向的那个TCB地址赋给ptcb->OSTCBNext(刚才从FreeList中移除的那个TCB的Next) 
//即让下图的1优先级的tcb ->next = 3优先级的tcb

        ptcb->OSTCBPrev    = (OS_TCB *)0;
//如图prev前指针是指向NULL//0优先级tcb prev = 0
        if (OSTCBList != (OS_TCB *)0) {
            OSTCBList->OSTCBPrev = ptcb;
//如下图 假如原先OSTCBList指向OSTCBPrio=1的那个TCB,即OSTCBList != (OS_TCB *)0   
//让OSTCBList->OSTCBPrev////(OSTCBPrio=1的那个TCB的OSTCBPrev)=刚才从FreeList中移除的那个TCB

        }
        OSTCBList               = ptcb;
// //OSTCBList由原来指向OSTCBPrio=1的那个TCB改为指向OSTCBPrio=3的那个TCB 

        OSRdyGrp               |= ptcb->OSTCBBitY;         /* Make task ready to run                   */
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        OSTaskCtr++;                                       /* Increment the #tasks counter             */
        OS_EXIT_CRITICAL();
        return (OS_ERR_NONE);
    }
    OS_EXIT_CRITICAL();
    return (OS_ERR_TASK_NO_MORE_TCB);
}


OS_EXT  OS_TCB           *OSTCBCur;                        /* Pointer to currently running TCB         */
OS_EXT  OS_TCB           *OSTCBFreeList;                   /* Pointer to list of free TCBs             */
OS_EXT  OS_TCB           *OSTCBHighRdy;                    /* Pointer to highest priority TCB R-to-R   */
OS_EXT  OS_TCB           *OSTCBList;                       /* Pointer to doubly linked list of TCBs    */
OS_EXT  OS_TCB           *OSTCBPrioTbl[OS_LOWEST_PRIO + 1];/* Table of pointers to created TCBs        */
OS_EXT  OS_TCB            OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS];   /* Table of TCBs                  */

图片
阅读(1747) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~