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手册  可以知道为什么寄存器这么配置这么配置

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 初始化

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链表中。

你可能感兴趣的:(ucos,OSTaskStkInit(),OS_TCBInit())