<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 淺析μC/OS-ⅡAPI的設(shè)計(jì)思想及實(shí)現(xiàn)機(jī)制

          淺析μC/OS-ⅡAPI的設(shè)計(jì)思想及實(shí)現(xiàn)機(jī)制

          作者: 時(shí)間:2012-08-24 來源:網(wǎng)絡(luò) 收藏

          void MyTask (void *pdata)

          函數(shù)參數(shù)為一指針變量,指向?qū)?yīng)任務(wù)的OS_TCB結(jié)構(gòu)地址。本函數(shù)是有用的調(diào)試工具。

          3. 消息和同步類的設(shè)計(jì)思路和

          μⅡ中有三種方法消息通信和同步:信號(hào)量、郵箱和消息隊(duì)列。一個(gè)任務(wù)或者中斷服務(wù)子程序可以通過事件控制塊ECB(Event Control Blocks)來向另外的任務(wù)發(fā)信號(hào)。這里,所有的信號(hào)都被看成是事件(Event)。這也說明為什么上面把用于通訊的數(shù)據(jù)結(jié)構(gòu)叫做事件控制塊。一個(gè)任務(wù)還可以等待另一個(gè)任務(wù)或中斷服務(wù)子程序給它發(fā)送信號(hào)。這里要注意的是,只有任務(wù)可以等待事件發(fā)生,中斷服務(wù)子程序是不能這樣做的。對(duì)于處于等待狀態(tài)的任務(wù),還可以給它指定一個(gè)最長(zhǎng)等待時(shí)間,以此來防止因?yàn)榈却氖录]有發(fā)生而無限期地等下去。多個(gè)任務(wù)可以同時(shí)等待同一個(gè)事件的發(fā)生。在這種情況下,當(dāng)該事件發(fā)生后,所有等待該事件的任務(wù)中,優(yōu)先級(jí)最高的任務(wù)得到了該事件并進(jìn)入就緒狀態(tài),準(zhǔn)備執(zhí)行。上面講到的事件,可以是信號(hào)量、郵箱或者消息隊(duì)列等。當(dāng)事件控制塊是一個(gè)信號(hào)量時(shí),任務(wù)可以等待它,也可以給它發(fā)送消息。

          μII中的信號(hào)量由兩部分組成:一個(gè)是信號(hào)量的計(jì)數(shù)值,它是一個(gè)16位的無符號(hào)整數(shù)(0 到65,535之間);另一個(gè)是由等待該信號(hào)量的任務(wù)組成的等待任務(wù)表。用戶要在OS_CFG.H中將OS_SEM_EN開關(guān)量常數(shù)置成1,這樣μII才能支持信號(hào)量。

          郵箱是μC/OS-II中另一種通訊,它可以使一個(gè)任務(wù)或者中斷服務(wù)子程序向另一個(gè)任務(wù)發(fā)送一個(gè)指針型的變量。該指針指向一個(gè)包含了特定“消息”的數(shù)據(jù)結(jié)構(gòu)。為了在μC/OS-II中使用郵箱,必須將OS_CFG.H中的OS_MBOX_EN常數(shù)置為1。

          消息隊(duì)列是μC/OS-II中另一種通訊,它可以使一個(gè)任務(wù)或者中斷服務(wù)子程序向另一個(gè)任務(wù)發(fā)送以指針方式定義的變量。因具體的應(yīng)用有所不同,每個(gè)指針指向的數(shù)據(jù)結(jié)構(gòu)變量也有所不同。為了使用μC/OS-II的消息隊(duì)列功能,需要在OS_CFG.H 文件中,將OS_Q_EN常數(shù)設(shè)置為1,并且通過常數(shù)OS_MAX_QS來決定μC/OS-II支持的最多消息隊(duì)列數(shù)。

          μC/OS-Ⅱ提供一系列函數(shù)供用戶調(diào)用,各個(gè)任務(wù)之間的通信和同步功能。下面以信號(hào)量為例說明各個(gè)的實(shí)現(xiàn)。

          μC/OS-II提供了5個(gè)對(duì)信號(hào)量進(jìn)行操作的函數(shù)。它們是:OSSemCreate(),OSSemPend(),OSSemPost(),OSSemAccept()和OSSemQuery()函數(shù)。圖 F6.5說明了任務(wù)、中斷服務(wù)子程序和信號(hào)量之間的關(guān)系。圖中用鑰匙或者旗幟的符號(hào)來表示信號(hào)量:如果信號(hào)量用于對(duì)共享資源的訪問,那么信號(hào)量就用鑰匙符號(hào)。符號(hào)旁邊的數(shù)字N代表可用資源數(shù)。對(duì)于二值信號(hào)量,該值就是1;如果信號(hào)量用于表示某事件的發(fā)生,那么就用旗幟符號(hào)。這時(shí)的數(shù)字N代表事件已經(jīng)發(fā)生的次數(shù)。從圖 F6.5中可以看出OSSemPost()函數(shù)可以由任務(wù)或者中斷服務(wù)子程序調(diào)用,而OSSemPend()和OSSemQuery()函數(shù)只能有任務(wù)程序調(diào)用。

          3.1建立一個(gè)信號(hào)量, OSSemCreate()

          OS_EVENT *OSSemCreate (INT16U cnt)

          函數(shù)參數(shù)傳遞的是要?jiǎng)?chuàng)建的信號(hào)量的初始值,在函數(shù)內(nèi)部對(duì)任務(wù)控制塊進(jìn)行初始化。OSSemCreate()返回給調(diào)用函數(shù)一個(gè)指向任務(wù)控制塊的指針。以后對(duì)信號(hào)量的所有操作,如OSSemPend(), OSSemPost(), OSSemAccept()和OSSemQuery()都是通過該指針完成的。因此,這個(gè)指針實(shí)際上就是該信號(hào)量的句柄。如果系統(tǒng)中沒有可用的任務(wù)控制塊,OSSemCreate()將返回一個(gè)NULL指針。

          值得注意的是,在μC/OS-II中,信號(hào)量一旦建立就不能刪除了,因此也就不可能將一個(gè)已分配的任務(wù)控制塊再放回到空閑ECB鏈表中。如果有任務(wù)正在等待某個(gè)信號(hào)量,或者某任務(wù)的運(yùn)行依賴于某信號(hào)量的出現(xiàn)時(shí),刪除該任務(wù)是很危險(xiǎn)的。

          3.2等待一個(gè)信號(hào)量, OSSemPend()

          void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)

          它首先檢查指針pevent所指的任務(wù)控制塊是否是由OSSemCreate()建立的。如果信號(hào)量當(dāng)前是可用的(信號(hào)量的計(jì)數(shù)值大于0),將信號(hào)量的計(jì)數(shù)值減1,然后函數(shù)將“無錯(cuò)”錯(cuò)誤代碼返回給它的調(diào)用函數(shù)。顯然,如果正在等待信號(hào)量,這時(shí)的輸出正是我們所希望的,也是運(yùn)行OSSemPend()函數(shù)最快的路徑。

          3.3發(fā)送一個(gè)信號(hào)量, OSSemPost()

          INT8U OSSemPost (OS_EVENT *pevent)

          它首先檢查參數(shù)指針pevent指向的任務(wù)控制塊是否是OSSemCreate()函數(shù)建立的,接著檢查是否有任務(wù)在等待該信號(hào)量。如果該任務(wù)控制塊中的.OSEventGrp域不是0,說明有任務(wù)正在等待該信號(hào)量。這時(shí),就要調(diào)用函數(shù)OSEventTaskRdy(),使一個(gè)任務(wù)進(jìn)入就緒狀態(tài),把其中的最高優(yōu)先級(jí)任務(wù)從等待任務(wù)列表中刪除并使它進(jìn)入就緒狀態(tài)。然后,調(diào)用OSSched()任務(wù)調(diào)度函數(shù)檢查該任務(wù)是否是系統(tǒng)中的最高優(yōu)先級(jí)的就緒任務(wù)。如果是,這時(shí)就要進(jìn)行任務(wù)切換[當(dāng)OSSemPost()函數(shù)是在任務(wù)中調(diào)用的],準(zhǔn)備執(zhí)行該就緒任務(wù)。如果不是,OSSched()直接返回,調(diào)用OSSemPost()的任務(wù)得以繼續(xù)執(zhí)行。如果這時(shí)沒有任務(wù)在等待該信號(hào)量,該信號(hào)量的計(jì)數(shù)值就簡(jiǎn)單地加1。

          上面是由任務(wù)調(diào)用OSSemPost()時(shí)的情況。當(dāng)中斷服務(wù)子程序調(diào)用該函數(shù)時(shí),不會(huì)發(fā)生上面的任務(wù)切換。如果需要,任務(wù)切換要等到中斷嵌套的最外層中斷服務(wù)子程序調(diào)用OSIntExit()函數(shù)后才能進(jìn)行。

          3.4無等待地請(qǐng)求一個(gè)信號(hào)量, OSSemAccept()

          INT16U OSSemAccept (OS_EVENT *pevent)

          當(dāng)一個(gè)任務(wù)請(qǐng)求一個(gè)信號(hào)量時(shí),如果該信號(hào)量暫時(shí)無效,也可以讓該任務(wù)簡(jiǎn)單地返回,而不是進(jìn)入睡眠等待狀態(tài)。這種情況下的操作是由OSSemAccept()函數(shù)完成的。該函數(shù)在最開始也是檢查參數(shù)指針pevent指向的事件控制塊是否是由OSSemCreate()函數(shù)建立的,接著從該信號(hào)量的事件控制塊中取出當(dāng)前計(jì)數(shù)值,并檢查該信號(hào)量是否有效(計(jì)數(shù)值是否為非0值)。如果有效,則將信號(hào)量的計(jì)數(shù)值減1,然后將信號(hào)量的原有計(jì)數(shù)值返回給調(diào)用函數(shù)。調(diào)用函數(shù)需要對(duì)該返回值進(jìn)行檢查。如果該值是0,說明該信號(hào)量無效。如果該值大于0,說明該信號(hào)量有效,同時(shí)該值也暗示著該信號(hào)量當(dāng)前可用的資源數(shù)。應(yīng)該注意的是,這些可用資源中,已經(jīng)被該調(diào)用函數(shù)自身占用了一個(gè)(該計(jì)數(shù)值已經(jīng)被減1)。中斷服務(wù)子程序要請(qǐng)求信號(hào)量時(shí),只能用OSSemAccept()而不能用OSSemPend(),因?yàn)橹袛喾?wù)子程序是不允許等待的。



          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();