ucOS- II中設(shè)計(jì)了五種通訊機(jī)制
1. 先總結(jié)一下作為核心的事件控制機(jī)制:
1.1 數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì): 類(lèi)似于任務(wù)就緒表一樣,作者設(shè)計(jì)了等待任務(wù)表,表的作用原理和任務(wù)就緒表完全一樣,甚至共用了OSMapTbl和OSUnMapTbl這 兩個(gè)表,不用之處,任務(wù)就緒表用來(lái)查詢(xún)就緒的任務(wù)中優(yōu)先級(jí)最好的那個(gè),而等待任務(wù)表用來(lái)查詢(xún)等待事件的任務(wù)中優(yōu)先級(jí)最高的那個(gè),類(lèi)似于就緒表,設(shè)計(jì)了兩個(gè) 變量:OSEventGrp和OSEventTbl[],不同的時(shí)候這兩個(gè)變量被設(shè)計(jì)進(jìn)時(shí)間控制塊(event control block ECB)中,也就是說(shuō)對(duì)于每個(gè)事件(上述五種)都有一個(gè)等待任務(wù)表。對(duì)于ECB,還有其他三個(gè)變量:OSEventType(用來(lái)標(biāo)識(shí)是上述五種的哪一 種), OSEventCnt(信號(hào)量和互斥體會(huì)用到)和OSEventPtr(在郵箱中用來(lái)存放消息,在隊(duì)列中用來(lái)存放隊(duì)列塊的指針)。對(duì)于事件組來(lái)說(shuō),作者設(shè) 計(jì)了另一套數(shù)據(jù)結(jié)構(gòu),而沒(méi)有用到ECB。
1.2 事件控制的核心函數(shù)有四個(gè),基本上就是對(duì)等待任務(wù)表的操作,這些函數(shù)將作為上述五種通訊機(jī)制的核心功能:
1.2.1 OS_EventWaitListInit:初始化等待任務(wù)表, 很簡(jiǎn)單。
1.2.2 OS_EventTaskRdy:首先找到等待該事件的優(yōu)先級(jí)最高的任務(wù),將其從等待任務(wù)表中移走,然后更新該任務(wù)的TCB,最高根據(jù)TCB的OSTCBStat變量更新任務(wù)就緒表(如果該任務(wù)沒(méi)有等待任何事件,那么就把它加入任務(wù)就緒表)。
1.2.3 OS_EventTaskWait:首先把當(dāng)前任務(wù)從任務(wù)就緒表中移走,然后把當(dāng)前任務(wù)加進(jìn)這個(gè)事件的等待任務(wù)表。這個(gè)函數(shù)其實(shí)就是掛起當(dāng)前任務(wù)!
1.2.4 OS_EventTO:超時(shí)處理函數(shù),將當(dāng)前任務(wù)從等待任務(wù)列表中移走,并更新TCB使其進(jìn)入就緒狀態(tài),值得注意的是,它并不更新就緒任務(wù)表!?。?/div>
2. 信號(hào)量的實(shí)現(xiàn)
信號(hào)量的用途主要有三個(gè):第一, 表示一個(gè)或多個(gè)事件的發(fā)生; 第二, 表示共享資源的可用(二值信號(hào)量); 第三, 表示n個(gè)相同資源的訪(fǎng)問(wèn)(多值信號(hào)量)(這是書(shū)上的說(shuō)法,我認(rèn)為應(yīng)該表述為: 表示共享資源對(duì)n個(gè)任務(wù)的可用)。
2.1 數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì):信號(hào)量只是用到ECB,一個(gè)信號(hào)量用一個(gè)ECB表示,沒(méi)有用到其他數(shù)據(jù)結(jié)構(gòu)。其中ECB的OSEventPtr變量沒(méi)有用到,只是簡(jiǎn)單的將其設(shè)為0,因此信號(hào)量是比較簡(jiǎn)單的一個(gè)通訊機(jī)制。
2.2 核心函數(shù)主要有四個(gè):
2.2.1 OSSemCreate:創(chuàng)建一個(gè)信號(hào)量:首先從事件控制塊緩沖區(qū)中得到一個(gè)ECB,然后初始化這個(gè)ECB,對(duì)其中等待任務(wù)表的初始化用到OS_EventWaitListInit。
2.2.2 OSSemDel:銷(xiāo)毀一個(gè)信號(hào)量:有兩種情況, 第一,只有在沒(méi)有任務(wù)等待該信號(hào)量的時(shí)候才刪除;第二,不管有沒(méi)有任務(wù)等待該信號(hào)量都強(qiáng)制刪除;對(duì)于第一種情況,用OS_DEL_NO_PEND進(jìn)行標(biāo) 識(shí),這個(gè)時(shí)候,如果確實(shí)沒(méi)有任務(wù)在等待該信號(hào)量,將ECB歸還到ECB緩沖區(qū),然后返回; 如果有任務(wù)在等待該信號(hào)量,直接返回錯(cuò)誤標(biāo)識(shí),以告訴調(diào)用者刪除失敗。 對(duì)于第二種情況,用OS_DEL_ALWAYS進(jìn)行標(biāo)識(shí),首先用OS_EventTaskRdy將等待任務(wù)表中的所有任務(wù)都移走,然后將該ECB歸還到 ECB緩沖區(qū)。這個(gè)時(shí)候要做判斷如果剛剛有任務(wù)在等待該信號(hào)量(這個(gè)判斷在移走之前已經(jīng)做好),就必須重新調(diào)度:OS_Sched!所以,如果當(dāng)前任務(wù)不是優(yōu)先級(jí)最高的任務(wù),那么這個(gè)函數(shù)將會(huì)被掛起,呵呵。
2.2.3 OSSemPend:該函數(shù)可能會(huì)引起當(dāng)前任務(wù)被掛起:首先判斷該信號(hào)量是否可用,也就是ECB的OSEventCnt是否不為0,如果可用的話(huà)更新 ECB然后返回,任務(wù)繼續(xù)執(zhí)行;如果不可用,那么就更新當(dāng)前任務(wù)的TCB,然后用OS_EventTaskWait掛起任務(wù),然后重新調(diào)度。這時(shí),該函數(shù) 將可能被掛起,直到當(dāng)前任務(wù)獲得該信號(hào)量從而恢復(fù)執(zhí)行。然后該函數(shù)判斷當(dāng)前任務(wù)繼續(xù)執(zhí)行的原因,如果是超時(shí)的話(huà),調(diào)用OS_EventTO,如果是得到信 號(hào)量而返回的話(huà),更新當(dāng)前TCB,然后返回。另外,這也就是OS_EventTO不更新就緒表的原因——本身已經(jīng)在運(yùn)行了呀,呵呵。
2.2.4 OSSemPost:該函數(shù)釋放該信號(hào)量,從而可以使正在等待該信號(hào)量的任務(wù)恢復(fù)執(zhí)行: 首先判斷等待任務(wù)表中是否有任務(wù)正在等待該信號(hào)量,如果有的話(huà)就通過(guò)OS_EventTaskRdy使等待任務(wù)表中優(yōu)先級(jí)最高的任務(wù)不再等待該信號(hào)量(具 體的操作如上面所述)。接下來(lái)(不管有沒(méi)有任務(wù)正在等待該信號(hào)量)就更新ECB,其實(shí)就是將其中的變量OSEventCnt加1。
前面對(duì)信號(hào)量 做了一個(gè)簡(jiǎn)單的總結(jié),下面對(duì)互斥體,郵箱和隊(duì)列以及事件組做一個(gè)總結(jié),由于事件組沒(méi)有用到ECB,而其他的都有用到ECB,所以最后總結(jié)事件組,也就是 說(shuō),除了事件組會(huì)從一個(gè)作者專(zhuān)門(mén)設(shè)計(jì)的系統(tǒng)緩沖區(qū)申請(qǐng)用到的數(shù)據(jù)結(jié)構(gòu),其他的都會(huì)從ECB緩沖區(qū)中申請(qǐng)ECB。
3. 互斥體的實(shí)現(xiàn)
從其名字,mutual exclusion semaphore,可以看出來(lái),其實(shí)互斥體屬于信號(hào)量的一種,其實(shí)它是一個(gè)二值信號(hào)量,之所以把它單獨(dú)拿出來(lái)設(shè)計(jì),主要是為了解決任務(wù)優(yōu)先級(jí)反轉(zhuǎn)的問(wèn)題 ——當(dāng)該互斥體被一個(gè)任務(wù)占用的時(shí)候,如果有更高的優(yōu)先級(jí)任務(wù)等待該互斥體,那么將占用該互斥體的任務(wù)的優(yōu)先級(jí)提升到預(yù)先設(shè)定的那個(gè)比較高的優(yōu)先級(jí),從而 能改善優(yōu)先級(jí)反轉(zhuǎn)的問(wèn)題,但是不能完全去掉,呵呵。
3.1 數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì):
和信號(hào)量一樣,互斥體只用到ECB這一數(shù)據(jù)結(jié)構(gòu), 不同的是,由于它主要被設(shè)計(jì)用來(lái)解決優(yōu)先級(jí)反轉(zhuǎn)的問(wèn)題,每一個(gè)互斥體都會(huì)一個(gè)實(shí)現(xiàn)設(shè)定的優(yōu)先級(jí)聯(lián)系起來(lái),這個(gè)優(yōu)先級(jí)應(yīng)該盡量比較高,這樣,擁有這個(gè)互斥體 的任務(wù)將會(huì)先被處理,從而改善優(yōu)先級(jí)反轉(zhuǎn)的問(wèn)題。ECB中,OSEventType用來(lái)標(biāo)識(shí)該事件對(duì)象是個(gè)互斥體;OSEventCnt的高8位用來(lái)存放 與該互斥體關(guān)聯(lián)的優(yōu)先級(jí),而低8位存放擁有該互斥體的任務(wù)優(yōu)先級(jí);OSEventPtr存放擁有該互斥體的任務(wù)的TCB指針;剩下的等待任務(wù)表和信號(hào)量一 樣,沒(méi)任何區(qū)別。
3.2 核心函數(shù)和信號(hào)量一樣有四個(gè),但是由于每個(gè)互斥體都與一個(gè)任務(wù)優(yōu)先級(jí)聯(lián)系起來(lái),實(shí)現(xiàn)有一些復(fù)雜:
3.2.1 OSMutexCreate:創(chuàng)建一個(gè)互斥體:首先判斷該優(yōu)先級(jí)有沒(méi)有被任務(wù)占用,如果有的話(huà),創(chuàng)建失??;然后從ECB緩沖區(qū)中取一個(gè)ECB; 最后初始化得到的ECB,值得注意的是,ECB的變量OSEventCnt的高8位用來(lái)存放關(guān)聯(lián)的優(yōu)先級(jí),當(dāng)然,等待任務(wù)表還是用 OS_EventWaitListInit來(lái)初始化。
3.2.2 OSMutexDel: 刪除一個(gè)互斥體:其實(shí)現(xiàn)與信號(hào)量基本一樣,唯一的不用還是由于其關(guān)聯(lián)了一個(gè)任務(wù)優(yōu)先級(jí),刪除的時(shí)候應(yīng)該將優(yōu)先級(jí)重新標(biāo)識(shí)為可用。
3.2.3 OSMutexPend:等待一個(gè)互斥體:首先判斷是否該互斥體可用,如果可用的的話(huà)就用當(dāng)前任務(wù)的優(yōu)先級(jí)和TCB更新ECB,表明該互斥體已經(jīng)被當(dāng)前任務(wù)占用,直接返回,這種情況最簡(jiǎn)單; 如果互斥體已經(jīng)被其他任務(wù)占用:首先判斷占用該互斥體的任務(wù)的優(yōu)先級(jí)是不是比當(dāng)前任務(wù)的優(yōu)先級(jí)低,如果是的話(huà)就要做提升占用該互斥體任務(wù)優(yōu)先級(jí)的操作,這也就是互斥體的主要用途——更新就緒任務(wù)表,更新該任務(wù)TCB,更新任務(wù)優(yōu)先級(jí)標(biāo)識(shí)表OSTCBPrioTbl。剩下的處理與信號(hào)量的OSSemPend的處理完全一致:更 新當(dāng)前任務(wù)的TCB,然后用OS_EventTaskWait掛起任務(wù),然后重新調(diào)度。這時(shí),該函數(shù)將可能被掛起,直到當(dāng)前任務(wù)獲得該互斥體從而恢復(fù)執(zhí) 行。然后該函數(shù)判斷當(dāng)前任務(wù)繼續(xù)執(zhí)行的原因,如果是超時(shí)的話(huà),調(diào)用OS_EventTO,如果是得到該互斥體而返回的話(huà),更新當(dāng)前TCB,然后返回。
3.2.4 OSMutexPost:釋放一個(gè)互斥體,注意,只要占用該互斥體的任務(wù)能夠釋放該互斥體!首先檢查當(dāng)前任務(wù)是否占用該互斥體,如果不是的話(huà)直接返回錯(cuò)誤;然后判斷當(dāng)前的任務(wù)優(yōu)先級(jí)是否被提升過(guò),如果是的話(huà),就做恢復(fù)當(dāng)前任務(wù)的優(yōu)先級(jí)——更新就緒任務(wù)表,更新當(dāng)前任務(wù)TCB,更新任務(wù)優(yōu)先級(jí)標(biāo)識(shí)表OSTCBPrioTbl;接下來(lái),通過(guò)等待任務(wù)表判斷是否有任務(wù)在等待該互斥體,如果有的話(huà)通過(guò)OS_EventTaskRdy其中優(yōu)先級(jí)最高的任務(wù),然后將該互斥體標(biāo)識(shí)為這個(gè)優(yōu)先級(jí)最高的任務(wù)所占用, 如果沒(méi)有任務(wù)在等待該互斥體,就重置它。
4. 郵箱的實(shí)現(xiàn)
郵箱(mail box)主要用來(lái)從一個(gè)任務(wù)向另外一個(gè)任務(wù)發(fā)送一個(gè)消息,其實(shí)就是一個(gè)指針,因此,與信號(hào)量和互斥提稍有不同,信號(hào)量和互斥體用來(lái)同步對(duì)資源的訪(fǎng)問(wèn),而這 個(gè)資源在信號(hào)量和互斥體中是沒(méi)有體現(xiàn)的,換句話(huà)說(shuō),從信號(hào)量和互斥體的ECB中不能看出是在同步哪些資源,而郵箱的話(huà),這個(gè)資源(也就是消息)被放在 ECB中!總的說(shuō)來(lái),郵箱的實(shí)現(xiàn)相對(duì)來(lái)說(shuō)很簡(jiǎn)單!
4.1 數(shù)據(jù)機(jī)構(gòu)的設(shè)計(jì):
郵箱也只用到ECB,和信號(hào)量以及互斥體不同的是,郵箱沒(méi)有用到OSEventCnt,而是使用OSEventPtr來(lái)存放消息(指針)。其他的和信號(hào)量于互斥體相同。
4.2 核心函數(shù)也是四個(gè),與信號(hào)量和互斥體一樣:
4.2.1 OSMboxCreate:創(chuàng)建一個(gè)郵箱:實(shí)現(xiàn)很簡(jiǎn)單,首先申請(qǐng)一個(gè)ECB,然后初始化這個(gè)ECB,其中用OS_EventWaitListInit初始化等待任務(wù)表。
4.2.2 OSMboxDel:刪除一個(gè)郵箱:與信號(hào)量中OSSemDel完全相同。
4.2.3 OSMboxPend:等待一個(gè)郵箱消息:首先檢查該郵箱中是否有消息,如果有的話(huà)取出消息,然后返回; 如果郵箱中沒(méi)有消息,那么更新當(dāng)前任務(wù)TCB,并用OS_EventTaskWait掛起當(dāng)前任務(wù),然后重新調(diào)度:OS_Sched! 這個(gè)時(shí)候當(dāng)前任務(wù)將會(huì)被掛起,直到等待的消息來(lái)臨或者超時(shí)才得意恢復(fù)執(zhí)行,之后,它檢查郵箱中是否有消息,如果有的話(huà),取走消息,正常返回;如果郵箱中仍 然沒(méi)有消息,那么當(dāng)前任務(wù)恢復(fù)執(zhí)行是因?yàn)槌瑫r(shí),于是返回超時(shí)錯(cuò)誤!
關(guān)鍵詞:
ucOS-I通訊機(jī)
相關(guān)推薦
-
-
-
jameszxj | 2003-09-06
-
-
-
wsser | 2004-07-25
-
唐朝 | 2003-07-11
-
Gao | 2003-02-17
-
技創(chuàng)快刀 | 2004-04-29
-
-
技術(shù)專(zhuān)區(qū)
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機(jī)
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線(xiàn)
- 開(kāi)關(guān)電源
- 單片機(jī)
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩(wěn)壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開(kāi)發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機(jī)控制
- 藍(lán)牙
- PLC
- PWM
- 汽車(chē)電子
- 轉(zhuǎn)換器
- 電源管理
- 信號(hào)放大器
評(píng)論