//系統任務建立函數
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
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
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鏈表中。指針