日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OS_CORE.C(9)

發布時間:2025/3/21 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OS_CORE.C(9) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本篇介紹以下幾個函數:

OSVersion()獲得版本號函數、

OS_Dummy()虛擬函數、

OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)使任務進入就緒態的函數、

OS_EventTaskWait (OS_EVENT *pevent)使任務進入等待狀態的函數、

OS_EventTaskWaitMulti(OS_EVENT **pevents_wait)使任務進入等待狀態的函數(多任務下)、


OSVersion()獲得版本號函數:

/*$PAGE*/ /* ********************************************************************************************************* * GET VERSION * 獲得版本號 * Description: This function is used to return the version number of uC/OS-II. The returned value * corresponds to uC/OS-II's version number multiplied by 100. In other words, version 2.00 * would be returned as 200. *這個函數是返回一個uC/OS-II的版本值. 這個返回值乘100是uC/OS-II的版本號. * Arguments : none * * Returns : the version number of uC/OS-II multiplied by 100. ********************************************************************************************************* */ INT16U OSVersion(void) {return (OS_VERSION); } OS_Dummy()虛擬函數:

/*$PAGE*/ /* ********************************************************************************************************* * DUMMY FUNCTION * 虛擬函數 * Description: This function doesn't do anything. It is called by OSTaskDel(). *這個函數不做任務工作. 它是隨便訪問OSTaskDel()函數. * Arguments : none * * Returns : none ********************************************************************************************************* */#if OS_TASK_DEL_EN > 0u void OS_Dummy(void) { } #endif OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)使任務進入就緒態的 函數:

/*$PAGE*/ /* ********************************************************************************************************* * MAKE TASK READY TO RUN BASED ON EVENT OCCURING * 使一個任務進入就緒態 * Description: This function is called by other uC/OS-II services and is used to ready a task that was * waiting for an event to occur. *描述:該功能被其他oc/os-ii服務調用,用來使正在等待事件發生的任務進入就緒態。 * Arguments : pevent is a pointer to the event control block corresponding to the event. * 參數: --pevent指針指向與事件對應的事件控制塊 * pmsg is a pointer to a message. This pointer is used by message oriented services * such as MAILBOXEs and QUEUEs. The pointer is not used when called by other * service functions. * --pmsg指針指向消息,只能面向消息的服務才能使用,例如郵箱和隊列。其他的不能調用該函數。 * msk is a mask that is used to clear the status byte of the TCB. For example, * OSSemPost() will pass OS_STAT_SEM, OSMboxPost() will pass OS_STAT_MBOX etc. * --msk函數是一個掩碼,用來清除TCB的狀態字。例如,通過OSSemPost()函數清除OS_STAT_SEM;利用OSMboxPost()函數清除OS_STAT_MBOX。 * pend_stat is used to indicate the readied task's pending status: * --pend_stat用來表明已準備好的任務的掛起狀態。掛起狀態有以下兩種: * OS_STAT_PEND_OK Task ready due to a post (or delete), not a timeout or * an abort.--掛起結束(正常結束):任務已經準備好進入就緒態。 * OS_STAT_PEND_ABORT Task ready due to an abort.--取消掛起:任務被取消。 * * Returns : none * * Note : This function is INTERNAL to uC/OS-II and your application should not call it. 這個函數是uC/OS-II內部函數,你不可以在應用程序調用它,調用此函數也應當關閉中斷 ********************************************************************************************************* */ #if (OS_EVENT_EN) INT8U OS_EventTaskRdy(OS_EVENT *pevent,void *pmsg,INT8U msk,INT8U pend_stat) {OS_TCB *ptcb; /*指向TCB列表的指針*/INT8U y; /*存放字節索引*/INT8U x; /*存放任務在表中對應的具體位置*/INT8U prio; /*存放優先級(數字越小,優先級越高)*/ #if OS_LOWEST_PRIO > 63u /*如果最低優先級大于63u(超出了范圍)*/OS_PRIO *ptbl; /*設置一個專門存放超出范圍的優先級指針ptb1*/ #endif#if OS_LOWEST_PRIO <= 63u /*如果最低優先級<=63*/y = OSUnMapTbl[pevent->OSEventGrp]; /* Find HPT waiting for message首先計算HPT任務在.OSEventTbl[]中的字節索引,其結果是一個從0到OS_LOWEST_PRIO/8+1之間的數 */x = OSUnMapTbl[pevent->OSEventTbl[y]]; /*判斷HPT任務在.OSEventTbl[]中相應位的位置*/prio = (INT8U)((y << 3u) + x); /* Find priority of task getting the msg 根據以上結果計算出HPT任務的優先級*/ #else /*最低優先級>63*/if ((pevent->OSEventGrp & 0xFFu) != 0u) /*存在事件控制塊所在的組*/{ y = OSUnMapTbl[pevent->OSEventGrp & 0xFFu]; /*找到事件所在的組*/}else {y = OSUnMapTbl[(OS_PRIO)(pevent->OSEventGrp >> 8u) & 0xFFu] + 8u;/*沒有組,將y置為8(不在組內)*/}ptbl = &pevent->OSEventTbl[y]; /*ptb1指針指向上面求出的組的首地址*/if ((*ptbl & 0xFFu) != 0u) /*如果該指針指向的這一行不為0,即存在有效值*/{ x = OSUnMapTbl[*ptbl & 0xFFu]; /*得到該任務在表中相應的位置*/}else { x = OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u;/*為0,將x設為8(不在組內)*/}prio = (INT8U)((y << 4u) + x); /* Find priority of task getting the msg找到得到消息的任務的優先級*//*因為超過了63,所以此時y占了4位,所以左移4u。上面左移3u是因為y在63內,只占了3位*/ #endifptcb = OSTCBPrioTbl[prio]; /* Point to this task's OS_TCB指針指向任務的TCB*/ptcb->OSTCBDly = 0u; /* Prevent OSTimeTick() from readying task將OSTCBDly清為0*//*因為最高優先級任務運行條件已經得到滿足,必須停止OSTimeTick()函數對.OSTCBDly域的遞減操作*/ #if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u)/*如果生成隊列且隊列數>0或者生成了郵箱*/ptcb->OSTCBMsg = pmsg; /* Send message directly to waiting task直接給等待的任務發送消息*/ #elsepmsg = pmsg; /*pmsg不進行變化*//* Prevent compiler warning if not used防止編譯警告*/ #endifptcb->OSTCBStat &= (INT8U)~msk; /* Clear bit associated with event type清除與事件類型相關的位*/ptcb->OSTCBStatPend = pend_stat; /* Set pend status of post or abort設置掛起狀態*//* See if task is ready (could be susp'd)看看任務是否已經準備好了(能否被掛起)*/if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) //已經準備好了,將任務設置為就緒態{OSRdyGrp |= ptcb->OSTCBBitY; /* Put task in the ready to run list*/OSRdyTbl[y] |= ptcb->OSTCBBitX;}OS_EventTaskRemove(ptcb, pevent); /* Remove this task from event wait list從事件等待列表中刪除任務*/ #if (OS_EVENT_MULTI_EN > 0u) /*如果是多任務*/if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) /*的確存在多任務*/{ OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr);/* Remove this task from events' wait lists將該任務從事件的等待列表中移除*/ptcb->OSTCBEventPtr = (OS_EVENT *)pevent;/* Return event as first multi-pend event read返回讀到的第一個多掛起事件*/} #endifreturn (prio);//返回優先級 } #endif流程圖為:




關于這個函數中的計算優先級的方法:http://blog.sina.com.cn/s/blog_4a3946360102wlwx.html



每個任務的就緒態標志都放入就緒表中,就緒表中有兩個變量OSRdyGrp和OSRdyTbl[]。 OSRdyGrp是一個8位的變量,用來記錄哪幾列有就緒任務bit0~bit7。 OSRdyTbl[列號]用來記錄某行中那幾個位被置位。 假設有個prio為20的任務,那么填入這兩個變量的值應當這么操作:先算出OSRdyGrp中的位置20 / 8 = 2即BIT2,再算OSRdyTbl[OSRdyGrp]中的位置20 % 8 = 4即BIT4,那么看下圖可知20的位置確實在表[2][4]的位置?OSRdyGrp |= BIT2 ????OSRdyTbl[2] |=?BIT4。


OSRdyGrp和 OSRdyTbl[ OSRdyGrp]都是8個位的變量 ,這8個位可以是一個置為,也可以是多個置位,總計可以有2^8 64種數值,即0~63,那我們要找最高優先級的任務就是要找矩陣中數值最小的那個任務。這張表就是列出了0~63中為1的最小bit號,

假設bit2 bit4 bit6置為,那么這個值應當是2^6+2^4+2^2 = 84;它最小置位位應當是BIT2,這是我們看出來的,那么我把84(54h)代入第二個表查下,的確是2。這樣就能確定最高優先級任務的行列號了 我們看下面的代碼 y = OSUnMapTbl[OSRdyGrp];//確定行號 OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]);//確定列號

計算優先級的方法也顯而易見了:就緒列表或事件表中求索引號-》同一個表求相應位的位置-》計算優先級。

這個函數比較費解的,一個是求優先級的方法;一個是查表以及進行的邏輯運算。需要認真研究才可以搞懂。

OS_EventTaskWait (OS_EVENT *pevent)使任務進入等待狀態的函數:

當某個任務須等待一個事件的發生時,信號量、互斥型信號量、郵箱以及消息隊列會通過相應的PEND函數調用本函數,使當前任務從就緒任務表中脫離就緒態,并放到相應的事件控制塊ECB的等待任務表中

/*$PAGE*/ /*2018/2/7 ********************************************************************************************************* * MAKE TASK WAIT FOR EVENT TO OCCUR * 使一個任務進入等待某事件發生狀態 * Description: This function is called by other uC/OS-II services to suspend a task because an event has * not occurred. *描述:這個功能被其他uc/os-ii服務調用,當事件沒有發生時掛起該任務 * Arguments : pevent is a pointer to the event control block for which the task will be waiting for. *參數: --pevent是指向事件控制塊的指針 * Returns : none *返回值:無 * Note : This function is INTERNAL to uC/OS-II and your application should not call it. 注釋:該功能為內部功能函數,你的應用程序不能調用 ********************************************************************************************************* */ #if (OS_EVENT_EN) /*如果可以生成事件*/ void OS_EventTaskWait(OS_EVENT *pevent) /*使任務進入等待函數*/ {INT8U y;OSTCBCur->OSTCBEventPtr = pevent; /*將指向事件控制塊的指針賦給當前任務控制塊中指向事件的指針,建立任務與事件控制塊ECB之間的鏈接*/pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; /* Put task in waiting list將任務放置在等待列表中*/pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;y = OSTCBCur->OSTCBY; /* Task no longer ready任務不再為就緒態*/OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;if (OSRdyTbl[y] == 0u) /*將任務從就緒任務表中刪除*/{ OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;} } #endif


OS_EventTaskWaitMulti(OS_EVENT **pevents_wait)使任務進入等待狀態的函數(多任務下):

/*$PAGE*/ /*2018/2/7 ********************************************************************************************************* * MAKE TASK WAIT FOR ANY OF MULTIPLE EVENTS TO OCCUR * 多事件情況下的任務等待函數 * Description: This function is called by other uC/OS-II services to suspend a task because any one of * multiple events has not occurred. *描述:該功能被uc/os-ii服務調用,當多事件中的任何一個發生時,掛起任務 * Arguments : pevents_wait is a pointer to an array of event control blocks, NULL-terminated, for * which the task will be waiting for. *參數: --pevents_wait指向事件控制塊數組的指針(指針的指針)。以null結尾。 * Returns : none. *返回值:無 * Note : This function is INTERNAL to uC/OS-II and your application should not call it. 注釋:該功能為uc/os-ii內部功能,你的應用程序不能調用它。 ********************************************************************************************************* */ #if ((OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u)) /*如果可以產生事件并且多事件數量>0*/ void OS_EventTaskWaitMulti(OS_EVENT **pevents_wait) /*調用函數*/ {OS_EVENT **pevents;OS_EVENT *pevent;INT8U y;OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /*當前TCB的事件指針設置為0*/OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)pevents_wait; /*將事件等待指針賦給當前TCB中的多事件指針*/pevents = pevents_wait;pevent = *pevents;while (pevent != (OS_EVENT *)0) { /* Put task in waiting lists將任務放到等待列表中*/pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;pevents++;pevent = *pevents;}y = OSTCBCur->OSTCBY; /* Task no longer ready 此時該任務不再是就緒態 */OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;if (OSRdyTbl[y] == 0u) { /* Clear event grp bit if this was only task pending */OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;/*清除*/} } #endif OS_EventTaskRemove(OS_TCB ? *ptcb,OS_EVENT *pevent)從事件等待列表中移除任務函數:
/*$PAGE*/ /*2018/2/7 ********************************************************************************************************* * REMOVE TASK FROM EVENT WAIT LIST * 從事件等待列表中移除任務函數 * Description: Remove a task from an event's wait list. *描述:將任務從一個事件的等待列表中移除 * Arguments : ptcb is a pointer to the task to remove. *參數: --ptcb是一個指向要移除任務的指針 * pevent is a pointer to the event control block. * --pevent是一個指向事件控制塊的指針 * Returns : none *返回值:無 * Note : This function is INTERNAL to uC/OS-II and your application should not call it. 注釋:該功能為內部函數,你的應用程序不能調用。 ********************************************************************************************************* */ #if (OS_EVENT_EN) void OS_EventTaskRemove(OS_TCB *ptcb,OS_EVENT *pevent) {INT8U y;y = ptcb->OSTCBY;pevent->OSEventTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX; /* Remove task from wait list將人物從等待列表中移除*/if (pevent->OSEventTbl[y] == 0u) {pevent->OSEventGrp &= (OS_PRIO)~ptcb->OSTCBBitY;} } #endif后面這兩個函數在前面的基礎上就比較好理解了。不再贅述。

本篇博客重點還是放在兩張表的學習上。


總結

以上是生活随笔為你收集整理的OS_CORE.C(9)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。