?? os_task.c
字號:
OS_STK *pbos,
INT32U stk_size,
void *pext,
INT16U opt)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
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; /* 保留該優先級避免其他處理 ... */
/* ... 直到任務建立. */
OS_EXIT_CRITICAL();
if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) || /* 如果使能堆棧檢驗 */
((opt & OS_TASK_OPT_STK_CLR) != 0x0000))
{ /* 如果堆棧需要清零 */
#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); /* 初始化任務堆棧 */
err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
if (err == OS_NO_ERR)
{
OS_ENTER_CRITICAL();
OSTaskCtr++; /* 增加任務計數器 */
OS_EXIT_CRITICAL();
if (OSRunning == TRUE)
{ /* 如果多任務啟動尋找最高優先級任務 */
OS_Sched();
}
}
else
{
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* 放棄該優先級 */
OS_EXIT_CRITICAL();
}
return (err);
}
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 刪除任務
*
* 函數描述: 該函數為刪除任務。調用的任務通過設定自身的優先級別可以刪除自身。被刪除的任務返回到睡眠狀態,并
* 通過再次創建刪除掉的任務來重新激活。
*
* 輸入參數: prio 待刪除任務的優先級。注意,如果不知當前任務的優先級可通過設定為OS_PRIO_SELF來刪除當前任務。
*
*
* 返回值 : OS_NO_ERR 調用成功
* OS_TASK_DEL_IDLE 想刪除 uC/OS-II 的空閑任務
* OS_PRIO_INVALID 指定的優先級高于允許的最大值
* (例如. >= OS_LOWEST_PRIO)或沒有指定 OS_PRIO_SELF.
* OS_TASK_DEL_ERR 想刪除的任務不存在
* OS_TASK_DEL_ISR 想從中斷服務程序中刪除任務
*
* 注釋 : 1)為減少中斷隱患, OSTaskDel() 將關閉該任務:
* a) 通過脫離就緒
* b) 通過從等待列表中移除
* c) 通過避免 OSTimeTick() 使任務就緒待運行。
* 該任務能從 uC/OS-II 中的雜項結構中脫離。
* 2) OS_EXIT_CRITICAL() 后調用 OS_Dummy()的意義是因為在大多數處理器中,緊跟開中斷指令的下
* 一條指令常被忽略。
* 3) 中斷服務程序不能刪除任務
* 4) 如果當前任務正在被刪除,由于它已從就緒列表中移出,所以,它將不能被調度,上鎖嵌套計數器增加
* 增加嵌套計數器是避免其他任務被調度。也就是一個中斷服務程序將返回到當前正被刪除的任務。
* 刪除剩余部分將完成。
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_DEL_EN > 0
INT8U OSTaskDel (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
#if OS_EVENT_EN > 0
OS_EVENT *pevent;
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
OS_FLAG_NODE *pnode;
#endif
OS_TCB *ptcb;
BOOLEAN self;
self = self; // 預防編譯警告
if (OSIntNesting > 0)
{ /* 確保不是在ISR中刪除一個程序 */
return (OS_TASK_DEL_ISR);
}
#if OS_ARG_CHK_EN > 0
if (prio == OS_IDLE_PRIO)
{ /* 不允許刪除空閑任務 */
return (OS_TASK_DEL_IDLE);
}
if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF)
{ /* 任務優先級是否有效? */
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF)
{ /* 是否請求刪除自身? */
prio = OSTCBCur->OSTCBPrio; /* 設定刪除當前任務的優先級 */
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb != (OS_TCB *)0) /* 要刪除的任務是否存在? */
{
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00)
{ /* 使任務脫離就緒 */
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
#if OS_EVENT_EN > 0
pevent = ptcb->OSTCBEventPtr; /* 任務是否正在等待事件? */
if (pevent != (OS_EVENT *)0)
{
if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
{ /* ... 移除任務 */
pevent->OSEventGrp &= ~ptcb->OSTCBBitY; /* ... 從事件控制塊 */
}
}
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
pnode = ptcb->OSTCBFlagNode;
if (pnode != (OS_FLAG_NODE *)0)
{ /* 任務是否在等事件標志? */
OS_FlagUnlink(pnode); /* 從等待列表中移除 */
}
#endif
ptcb->OSTCBDly = 0; /* 避免 OSTimeTick() 更新 */
ptcb->OSTCBStat = OS_STAT_RDY; /* 防止任務重新開始 */
if (OSLockNesting < 255)
{
OSLockNesting++;
}
OS_EXIT_CRITICAL(); /* 打開中斷忽略下一指令 */
OS_Dummy(); /* ... 啞函數確保中斷關閉 */
OS_ENTER_CRITICAL(); /* ... 此處關閉中斷 */
if (OSLockNesting > 0)
{
OSLockNesting--;
}
OSTaskDelHook(ptcb); /* 調用戶定義的鉤子函數 */
OSTaskCtr--; /* 任務數減一 */
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* 舊優先級任務清零 */
if (ptcb->OSTCBPrev == (OS_TCB *)0)
{ /* 從任務控制塊鏈上移除 */
ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0;
OSTCBList = ptcb->OSTCBNext;
}
else
{
ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext;
ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev;
}
ptcb->OSTCBNext = OSTCBFreeList; /* 把任務控制塊返回到空余任務控制塊 */
OSTCBFreeList = ptcb;
OS_EXIT_CRITICAL();
OS_Sched(); /* 尋找新的最高優先級任務 */
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return (OS_TASK_DEL_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 請求刪除自身
*
* 函數描述: 該函數用于:
* a) 通知任務刪除自身
* b) 其他任務請求當前任務刪除自身
* 首先,試圖刪除一個任務,但是該任務卻占用著一些內存緩沖區、信號量、郵箱、隊列等資源。
* 因為一些資源還未釋放,任務不該被刪。正在請求的任務調用 OSTaskDelReq() 來顯示需要刪除的任務。
* 例如,10號任務需被刪除。請求刪除的任務例如,5號,將調用 OSTaskDelReq(10)。當10號任務執行時,
* 它將調用 OSTaskDelReq(OS_PRIO_SELF),并檢測函數的返回值。如果返回值是OS_TASK_DEL_REQ,則5號請
* 求刪除10號任務。10號任務將如下:
*
* void Task(void *data)
* {
* .
* .
* while (1)
* {
* OSTimeDly(1);
* if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ)
* {
* Release any owned resources;
* De-allocate any dynamic memory;
* OSTaskDel(OS_PRIO_SELF);
* }
* }
* }
*
* 輸入參數 : prio 被刪除的任務的優先級
*
* Returns : OS_NO_ERR 如果任務存在,請求許可注冊
* OS_TASK_NOT_EXIST 是否任務已被刪除。允許調用函數知道請求是否執行。
* OS_TASK_DEL_IDLE 請求刪除的任務是否是 uC/OS-II的空閑任務
* OS_PRIO_INVALID 指定的優先級是否高于允許的最大值。
* (例如 >= OS_LOWEST_PRIO) 或沒有指定為 OS_PRIO_SELF.
* OS_TASK_DEL_REQ 一個任務(可能是其他任務) 是否請求刪除正在運行的任務
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_DEL_EN > 0
INT8U OSTaskDelReq (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
BOOLEAN stat;
INT8U err;
OS_TCB *ptcb;
#if OS_ARG_CHK_EN > 0
if (prio == OS_IDLE_PRIO)
{ /* 不允許刪除空閑任務 */
return (OS_TASK_DEL_IDLE);
}
if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF)
{ /* 任務優先級是否有效 ? */
return (OS_PRIO_INVALID);
}
#endif
if (prio == OS_PRIO_SELF)
{ /* 是否一個任務正在請求 ... */
OS_ENTER_CRITICAL(); /* ... 這個任務要刪除自身 */
stat = OSTCBCur->OSTCBDelReq; /* 返回給調用函數的請求狀態 */
OS_EXIT_CRITICAL();
return (stat);
}
OS_ENTER_CRITICAL();
ptcb = OSTCBPrioTbl[prio];
if (ptcb != (OS_TCB *)0)
{ /* 要刪除的任務必須存在 */
ptcb->OSTCBDelReq = OS_TASK_DEL_REQ; /* 設定標志顯示任務被刪除 */
err = OS_NO_ERR;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -