?? os_task.c
字號:
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) { /* Task must be suspended */
//任務必須存在且被掛起
if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && /* Remove suspension */
//是通過清除OSTCBStat域中的OS_STAT_SUSPEND位而取消掛起的
(ptcb->OSTCBDly == 0)) { /* Must not be delayed */
//要使任務處于就緒態,OSTCBDly須為0。因為沒有任何標志表明任務
//正在等待延遲時間到
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;//當以上兩個條件滿足時,任務才處于就緒狀態
OS_EXIT_CRITICAL();
OS_Sched();//任務調度會檢查被恢復的任務擁有的優先級是否比調用本函數的任務
//優先級高。
} else {
OS_EXIT_CRITICAL();
}
return (OS_NO_ERR);//恢復成功
}
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_SUSPENDED);//如果任務沒有被掛起
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* STACK CHECKING
*
* Description: This function is called to check the amount of free memory left on the specified task's
* stack.
*
* Arguments : prio is the task priority
*
* pdata is a pointer to a data structure of type OS_STK_DATA.
*
* Returns : OS_NO_ERR upon success
* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
* OS_TASK_NOT_EXIST if the desired task has not been created
* OS_TASK_OPT_ERR if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created
*********************************************************************************************************
*/
/*
*********************************************************************************************************
堆棧檢驗
描述:這個函數用于檢驗指定任務堆棧的剩余存儲空間數量
參數:prio:任務優先級
pdata:OS_STK_DATA結構類型的數據指針。
返回:OS_NO_ERR :成功。
OS_PRIO_INVALID:優先級數值大于最大值或者沒有指定OS_PRIO_SELF
OS_TASK_NOT_EXIST:如果指定任務沒有被創建
OS_TASK_OPT_ERR:如果任務創建時沒有指定OS_TASK_OPT_STK_CHK
*********************************************************************************************************
*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
OS_STK *pchk;
INT32U free;
INT32U size;
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* Make sure task priority is valid */
return (OS_PRIO_INVALID);//如果OS_ARG_CHK_EN設置為1,優先級值大于最大值且不是 OS_PRIO_SELF
}
#endif
pdata->OSFree = 0; /* Assume failure, set to 0 size */
pdata->OSUsed = 0;//初始化為0
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { /* See if check for SELF */
prio = OSTCBCur->OSTCBPrio;//如果想知道當前任務堆棧信息
}
ptcb = OSTCBPrioTbl[prio];//提取優先級,如果非零,代表任務存在
if (ptcb == (OS_TCB *)0) { /* Make sure task exist */
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_EXIST);//任務不存在
}
if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) { /* Make sure stack checking option is set */
//要保證允許檢驗,要保證已經創建了任務,并傳遞了參數OS_TASK_OPT_STK_CHK
//如果建立任務的是OSTaskCreate(),而不是OSTaskCreateExt(),那么因為參數opt為零,
//所以檢驗失敗。
OS_EXIT_CRITICAL();
return (OS_TASK_OPT_ERR);
}
free = 0;
size = ptcb->OSTCBStkSize;//如果所有條件滿足,OSTaskStkChk就會像前面描述那樣,從堆棧棧底
//開始統計堆棧的空閑空間,直到發現一個儲存值非零的堆棧入口。
pchk = ptcb->OSTCBStkBottom;
OS_EXIT_CRITICAL();
#if OS_STK_GROWTH == 1//如果堆棧設置成從高到低增長
while (*pchk++ == (OS_STK)0) { /* Compute the number of zero entries on the stk */
free++;//計算空塊
}
#else//如果從低到高增長
while (*pchk-- == (OS_STK)0) {
free++;
}
#endif
pdata->OSFree = free * sizeof(OS_STK); /* Compute number of free bytes on the stack */
//計算空堆棧字節
pdata->OSUsed = (size - free) * sizeof(OS_STK); /* Compute number of bytes used on the stack */
//計算已用堆棧字節
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* SUSPEND A TASK
*
* Description: This function is called to suspend a task. The task can be the calling task if the
* priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF.
*
* Arguments : prio is the priority of the task to suspend. If you specify OS_PRIO_SELF, the
* calling task will suspend itself and rescheduling will occur.
*
* Returns : OS_NO_ERR if the requested task is suspended
* OS_TASK_SUSPEND_IDLE if you attempted to suspend the idle task which is not allowed.
* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
* OS_TASK_SUSPEND_PRIO if the task to suspend does not exist
*
* Note : You should use this function with great care. If you suspend a task that is waiting for
* an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from
* running when the event arrives.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
掛起一個任務
描述:調用此函數去掛起一個任務,如果傳送到OSTaskSuspend()的任務的優先級是要掛起的任務或者是
OS_PRIO_SELF,那么這個任務將被掛起。
參數: prio:需要掛起任務的優先級。如果指定OS_PRIO_SELF,那么這個任務將自己掛起,再發生再
次調度。
返回:OS_NO_ERR:如果請求的任務被掛起。
OS_TASK_SUSPEND_IDLE:如果想掛起空閑任務
OS_PRIO_INVALID :想掛起任務優先級不合理
OS_TASK_SUSPEND_PRIO:需要掛起的任務不存在。
備注:調用時要十分小心,如果你想掛起一個等待事件(郵箱,消息,隊列)的任務,事件到來的時候
你將阻止這個任務運行。
*********************************************************************************************************
*/
#if OS_TASK_SUSPEND_EN > 0
INT8U OSTaskSuspend (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
BOOLEAN self;
OS_TCB *ptcb;
#if OS_ARG_CHK_EN > 0
if (prio == OS_IDLE_PRIO) { /* Not allowed to suspend idle task */
return (OS_TASK_SUSPEND_IDLE);//不能掛起空閑任務
}
if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* Task priority valid ? */
return (OS_PRIO_INVALID);//任務優先級不合理
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { /* See if suspend SELF */
//是不是要掛起自己,這樣,OSTaskSuspend 會從當前任務的任務控制塊中
//獲得當前任務的優先級
prio = OSTCBCur->OSTCBPrio;
self = TRUE;
} else if (prio == OSTCBCur->OSTCBPrio) { /* See if suspending self */
self = TRUE;//也可以通過指定優先級,掛起調用本函數的任務。這兩種情況下,
//任務調度都被調用,這是為什么要定義局部變量self的原因,該變量在
//適當的時候會被測試,如果沒有掛起調用本函數的任務,OSTaskSus_pend()
//就沒有必要運行任務調度程序,因為調用該函數的任務正在掛起一個
//優先級比較低的任務
} else {
self = FALSE; /* No suspending another task */
//不是要掛起自己
}
ptcb = OSTCBPrioTbl[prio];//取需要掛起任務的TCB
if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */
OS_EXIT_CRITICAL();
return (OS_TASK_SUSPEND_PRIO);//如果要掛起的任務不存在
}
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { /* Make task not ready */
OSRdyGrp &= ~ptcb->OSTCBBitY;//如果該任務存在,就會從就緒表中去掉。
//要掛起的任務可能不在就緒表中,有可能在等待事件發生或者延遲。要
//掛起的任務在OSRdyTbl[]中對應位已被清除。再次清除該位,比先檢驗該位是否被
//清除,如果沒有清除再清除快得多,所以就沒有檢驗了。
}
ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */
//終于掛起來了
OS_EXIT_CRITICAL();
if (self == TRUE) { /* Context switch only if SELF */
OS_Sched();//僅僅在掛起任務自己的情況下才調用任務調度
}
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* QUERY A TASK
*
* Description: This function is called to obtain a copy of the desired task's TCB.
*
* Arguments : prio is the priority of the task to obtain information from.
*
* Returns : OS_NO_ERR if the requested task is suspended
* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
* OS_PRIO_ERR if the desired task has not been created
*********************************************************************************************************
*/
/*
*********************************************************************************************************
查詢一個任務
描述:此函數調用去獲得一個指定任務TCB的副本
參數:prio:指定函數的優先級
返回: OS_NO_ERR:請求的函數被掛起
OS_PRIO_INVALID:任務優先級不合法
OS_PRIO_ERR如果指定的函數還沒有創建
*********************************************************************************************************
*/
#if OS_TASK_QUERY_EN > 0
INT8U OSTaskQuery (INT8U prio, OS_TCB *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* Task priority valid ? */
return (OS_PRIO_INVALID);//優先級不合法
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { /* See if suspend SELF */
prio = OSTCBCur->OSTCBPrio;//掛起自己
}
ptcb = OSTCBPrioTbl[prio];//不掛起自己
if (ptcb == (OS_TCB *)0) { /* Task to query must exist */
//任務不存在
OS_EXIT_CRITICAL();
return (OS_PRIO_ERR);//返回錯誤
}
memcpy(pdata, ptcb, sizeof(OS_TCB)); /* Copy TCB into user storage area */
//任務的TCB復制到用戶的存儲空間
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -