uC/OS-II源碼解析(os_task.c)

/*
** ver: 2.52
** file: os_task.c
** brief: 任務相關操作 C 文件
*/



#ifndef  OS_MASTER_FILE
#include "includes.h"                           /* 包含頭文件 */                 
#endif

/*
***************************************************************************
*                                        改變任務優先級
*
* brief   : 該函數用來改變任務優先級
*
* oldprio : 舊的任務優先級
*
* newprio : 新的任務優先級
*
* Returns    : OS_NO_ERR        優先級修改成功
*              OS_PRIO_INVALID  無效優先級
*              OS_PRIO_EXIST    優先級已經存在
*              OS_PRIO_ERR      不存在優先級對應的任務
****************************************************************************
*/

#if OS_TASK_CHANGE_PRIO_EN > 0
INT8U  OSTaskChangePrio (INT8U oldprio, INT8U newprio)
{
#if OS_CRITICAL_METHOD == 3                      
    OS_CPU_SR    cpu_sr;
#endif

#if OS_EVENT_EN > 0
    OS_EVENT    *pevent;
#endif

    OS_TCB      *ptcb;
    INT8U        x;
    INT8U        y;
    INT8U        bitx;
    INT8U        bity;



#if OS_ARG_CHK_EN > 0                      /* 參數檢查 */            
    if ((oldprio >= OS_LOWEST_PRIO && oldprio != OS_PRIO_SELF)  ||
         newprio >= OS_LOWEST_PRIO) {      /* 優先級檢查 */
        return (OS_PRIO_INVALID);
    }
#endif
    OS_ENTER_CRITICAL();
    if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) {   
        OS_EXIT_CRITICAL();                 /* 已經存在 newprio 優先級的任務 */
        return (OS_PRIO_EXIST);
    } else {
        OSTCBPrioTbl[newprio] = (OS_TCB *)1;/* 佔用 OSTCBPrioTbl[newprio] */
        OS_EXIT_CRITICAL();
        y    = newprio >> 3;                /* 預運算 */
        bity = OSMapTbl[y];
        x    = newprio & 0x07;
        bitx = OSMapTbl[x];
        OS_ENTER_CRITICAL();
        if (oldprio == OS_PRIO_SELF) {      /* 是否改變自身優先級 */
            oldprio = OSTCBCur->OSTCBPrio;  /* 改變自身優先級 */
        }
        ptcb = OSTCBPrioTbl[oldprio];
        if (ptcb != (OS_TCB *)0) {          /* 任務存在 */
            OSTCBPrioTbl[oldprio] = (OS_TCB *)0;/* 移除 TCB */
            if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) {  
                                            /* 如果任務是就緒,則清除 */
                if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) {
                    OSRdyGrp &= ~ptcb->OSTCBBitY;
                }                   
                OSRdyGrp    |= bity;        /* 使優先級任務進入就緒 */                    
                OSRdyTbl[y] |= bitx;
#if OS_EVENT_EN > 0
            } else {
                pevent = ptcb->OSTCBEventPtr;
                if (pevent != (OS_EVENT *)0) {/* 任務正在等待事件發生  */
                                              /* 清除等待任務 */
                    if ((pevent->OSEventTbl[ptcb->OSTCBY] 
                        &= ~ptcb->OSTCBBitX) == 0) {
                        pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
                    }
                    pevent->OSEventGrp    |= bity;/* 使新優先級任務等待 */
                    pevent->OSEventTbl[y] |= bitx;
                }
#endif
            }
            OSTCBPrioTbl[newprio] = ptcb;    /* 把任務控制塊給新優先級任務 */
            ptcb->OSTCBPrio       = newprio; /* 初始化任務控制塊 */
            ptcb->OSTCBY          = y;
            ptcb->OSTCBX          = x;
            ptcb->OSTCBBitY       = bity;
            ptcb->OSTCBBitX       = bitx;
            OS_EXIT_CRITICAL();
            OS_Sched();                      /* 任務調度 */
            return (OS_NO_ERR);
        } else {     /* 任務不存在 */
            OSTCBPrioTbl[newprio] = (OS_TCB *)0;/* 釋放 OSTCBPrioTbl[newprio] */
            OS_EXIT_CRITICAL();
            return (OS_PRIO_ERR);         
        }
    }
}
#endif
/*$PAGE*/
/*
****************************************************************************
*                                            創建一個任務
*
* brief : 創建任務,不能在 ISR 中調用
*
* task  : 指向任務函數的指針
*
* pdata : 傳遞給任務的參數
*
* ptos  : 堆棧棧頂指針
*
* prio  : 任務優先級
*
* returns    : OS_NO_ERR        創建任務成功
*              OS_PRIO_EXIT     任務已經存在
*              OS_PRIO_INVALID  無效優先級
*****************************************************************************
*/

#if OS_TASK_CREATE_EN > 0
INT8U  OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                 
    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;    /* 佔用 OSTCBPrioTbl[prio] */

        OS_EXIT_CRITICAL();
        /* 初始化任務堆棧 */
        psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0);
        /* 初始化任務控制塊 */
        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;/* 釋放 OSTCBPrioTbl[prio] */
            OS_EXIT_CRITICAL();
        }
        return (err);
    }
    OS_EXIT_CRITICAL();
    return (OS_PRIO_EXIST);
}
#endif
/*$PAGE*/
/*
*********************************************************************************
*                                     創建一個任務
*
* brief : 創建任務,類似於函數 OSTaskCreate(),對其進行了擴展
*
* task  : 指向任務函數的指針
*
* pdata : 傳遞給任務的參數
*
* ptos  : 堆棧棧頂指針
*
* prio  : 任務優先級
*
* id    : 任務 ID
*
* pbos  : 堆棧棧底指針
*
* stk_size : 對棧大小
*
* pext  :  TCB 擴展數據結構指針
*
* opt   :  選擇項.
*              OS_TASK_OPT_STK_CHK 堆棧檢查
*              OS_TASK_OPT_STK_CLR 堆棧清 0         
*              OS_TASK_OPT_SAVE_FP 保存浮點寄存器      
*                 
*
* returns    : OS_NO_ERR        創建任務成功
*              OS_PRIO_EXIT     任務已經存在         
*              OS_PRIO_INVALID  無效優先級
********************************************************************************
*/
/*$PAGE*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U  OSTaskCreateExt (void   (*task)(void *pd),
                        void    *pdata,
                        OS_STK  *ptos,
                        INT8U    prio,
                        INT16U   id,
                        OS_STK  *pbos,
                        INT32U   stk_size,
                        void    *pext,
                        INT16U   opt)
{
#if OS_CRITICAL_METHOD == 3                 
    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;    /* 佔用 OSTCBPrioTbl[prio] */

        OS_EXIT_CRITICAL();

        if (((opt & OS_TASK_OPT_STK_CHK) != 0x0000) ||   /* 堆棧檢查 */
            ((opt & OS_TASK_OPT_STK_CLR) != 0x0000)) {   /* 堆棧清 0 */
            #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++;                  /* 任務數加 1 */
            OS_EXIT_CRITICAL();
            if (OSRunning == TRUE) {      /* 任務調度 */
                OS_Sched();
            }
        } else {
            OS_ENTER_CRITICAL();
            OSTCBPrioTbl[prio] = (OS_TCB *)0; /* 釋放 佔用 OSTCBPrioTbl[prio] */
            OS_EXIT_CRITICAL();
        }
        return (err);
    }
    OS_EXIT_CRITICAL();
    return (OS_PRIO_EXIST);
}
#endif
/*$PAGE*/
/*
**********************************************************************************
*                                            刪除一個任務
*
* bried: 刪除任務,通過重新創建可以再次激活任務
*
* prio : 任務優先級
*
* returns    : OS_NO_ERR           成功
*              OS_TASK_DEL_IDLE    不允許刪除空閒任務
*              OS_PRIO_INVALID     無效優先級
*              OS_TASK_DEL_ERR     任務不存在
*              OS_TASK_DEL_ISR     不能中斷中刪除任務
*
**********************************************************************************
*/
/*$PAGE*/
#if OS_TASK_DEL_EN > 0
INT8U  OSTaskDel (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                      
    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;



    if (OSIntNesting > 0) {           /* 不能在中斷中刪除任務    */
        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;   /* 防止其他任務ISR調用 OSTaskResume()使任務運行 */
        if (OSLockNesting < 255) {       /* 禁止任務調度 */
            OSLockNesting++;
        }
        OS_EXIT_CRITICAL();              /* 開中斷,以縮短中斷響應 */
        OS_Dummy();                      /* 確保中斷被打開過       */
        OS_ENTER_CRITICAL();             /* 關中斷                 */
        if (OSLockNesting > 0) {         /* 運行任務調度           */
            OSLockNesting--;
        }
        OSTaskDelHook(ptcb);             /* 調用用戶自定義鉤子函數 */
        OSTaskCtr--;                     /* 任務數減 1             */
        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*/
/*
**************************************************************************************
*                                    請求刪除任務
*
* brief : 這個函數被用來 :
*                   a) 任務A 通知任務B 刪除任務B 就是老子不會殺你,你自殺的意思
*                   b) 任務B 查看是否有其他任務刪除自己,注意 我要自殺了
*              是不是有點小懵逼.  簡單的說就是, 你想刪除一個任務
*              然而,這個任務佔用一些資源 (內存緩衝區,信號量, 郵
*              箱, 隊列 等等). 因此這個任務不能被刪除,否則會導致
*              存儲器漏洞,這就需要使用 OSTaskDelReq() 去通知到被
*              刪除的任務,讓其釋放資源後刪除自己,例如, 任務 #10 
*              需要被刪除. 任務#5將調用OSTaskDelReq(10),任務#10 
*              調用OSTaskDelReq(OS_PRIO_SELF)查詢是否有其他任務要
*              刪除自己,如果返回 OS_TASK_DEL_REQ, 則任務 #10 完
*              成刪除自己的動作
*
*                   void Task_#10(void *data)
*                   {
*                       .
*                       .
*                       while (1) {
*                           OSTimeDly(1);
*                           if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
*                               釋放資源;
*                               釋放內存;
*                               OSTaskDel(OS_PRIO_SELF);
*                           }
*                       }
*                   }
*
* prio  : 優先級
*
* Returns    : OS_NO_ERR          成功
*              OS_TASK_NOT_EXIST  任務不存在
*              OS_TASK_DEL_IDLE   不允許刪除空閒任務
*              OS_PRIO_INVALID    優先級無效
*              OS_TASK_DEL_REQ    發出任務刪除請求
*************************************************************************************
/*$PAGE*/
#if OS_TASK_DEL_EN > 0
INT8U  OSTaskDelReq (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                      
    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;
    } else {
        err               = OS_TASK_NOT_EXIST;           /* 任務不存在       */
    }
    OS_EXIT_CRITICAL();
    return (err);
}
#endif
/*$PAGE*/
/*
***********************************************************************************
*                                        恢復掛起的任務
*
* brief : 恢復被掛起的任務
*
* prio  : 任務優先級
*
* returns    : OS_NO_ERR                成功
*              OS_PRIO_INVALID          無效優先級
*              OS_TASK_RESUME_PRIO      任務不存在
*              OS_TASK_NOT_SUSPENDED    任務沒有被掛起
***********************************************************************************
*/

#if OS_TASK_SUSPEND_EN > 0
INT8U  OSTaskResume (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3                     
    OS_CPU_SR  cpu_sr;
#endif
    OS_TCB    *ptcb;


#if OS_ARG_CHK_EN > 0
    if (prio >= OS_LOWEST_PRIO) {         /* 檢查優先級的有效性 */
        return (OS_PRIO_INVALID);
    }
#endif
    OS_ENTER_CRITICAL();
    ptcb = OSTCBPrioTbl[prio];
    if (ptcb == (OS_TCB *)0) {            /* 檢查任務是否存在   */
        OS_EXIT_CRITICAL();
        return (OS_TASK_RESUME_PRIO);
    }
    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) {/* 任務被掛起   */
        if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && /* 取消掛起狀態 */
             (ptcb->OSTCBDly  == 0)) {                       /* 不能有延時   */
            OSRdyGrp               |= ptcb->OSTCBBitY;       /* 使任務就緒   */
            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*/
/*
**********************************************************************************
*                                             堆棧檢測
*
* brief : 該函數用於檢測任務的堆棧使用情況
*
* prio  : 任務優先級
*
* pdata : 保存堆棧使用情況的數據結構指針
*
* returns : OS_NO_ERR           成功
*           OS_PRIO_INVALID     無效優先級 
*           OS_TASK_NOT_EXIST   任務不存在
*           OS_TASK_OPT_ERR     選項錯誤
***********************************************************************************
*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U  OSTaskStkChk (INT8U prio, OS_STK_DATA *pdata)
{
#if OS_CRITICAL_METHOD == 3                       
    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) { /* 檢查優先級有效性 */
        return (OS_PRIO_INVALID);
    }
#endif
    pdata->OSFree = 0;                                   /* 初始化局部變量   */
    pdata->OSUsed = 0;
    OS_ENTER_CRITICAL();
    if (prio == OS_PRIO_SELF) {                          /* 是否檢測自身堆棧 */
        prio = OSTCBCur->OSTCBPrio;
    }
    ptcb = OSTCBPrioTbl[prio];
    if (ptcb == (OS_TCB *)0) {                           /* 任務不存在 */
        OS_EXIT_CRITICAL();
        return (OS_TASK_NOT_EXIST);
    }
    if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) {   /* 檢查 OPT 的有效性 */
        OS_EXIT_CRITICAL();
        return (OS_TASK_OPT_ERR);
    }
    free = 0;
    size = ptcb->OSTCBStkSize;
    pchk = ptcb->OSTCBStkBottom;
    OS_EXIT_CRITICAL();
#if OS_STK_GROWTH == 1
    while (*pchk++ == (OS_STK)0) {                    /* 計算堆棧中 0 的數量 */
        free++;
    }
#else
    while (*pchk-- == (OS_STK)0) {
        free++;
    }
#endif
    pdata->OSFree = free * sizeof(OS_STK);            /* 計算剩餘字節數 */
    pdata->OSUsed = (size - free) * sizeof(OS_STK);   /* 計算已使用字節數 */
    return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
***********************************************************************************
*                                            掛起任務
*
* breif: 該函數用於掛起一個任務,可以使其他任務或者自身
*
* prio : 待掛起任務優先級. 如果等於 OS_PRIO_SELF,則掛起自身並進行任務調度
*
* returns :    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            
    OS_CPU_SR  cpu_sr;
#endif
    BOOLEAN    self;
    OS_TCB    *ptcb;


#if OS_ARG_CHK_EN > 0
    if (prio == OS_IDLE_PRIO) {                           /* 不允許掛起空閒任務 */
        return (OS_TASK_SUSPEND_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;
        self = TRUE;
    } else if (prio == OSTCBCur->OSTCBPrio) {             /* 掛起自身           */
        self = TRUE;
    } else {
        self = FALSE;                                     /* 非自身掛起         */
    }
    ptcb = OSTCBPrioTbl[prio];
    if (ptcb == (OS_TCB *)0) {                            /* 待掛起任務不存在   */
        OS_EXIT_CRITICAL();
        return (OS_TASK_SUSPEND_PRIO);
    }
    if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { /* 清除就緒表相應位 */
        OSRdyGrp &= ~ptcb->OSTCBBitY;
    }
    ptcb->OSTCBStat |= OS_STAT_SUSPEND;                    /* 狀態設置爲掛起態   */
    OS_EXIT_CRITICAL();
    if (self == TRUE) {                                    /* 任務調度           */
        OS_Sched();
    }
    return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
************************************************************************************
*                                            查詢任務
*
* brief: 查詢一個任務的狀態
*
* prio : 待查詢任務優先級
*
* Returns    : 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                      
    OS_CPU_SR  cpu_sr;
#endif
    OS_TCB    *ptcb;


#if OS_ARG_CHK_EN > 0
    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) {                             /* 任務不存在       */
        OS_EXIT_CRITICAL();
        return (OS_PRIO_ERR);
    }
    memcpy(pdata, ptcb, sizeof(OS_TCB));                   /* 複製 TCB 內容    */
    OS_EXIT_CRITICAL();
    return (OS_NO_ERR);
}
#endif
發佈了47 篇原創文章 · 獲贊 85 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章