1. OSTaskCreate()
OSTaskCreate()建立一個新任務,能夠在多任務環境啟動之前,或者執行任務中建立任務。注意,ISR中禁止建立任務,一個任務必須為無限循環結構。
源碼例如以下:
#if OS_TASK_CREATE_EN > 0 /* 條件編譯,是否同意任務的創建 */
INT8U OSTaskCreate (void (*task)(void *pd), /* 函數指針,void *pd為函數的參數 */
void *pdata, /* 建立任務時,傳遞的參數 */
OS_STK *ptos, /* 指向堆棧任務棧頂的指針 */
INT8U prio) /* 任務優先級 */
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_STK *psp;
INT8U err;#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO) { /* 參數檢查,優先級是否處於同意優先級之內 */
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL(); /* 關中斷 */
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* 推斷任務的優先級是否存在,如不存在,設置任 */
OSTCBPrioTbl[prio] = (OS_TCB *)1; /* 務優先級為1設置優先級后,就能夠開中斷了, */
/* 不用操心沖突,由於該優先級已經被占了 */
OS_EXIT_CRITICAL();
psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0);
/* 初始化堆棧,此函數與詳細的硬件有關,OS_CPU_C.C */
err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); /* 詳見此函數的說明 */
if (err == OS_NO_ERR) {
OS_ENTER_CRITICAL();
OSTaskCtr++; /* 任務計數器加1,統計執行的任務數 */
OS_EXIT_CRITICAL();
if (OSRunning == TRUE) { /* 假設是在任務執行過程中新建任務,須要進行 */
OS_Sched(); /* 任務調度,保證 優先級最高的任務處於執行態 */
}
} else {
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0;/* 假設任務創建失敗,優先級設置為0,放棄該 */
/* 任務的優先級保證別的任務創建時能夠使用 */
/* 此優先級 */
OS_EXIT_CRITICAL();
}
return (err); /* 創建任務失敗,返回錯誤代碼 */
}
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST); /* 返回OS_PRIO_EXIST,告知任務優先級已經存在 */
}
#endif
2. OSTaskCreateExt()
OSTaskCreateExt()為OSTaskCreate()的擴展函數,同意很多其它的內容設置。
源碼例如以下:
#if OS_TASK_CREATE_EXT_EN > 0
INT8U OSTaskCreateExt (void (*task)(void *pd), /* 同上 */
void *pdata, /* 同上 */
OS_STK *ptos, /* 同上 */
INT8U prio, /* 同上 */
INT16U id, /* 任務ID,2.52版本號,無實際作用,保留作為擴展用 */
OS_STK *pbos, /* 指向堆棧底部的指針,用於OSTaskStkChk()函數 */
INT32U stk_size, /* 指定任務堆棧的大小,由OS_STK類型決定 */
void *pext, /* 定義數據結構的指針,作為TCB的擴展 */
INT16U opt) /* 存放於任務操作相關的信息,詳見uCOS-II.H */
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_STK *psp;
INT8U err;#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) {
/* Make sure task doesn’t already exist at this priority *//* Reserve the priority to prevent others from doing … */
/* … the same thing until task is created. */
OSTCBPrioTbl[prio] = (OS_TCB *)1; OS_EXIT_CRITICAL();if (((opt & OS_TASK_OPT_STK_CHK) != 0×0000) ||
/* See if stack checking has been enabled */
((opt & OS_TASK_OPT_STK_CLR) != 0×0000)) {
/* See if stack needs to be cleared */
#if OS_STK_GROWTH == 1
(void)memset(pbos, 0, stk_size * sizeof(OS_STK));
#else
(void)memset(ptos, 0, stk_size * sizeof(OS_STK));
#endif
}psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt);
/* Initialize the task’s stack */
err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
if (err == OS_NO_ERR) {
OS_ENTER_CRITICAL();
OSTaskCtr++; /* Increment the #tasks counter */
OS_EXIT_CRITICAL();
if (OSRunning == TRUE) { /* Find HPT if multitasking has started */
OS_Sched();
}
} else {
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */
OS_EXIT_CRITICAL();
}
return (err);
}
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
#endif