ucos 初始化OSTaskCreate() 源碼分析 2

//系統任務建立函數

OSTaskCreate 任務建立

INT8U  OSTaskCreate (void   (*task)(void *p_arg),    //任務函數地址
                     void    *p_arg,                               //任務函數傳遞參數
                     OS_STK  *ptos,                        //任務的棧底
                     INT8U    prio)                    //任務優先級
{
    OS_STK    *psp;
    INT8U      err;
#if OS_CRITICAL_METHOD == 3u                 /* 中斷模式       */
    OS_CPU_SR  cpu_sr = 0u;
#endif
//基本上不用
#ifdef OS_SAFETY_CRITICAL_IEC61508
// 不容許建立任務
    if (OSSafetyCriticalStartFlag == OS_TRUE) {
        OS_SAFETY_CRITICAL_EXCEPTION();
    }
#endif

#if OS_ARG_CHK_EN > 0u
    if (prio > OS_LOWEST_PRIO) {             /* 肯定任務優先級範圍正確    */
        return (OS_ERR_PRIO_INVALID);
    }
#endif
    OS_ENTER_CRITICAL();
    if (OSIntNesting > 0u) {                 /* 肯定沒有嵌套中斷  */
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_CREATE_ISR);
    }
    if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* 當前優先級任務沒有存在  */
        OSTCBPrioTbl[prio] = OS_TCB_RESERVED;
        OS_EXIT_CRITICAL();
        psp = OSTaskStkInit(task, p_arg, ptos, 0u);      /* 任務堆棧初始化 並給賦給psp      */
        //OS_TCBInit(優先級指針,堆棧指針,棧底指針,任務標誌符,堆棧容量,擴展指針,選擇項) 
 err = OS_TCBInit(prio, psp, (OS_STK *)0, 0u, 0u, (void *)0, 0u);
        if (err == OS_ERR_NONE) {  //
            if (OSRunning == OS_TRUE) {      /*運行狀態 */
                OS_Sched();   //系統調度
            }
        } else {
            OS_ENTER_CRITICAL();
     //建立失敗,當前優先級任務清零
            OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others                 */
            OS_EXIT_CRITICAL();
        }
        return (err);
    }
    OS_EXIT_CRITICAL();
    return (OS_ERR_PRIO_EXIST);
}


查詢cortex-M3手冊  能夠知道爲何寄存器這麼配置這麼配置this

OSTaskStkInit() 任務棧初始化

OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
{
    OS_STK *stk;
    (void)opt;                                   /* 'opt' is not used, prevent warning  */
    stk       = ptos;                            /* Load stack pointer                */
    /* Registers stacked as if auto-saved on exception    */
    *(stk)    = (INT32U)0x01000000L;             /* xPSR                  */
    *(--stk)  = (INT32U)task;                    /* Entry Point                  */
    *(--stk)  = (INT32U)0xFFFFFFFEL;             /* R14 (LR)               */
    *(--stk)  = (INT32U)0x12121212L;             /* R12   12表明寄存器12                      */
    *(--stk)  = (INT32U)0x03030303L;             /* R3    03表明寄存器3                          */
    *(--stk)  = (INT32U)0x02020202L;             /* R2                 */
    *(--stk)  = (INT32U)0x01010101L;             /* R1           */
    *(--stk)  = (INT32U)p_arg;                   /* R0 : argument                */
     /* Remaining registers saved on process stack         */
    *(--stk)  = (INT32U)0x11111111L;             /* R11              */
    *(--stk)  = (INT32U)0x10101010L;             /* R10              */
    *(--stk)  = (INT32U)0x09090909L;             /* R9                */
    *(--stk)  = (INT32U)0x08080808L;             /* R8                 */
    *(--stk)  = (INT32U)0x07070707L;             /* R7                 */
    *(--stk)  = (INT32U)0x06060606L;             /* R6                */
    *(--stk)  = (INT32U)0x05050505L;             /* R5                                                 */
    *(--stk)  = (INT32U)0x04040404L;             /* R4                                                 */

    return (stk);
}


//單個TCB 初始化spa

OS_TCBInit() TCB塊初始化

INT8U  OS_TCBInit (INT8U    prio,  //優先級
                   OS_STK  *ptos,  //棧頂
                   OS_STK  *pbos, //棧底
                   INT16U   id,   //任務id
                   INT32U   stk_size,  //任務大小
                   void    *pext,   //任務數據擴展
                   INT16U   opt)
{
    OS_TCB    *ptcb;
#if OS_CRITICAL_METHOD == 3u         /* 進入臨界區模式Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr = 0u;
#endif
#if OS_TASK_REG_TBL_SIZE > 0u
    INT8U      i;
#endif

    OS_ENTER_CRITICAL();
    ptcb = OSTCBFreeList;                                  
    if (ptcb != (OS_TCB *)0) {  //空閒任務鏈表中取出一個
        OSTCBFreeList            = ptcb->OSTCBNext;        /* 更新空閒TCB列表         */
        OS_EXIT_CRITICAL();
        ptcb->OSTCBStkPtr        = ptos;                   /* 堆棧指針          */
        ptcb->OSTCBPrio          = prio;                   /* 優先級         */
        ptcb->OSTCBStat          = OS_STAT_RDY;            /* 狀態就緒       */
        ptcb->OSTCBStatPend      = OS_STAT_PEND_OK;        /* 清除阻塞狀態      */
        ptcb->OSTCBDly           = 0u;                     /* 不延時          */
        
        /*****************************************************************
        ************************    通常用不到  ******************************/
        #if OS_TASK_CREATE_EXT_EN > 0u
                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 > 0u
                ptcb->OSTCBDelReq        = OS_ERR_NONE;  //刪除請求清空
        #endif
        //   將任務優先級轉換  存到bitx,bity中
        #if OS_LOWEST_PRIO <= 63u                        /* 進行優先級轉換         */
                ptcb->OSTCBY             = (INT8U)(prio >> 3u);
                ptcb->OSTCBX             = (INT8U)(prio & 0x07u);
        #else                   
                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);
        
        #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 分析 variables           */
                ptcb->OSTCBCyclesStart = 0uL;
                ptcb->OSTCBCyclesTot   = 0uL;
                ptcb->OSTCBStkBase     = (OS_STK *)0;
                ptcb->OSTCBStkUsed     = 0uL;
        #endif
        
    #if OS_TASK_NAME_EN > 0u
              ptcb->OSTCBTaskName    = (INT8U *)(void *)"?";
    #endif
        
   #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 賦給 當前任務優先級TCB 
         //鏈接之前建立的tcb
        ptcb->OSTCBNext    = OSTCBList;        /* 添加到TCB鏈表中        */
        ptcb->OSTCBPrev    = (OS_TCB *)0;
        if (OSTCBList != (OS_TCB *)0) {
            OSTCBList->OSTCBPrev = ptcb;   //創建雙向鏈接
        }
 
        OSTCBList               = ptcb;      //新鏈表添加到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);
}

   

任務建立主要作的事情:判斷優先級範圍是否正常、判斷是否有中斷嵌套、判斷當前優先級TCB是否存在、將參數寫入任務棧中,初始化TCB,將值賦給TCB中,將新建的TCB添加到TCB鏈表中。指針

相關文章
相關標籤/搜索