聊聊基于RTOS的軟件開發(fā)理論
1.RTOS的特點(diǎn)
操作系統(tǒng)是計(jì)算機(jī)中最重要的軟件,類似管家,把不同的軟件任務(wù)安排給硬件資源去執(zhí)行。為保證服務(wù)質(zhì)量,需要對(duì)任務(wù)進(jìn)行合理安排,訪問硬件也進(jìn)行一定的安全維護(hù),保證硬件資源不閑置,不爭搶沖突,但允許合理的插隊(duì)。
RTOS的專業(yè)的描述:
- 執(zhí)行時(shí)間的可確定性是實(shí)時(shí)操作系統(tǒng)的基本特性。采用合理的算法和策略,為多個(gè)任務(wù)合理地分配資源,以滿足每個(gè)任務(wù)的實(shí)時(shí)性要求。
- 多任務(wù)搶占式是實(shí)時(shí)操作系統(tǒng)的基本特性。多個(gè)任務(wù)共同分享硬件系統(tǒng)資源,每個(gè)任務(wù)間彼此獨(dú)立,根據(jù)任務(wù)的重要程度給任務(wù)分配不同的優(yōu)先級(jí),優(yōu)先級(jí)越高的任務(wù)越容易得到 CPU 的使用權(quán),保證任務(wù)的實(shí)時(shí)性和充分地使用硬件資源。
- 對(duì)穩(wěn)定性和可靠性要求髙。
要成為老司機(jī),首先要考駕照,學(xué)習(xí)如何開車,至于汽車本身各系統(tǒng)工作原理,內(nèi)部構(gòu)造暫且不用關(guān)注;能上路,在不同路況安全駕駛。達(dá)到一定水平了再去深究車的部件組成、故障排查?;赗TOS的軟件開發(fā),不僅要明白操作系統(tǒng)接口的作用,還要理解其組合的意義。
本文是關(guān)于軟件開發(fā)的理論,作為有一定RTOS基礎(chǔ)的參考,授人以漁。對(duì)任務(wù)、公共函數(shù)、中斷服務(wù)的設(shè)計(jì),以及行為同步、資源同步、數(shù)據(jù)通信的思想和方法進(jìn)行說明,基本涵蓋RTOS軟件開發(fā)的全部理論。更多信息請(qǐng)關(guān)注微信公眾號(hào) 嵌入式系統(tǒng)。
2.任務(wù)設(shè)計(jì)
嵌入式系統(tǒng)的設(shè)計(jì)都是從需求分析開始,在軟件角度,對(duì)具體功能進(jìn)行任務(wù)劃分,是實(shí)時(shí)操作系統(tǒng)應(yīng)用軟件設(shè)計(jì)的關(guān)鍵。任務(wù)(task或thread)劃分是否合理將直接影響軟件設(shè)計(jì)的質(zhì)量、執(zhí)行效率和可擴(kuò)展性。
2.1 任務(wù)的特性
“任務(wù)”的狀態(tài)是動(dòng)態(tài)變化的,簡化就是有運(yùn)行和等待,而且阻塞等待是必須的,更多狀態(tài)可以參考操作系統(tǒng)基礎(chǔ)。多個(gè)任務(wù)宏觀上是并發(fā)運(yùn)行,其實(shí)對(duì)單CPU是分時(shí)復(fù)用,每個(gè)任務(wù)運(yùn)行時(shí)獨(dú)立的占有系統(tǒng)資,這也導(dǎo)致任務(wù)間數(shù)據(jù)傳輸?shù)漠惒叫浴?/p>
好比三口之家只有一個(gè)衛(wèi)生間,多人分時(shí)使用,不需要三人就配三個(gè)衛(wèi)生間,每人使用時(shí)完全享有衛(wèi)生間的設(shè)施,其他人有需要時(shí),得排隊(duì)或者看家庭地位強(qiáng)迫插隊(duì)。
在對(duì)一個(gè)具體的嵌入式系統(tǒng)進(jìn)行任務(wù)劃分時(shí),不同的角度有不同的方案,一般先考慮需求指標(biāo)和硬件資源限制。
- 實(shí)時(shí)性指標(biāo):在最壞的情況下,系統(tǒng)中對(duì)時(shí)間要求高的需求能否實(shí)現(xiàn)。
- 任務(wù)數(shù)目合理:任務(wù)數(shù)目多,每個(gè)任務(wù)只實(shí)現(xiàn)單一功能,任務(wù)的設(shè)計(jì)簡單;但任務(wù)的調(diào)度操作、任務(wù)之間的通信活動(dòng)增加,資源開銷大,運(yùn)行效率低。一般按功能類型、時(shí)間要求合理地合并一些任務(wù)。
- 降低資源需求:合理劃分任務(wù),減少任務(wù)之間的同步和通信需求,選擇合適的數(shù)據(jù)結(jié)構(gòu),從而降低對(duì)硬件資源的需求。
2.2 任務(wù)劃分的方法
為了使任務(wù)劃分合理,通常采用以下方法。
2.2.1 設(shè)備依賴性任務(wù)
系統(tǒng)任務(wù)必定是為了實(shí)現(xiàn)某些功能,這個(gè)功能是主動(dòng)執(zhí)行,如讀取信息、控制外設(shè),還是被動(dòng)執(zhí)行,如接收按鍵事件。
根據(jù)這個(gè)特性,任務(wù)可分為“主動(dòng)型”和“被動(dòng)型”兩種。主動(dòng)型任務(wù)與其他任務(wù)通過通信機(jī)制向該任務(wù)發(fā)出執(zhí)行請(qǐng)求執(zhí)行,被動(dòng)型任務(wù)通常是一個(gè)中斷服務(wù)程序(ISR) 和一個(gè)與之關(guān)聯(lián)的任務(wù)。在這個(gè)基礎(chǔ)上,也可以把多個(gè)同類型外設(shè)的檢測合并到一個(gè)任務(wù)。
2.2.2 關(guān)鍵任務(wù)
“關(guān)鍵性”是指某種功能在系統(tǒng)中的重要性,如果該功能異常將會(huì)產(chǎn)生嚴(yán)重后果,這種關(guān)鍵任務(wù)必須優(yōu)先得到運(yùn)行機(jī)會(huì),而且其檢測事件、消息隊(duì)列不能遺漏,特殊情況下控制時(shí)間也要及時(shí)響應(yīng)。這種任務(wù)得提高優(yōu)先級(jí)來保證運(yùn)行,而且其任務(wù)功能必須盡可能與其他功能剝離,獨(dú)立成為一個(gè)任務(wù),不能因?yàn)槿蝿?wù)里面的其他功能阻塞或者異常,影響關(guān)鍵功能的實(shí)現(xiàn)。
2.2.3 緊迫任務(wù)
“緊迫性”是指某種功能必須在規(guī)定的時(shí)間內(nèi)得到運(yùn)行權(quán)(及時(shí)運(yùn)行),這類功能有嚴(yán)格的實(shí)時(shí)性要求。大多數(shù)緊迫任務(wù)是由異步事件觸發(fā)的,這種緊迫任務(wù)安排在相應(yīng)的中斷服務(wù)中,或者優(yōu)先級(jí)盡可能髙的任務(wù)。要達(dá)到“按時(shí)完成”的目的,必須使“緊迫任務(wù)”需要的執(zhí)行時(shí)間盡可能短。盡可能剝離“不太緊迫”的操作,只剩下“必須立刻執(zhí)行”的操作,將被剝離的“不太緊迫”的操作另外封裝為一個(gè)任務(wù)。
2.2.4 數(shù)據(jù)處理任務(wù)
用戶應(yīng)用程序中消耗機(jī)時(shí)最多的一般是各種數(shù)據(jù)處理單元,而且通常不只一個(gè),它們分別為不同的功能服務(wù),這些單元?jiǎng)澐殖鰜恚謩e包裝成不同的任務(wù)。由于這類任務(wù)需要消耗較多機(jī)時(shí),所以優(yōu)先級(jí)必須較低。多個(gè)不同的數(shù)據(jù)處理任務(wù)時(shí),可安排相同的優(yōu)先級(jí),采用時(shí)間片輪轉(zhuǎn)方式運(yùn)行。
2.2.5 觸發(fā)條件相同的任務(wù)
如果若干功能由相同的事件觸發(fā),就可以將這些功能合并為一個(gè)任務(wù),從而減少事件分發(fā)給多個(gè)任務(wù)的工作量。如檢測到按鍵中斷后要進(jìn)行相應(yīng)數(shù)據(jù)處理、界面顯示、外設(shè)控制。在任務(wù)內(nèi)部,各功能的執(zhí)行順序需要盡可能按規(guī)則設(shè)定,如果各個(gè)功能之間有因果關(guān)系,則按因果關(guān)系的順序執(zhí)行;如果各個(gè)功能之間完全獨(dú)立,則按實(shí)時(shí)性要求的強(qiáng)弱順序執(zhí)行。
2.2.6 運(yùn)行周期相同的任務(wù)
對(duì)于需要重復(fù)執(zhí)行的操作,即具有周期性。這類功能組合在一起封裝為一個(gè)任務(wù),避免一個(gè)時(shí)間事件觸發(fā)多個(gè)任務(wù),省去事件分發(fā)操作與它們之間的通信。
2.2.7 順序操作任務(wù)
如果若干功能按固定順序進(jìn)行流水作業(yè),相互之間完全沒有"并發(fā)性",盡量將這些功能組合為一個(gè)任務(wù)。
2.3 任務(wù)的可調(diào)度性分析
任務(wù)劃分后,需要評(píng)估CPU占有率,以便確定這些任務(wù)是否可以在操作系統(tǒng)的調(diào)度下正常運(yùn)行。簡單的說就是計(jì)算在一定周期內(nèi),各任務(wù)運(yùn)行的最長時(shí)間長和是否小于周期,也可以粗略確認(rèn)最低優(yōu)先級(jí)的任務(wù)(待機(jī)任務(wù))是否有周期運(yùn)行的機(jī)會(huì),否則系統(tǒng)的正常運(yùn)行可能難以保證。
類似生產(chǎn)流水線,如果某個(gè)環(huán)節(jié)超時(shí),整個(gè)產(chǎn)線就沒法持續(xù)運(yùn)行。這種情況需要提高系統(tǒng)時(shí)鐘頻率或者換硬件方案,或者優(yōu)化軟件算法。
2.4 任務(wù)類型
任務(wù)設(shè)計(jì)是整個(gè)應(yīng)用程序的基礎(chǔ),按任務(wù)的執(zhí)行方式可以分為三類:單次執(zhí)行類、周期性執(zhí)行類和事件觸發(fā)類。
2.4.1 單次執(zhí)行的任務(wù)
這類任務(wù)創(chuàng)建后只執(zhí)行一次,執(zhí)行結(jié)束后即自行刪除。優(yōu)點(diǎn)一個(gè)功能運(yùn)行完了,立刻銷毀釋放資源,但也正是這樣,缺點(diǎn)也明顯,釋放不干凈,或者信號(hào)量處理不當(dāng)導(dǎo)致關(guān)聯(lián)任務(wù)永久阻塞。僅適合不與其他任務(wù)進(jìn)行通信(除ISR外)的孤立任務(wù)。
不過有些RTOS或者二次封裝,可以提供工作隊(duì)列(work queue),多個(gè)這樣的功能需求,統(tǒng)一到一個(gè)固定的任務(wù)執(zhí)行,該固定任務(wù)并不銷毀,一直存在,接收其他任務(wù)的執(zhí)行請(qǐng)求。類似共享單車,大家都是用完就還,由指定人負(fù)責(zé)維護(hù)執(zhí)行。
2.4.2 周期性執(zhí)行的任務(wù)
周期性執(zhí)行的任務(wù)創(chuàng)建一次,使用while 1永久存在,執(zhí)行任務(wù)實(shí)體后休眠,再按時(shí)喚醒或者超時(shí)觸發(fā),再運(yùn)行再休眠的循環(huán)操作。需要注意休眠時(shí)間和任務(wù)執(zhí)行時(shí)間比值越大越好,否則時(shí)間間隔會(huì)累積誤差。適用于對(duì)周期穩(wěn)定性要求不高的任務(wù),否則只能采用獨(dú)立于操作系統(tǒng)的定時(shí)中斷來觸發(fā)。
2.4.3 事件觸發(fā)執(zhí)行的任務(wù)
這類任務(wù)實(shí)體代碼的執(zhí)行需要等待某種事件的發(fā)生,在相關(guān)事件發(fā)生之前,如獲取隊(duì)列消息或信號(hào)量阻塞中,該任務(wù)被掛起等待。相關(guān)事件發(fā)生一次,該任務(wù)實(shí)體代碼就執(zhí)行一次。這種任務(wù)可以與其他任務(wù)進(jìn)行通信,也可被動(dòng)等待時(shí)間觸發(fā),一般情況下使用最多。
2.5 任務(wù)優(yōu)先級(jí)
不同RTOS任務(wù)優(yōu)先級(jí)定義的范圍和意義不同,比如有的是數(shù)值越小表示優(yōu)先級(jí)越高,有的相反;最大數(shù)值的范圍也與系統(tǒng)配置有關(guān)。任務(wù)的優(yōu)先級(jí)安排原則:
- 中斷關(guān)聯(lián)性:與中斷服務(wù)程序關(guān)聯(lián)的任務(wù)應(yīng)該安排盡可能高的優(yōu)先級(jí),以便及時(shí)處理異步事件,避免第二次中斷發(fā)生時(shí)第一次中斷還沒有處理完成,從而產(chǎn)生信號(hào)丟失現(xiàn)象。
- 緊迫性:因?yàn)榫o迫任務(wù)對(duì)響應(yīng)時(shí)間有嚴(yán)格要求,所有緊迫任務(wù)按響應(yīng)時(shí)間要求排序,越緊迫的任務(wù)安排的優(yōu)先級(jí)越高。
- 關(guān)鍵性:任務(wù)越關(guān)鍵安排的優(yōu)先級(jí)越髙,以保障其執(zhí)行機(jī)會(huì)。
- 傳遞性:信息傳遞的上游任務(wù)的優(yōu)先級(jí)高于下游任務(wù)的優(yōu)先級(jí),如信號(hào)采集任務(wù)的優(yōu)先級(jí)高于數(shù)據(jù)處理任務(wù)的優(yōu)先級(jí)。
- 快捷性:在前面各項(xiàng)條件相近時(shí),耗時(shí)短的任務(wù)安排的優(yōu)先級(jí)越高。
3.公共函數(shù)的設(shè)計(jì)
基于RTOS系統(tǒng)的全局公共函數(shù),需要考慮多任務(wù)訪問的沖突。好比你在家如廁,使用私有資源隨心所欲;出門在外上公廁,使用共享資源就得遵守一定規(guī)則。如果某個(gè)任務(wù)調(diào)用某個(gè)公共函數(shù)時(shí),被另一個(gè)髙優(yōu)先級(jí)的任務(wù)搶占,且高優(yōu)先級(jí)任務(wù)也要調(diào)用該公共函數(shù),為防止破壞原任務(wù)的數(shù)據(jù),確保這段代碼即使在多個(gè)任務(wù)同時(shí)且多次調(diào)用,運(yùn)行結(jié)果表現(xiàn)都是一樣,就必須按一定規(guī)則限制訪問,一般采用兩種措施,互斥調(diào)用和可重入設(shè)計(jì)。
3.1 互斥調(diào)用
將公共函數(shù)作為一種共享資源看待,以互斥方式調(diào)用公共函數(shù)。如果公共函數(shù)比較簡單,運(yùn)行時(shí)間很短,則可采用先關(guān)中斷( 或關(guān)調(diào)度) 再調(diào)用公共函數(shù),調(diào)用結(jié)束后再開中斷(或開調(diào)度),從而避免其他任務(wù)打擾。如果公共函數(shù)比較復(fù)雜,運(yùn)行時(shí)間較長,以上方案嚴(yán)重影響系統(tǒng)的實(shí)時(shí)性,最好為這個(gè)公共函數(shù)配備一個(gè)互斥信號(hào)量,任何任務(wù)在調(diào)用這個(gè)公共函數(shù)前必須首先取得對(duì)應(yīng)的互斥信號(hào)量,否則就會(huì)被掛起。
3.2 可重入設(shè)計(jì)
可重入函數(shù)允許多個(gè)任務(wù)嵌套調(diào)用,各任務(wù)的數(shù)據(jù)相互獨(dú)立,互不干擾,這種方式比采用互斥調(diào)用更直接。
將公共函數(shù)設(shè)計(jì)成為可重入函數(shù)的關(guān)鍵是不使用全局資源(如全局變量),只能使用臨時(shí)的局部變量,局部變量是調(diào)用時(shí)臨時(shí)分配儲(chǔ)存空間,所以不同的任務(wù)在不同時(shí)刻調(diào)用該函數(shù)時(shí),同一個(gè)局部變量分配的存儲(chǔ)空間是不重疊的,互不干擾??芍厝牒瘮?shù)調(diào)用的其他函數(shù)也必須是可重入的。
3.3 運(yùn)行效率
為保證運(yùn)行效率和實(shí)時(shí)性要求,函數(shù)盡量不要使用輪詢等待機(jī)制,可使用任務(wù)休眠等待。
4.中斷服務(wù)程序的設(shè)計(jì)
中斷服務(wù)程序(ISR ) 是嵌入式應(yīng)用系統(tǒng)獲取各種事件的基本手段,ISR的設(shè)計(jì)質(zhì)量直接影響到系統(tǒng)的實(shí)時(shí)性指標(biāo)和工作效率。
4.1 中斷優(yōu)先級(jí)
為不同的中斷服務(wù)程序安排不同的優(yōu)先級(jí),在允許中斷嵌套的情況下,高優(yōu)先級(jí)的中斷總是能夠得到及時(shí)響應(yīng)。只要沒有關(guān)閉中斷,中斷服務(wù)程序可以中斷任何任務(wù)的運(yùn)行,故可以將中斷服務(wù)程序看成比最高優(yōu)先級(jí)任務(wù)還要優(yōu)先的特殊任務(wù)(視RTOS類型和配置而定)。
4.2 中斷優(yōu)先級(jí)原則
中斷源是系統(tǒng)及時(shí)獲取異步事件的主要手段,其優(yōu)先級(jí)規(guī)則和任務(wù)比較類似,原則如下:
- 緊迫性:觸發(fā)中斷的事件允許耽誤的時(shí)間越短,設(shè)定的中斷優(yōu)先級(jí)就越高。
- 關(guān)鍵性:觸發(fā)中斷的事件越關(guān)鍵( 重要〉,設(shè)定的中斷優(yōu)先級(jí)就越高。
- 頻繁性:觸發(fā)中斷的事件發(fā)生越頻繁,設(shè)定的中斷優(yōu)先級(jí)就越高。
- 快捷性:在前三項(xiàng)條件相近時(shí),ISR 處理越快捷( 耗時(shí)短),設(shè)定的中斷優(yōu)先級(jí)就越高。
4.3 中斷與關(guān)聯(lián)任務(wù)的通信
中斷的主要功能是響應(yīng)異步事件,ISR只是觸發(fā)事件,本身不做過多處理,將獲取的異步事件通信給關(guān)聯(lián)任務(wù)處理。
ISR 與關(guān)聯(lián)任務(wù)的通信方式有兩種方式,信號(hào)量和消息:當(dāng)使用信號(hào)量進(jìn)行通信時(shí),ISR 只發(fā)送信號(hào)量,表示事件發(fā)生,通過信號(hào)量的同步功能觸發(fā)關(guān)聯(lián)任務(wù),所有具體工作均由關(guān)聯(lián)任務(wù)完成。當(dāng)使用數(shù)據(jù)消息進(jìn)行通信時(shí),ISR 需要完成對(duì)異步事件的信息采集,然后使用消息郵箱(或消息隊(duì)列) 將數(shù)據(jù)發(fā)送給關(guān)聯(lián)任務(wù),由關(guān)聯(lián)任務(wù)完成后續(xù)數(shù)據(jù)處理工作。
哪種方式更合適,需根據(jù)實(shí)際情況而定:
觸發(fā) ISR 的亊件不包含數(shù)據(jù):不需要對(duì)事件進(jìn)行數(shù)據(jù)處理,僅僅是一個(gè)特殊標(biāo)記,這種情況 ISR 使用信號(hào)量與關(guān)聯(lián)任務(wù)進(jìn)行通信。
觸發(fā) ISR 的事件是包含數(shù)據(jù)的低頻事件:將數(shù)據(jù)采集的工作放在關(guān)聯(lián)任務(wù)中完成,產(chǎn)生的時(shí)刻延誤與采樣周期相比可以忽略不計(jì),這種情況下,ISR 使用信號(hào)量與關(guān)聯(lián)任務(wù)進(jìn)行通信,從而簡化了ISR。
觸發(fā) ISR 的事件是包含數(shù)據(jù)的中髙頻事件:數(shù)據(jù)采集的工作放在關(guān)聯(lián)任務(wù)中完成,可能因?yàn)闀r(shí)刻延誤對(duì)采樣數(shù)據(jù)的質(zhì)量有影響,在這種情況下,數(shù)據(jù)采集的工作應(yīng)該放在 ISR 中完成,再使用消息郵箱(或消息隊(duì)列)與關(guān)聯(lián)任務(wù)進(jìn)行通信,關(guān)聯(lián)任務(wù)從消息郵箱(或消息隊(duì)列)中得到消息的數(shù)據(jù),并完成后續(xù)處理。
觸發(fā) ISR 的事件是包含數(shù)據(jù)的非周期“高頻”事件:對(duì)于非周期“高頻”事件,其最短事件間隔可能小于事件數(shù)據(jù)處理的耗時(shí),如果在關(guān)聯(lián)任務(wù)采集數(shù)據(jù)就可能出現(xiàn)數(shù)據(jù)丟失問題,在這種情況下,數(shù)據(jù)采集的工作應(yīng)該放在 ISR 中完成,由 ISR 使用具有數(shù)據(jù)緩沖功能的消息隊(duì)列與關(guān)聯(lián)任務(wù)進(jìn)行通信,關(guān)聯(lián)任務(wù)從消息隊(duì)列中得到消息的數(shù)據(jù),并完成后續(xù)處理工作。
有些芯片平臺(tái)的中斷服務(wù)不能使用操作系統(tǒng)接口函數(shù),不能直接發(fā)送消息或者信號(hào)量,需要進(jìn)行特殊處理。更多細(xì)節(jié)可關(guān)注微信公眾號(hào) 嵌入式系統(tǒng) ,獲取更多技能。
5.行為同步
在實(shí)時(shí)操作系統(tǒng)的支持下,系統(tǒng)的整體功能是通過各個(gè)任務(wù)( 包括 ISR )的協(xié)同運(yùn)行來實(shí)現(xiàn)的,其中運(yùn)行步驟的協(xié)調(diào)就是行為同步。
5.1 行為同步的通信方式
一個(gè)任務(wù)的運(yùn)行過程需要和其他任務(wù)的運(yùn)行配合,才能得到預(yù)定的效果,任務(wù)之間的協(xié)調(diào)關(guān)系稱為“行為同步”。行為同步的結(jié)果體現(xiàn)為任務(wù)之間的運(yùn)行按某種預(yù)定的順序來進(jìn)行。一般實(shí)時(shí)操作系統(tǒng)提供了各種的通信方式來適應(yīng)不同場合的需求,實(shí)現(xiàn)任務(wù)之間的行為同步。這里只是簡要描述,不同RTOS只是接口不同,其作用都一樣。也可以參考《FreeRTOS及其應(yīng)用,萬字長文,基礎(chǔ)入門》。
5.1 1 二值信號(hào)置
可以簡單理解為一個(gè)全局變量只能為0或者1,但其實(shí)是基于系統(tǒng)接口實(shí)現(xiàn),支持跨任務(wù)讀寫。二值信號(hào)量初始值為0,控制方發(fā)出同步信號(hào)(put/give),二值信號(hào)量的值為 1,被控制方在任務(wù)的同步點(diǎn)調(diào)用“等待一個(gè)信號(hào)量”的服務(wù)函數(shù)(get/take),如果二值信號(hào)量的值已經(jīng)為 1,就將二值信號(hào)量復(fù)位( 清零) 并繼續(xù)運(yùn)行下去;如果二值信號(hào)量的值為 0,便使自己掛起等待控制方的信號(hào)。
如果被控制方總能夠及時(shí)響應(yīng)控制方發(fā)出的信號(hào),完成相應(yīng)處理任務(wù),并在下一次信號(hào)來到之前進(jìn)入等待狀態(tài),這樣才能保證穩(wěn)定。如果被控制方獲取信號(hào)量過慢,控制方可能已經(jīng)發(fā)出多個(gè)信號(hào),導(dǎo)致信號(hào)事件被丟失。
把同步信息視為一個(gè)產(chǎn)品,控制方是產(chǎn)品的生產(chǎn)者,被控制方就是產(chǎn)品的消費(fèi)者。當(dāng)產(chǎn)品的“最短生產(chǎn)時(shí)間”比產(chǎn)品的“最長消費(fèi)時(shí)間”還長時(shí),產(chǎn)品永遠(yuǎn)是“供不應(yīng)求 ”,消費(fèi)者總是處于等待狀態(tài)”,生產(chǎn)出來的產(chǎn)品立即被消費(fèi)者取走,生產(chǎn)者和消費(fèi)者達(dá)到完全同步,生產(chǎn)一個(gè)就立即消費(fèi)一個(gè)。如果生產(chǎn)過快,消費(fèi)來不及,出現(xiàn)產(chǎn)品積壓,則表示任務(wù)可能需要調(diào)整優(yōu)先級(jí),或者說二值信號(hào)量不合適,需要使用計(jì)數(shù)信號(hào)量。
5.1.2 計(jì)數(shù)信號(hào)量
只要產(chǎn)品的平均生產(chǎn)時(shí)間比產(chǎn)品的平均消費(fèi)時(shí)間長,所有的產(chǎn)品就都會(huì)被消費(fèi)掉。但仍然有可能在某個(gè)時(shí)間段內(nèi)出現(xiàn)臨時(shí)的“產(chǎn)品積壓”。如產(chǎn)品的生產(chǎn)時(shí)間為 20-40 秒(平均30秒),產(chǎn)品的消費(fèi)時(shí)間為 10-30秒(平均 20 秒),總體上看是生產(chǎn)慢、消費(fèi)快,但在某個(gè)時(shí)間段,生產(chǎn)速度維持在高水平狀態(tài)(每20秒生產(chǎn)一個(gè)),而消費(fèi)速度偏偏維持在低水平狀態(tài)(每30秒消費(fèi)一個(gè)),這時(shí)就會(huì)臨時(shí)出現(xiàn)產(chǎn)品積壓現(xiàn)象。
二值信號(hào)量不能處理“信號(hào)積壓”現(xiàn)象,未及時(shí)響應(yīng)的信號(hào)將會(huì)被遺棄,有效響應(yīng)次數(shù)少于實(shí)際發(fā)出的信號(hào)次數(shù)。在這種情況下,采用計(jì)數(shù)信號(hào)是一個(gè)有效的選擇,在總體上能夠使控制方對(duì)被控制方進(jìn)行同步控制,在特殊情況下也不失去控制,保證每次控制信號(hào)都能夠得到響應(yīng),盡管響應(yīng)時(shí)間偶爾會(huì)有延誤。
計(jì)數(shù)信號(hào)最初始值為 0,控制方需要發(fā)出同步信號(hào)時(shí),就調(diào)用“發(fā)出一個(gè)信號(hào)量”的服務(wù)函數(shù),使計(jì)數(shù)信號(hào)量的值加 1,被控制方在任務(wù)的“同步點(diǎn)”調(diào)用“等待一個(gè)信號(hào)量”的服務(wù)函數(shù)。如果計(jì)數(shù)信號(hào)量的值不為 0,就將計(jì)數(shù)信號(hào)量減 1,并繼續(xù)運(yùn)行下去;如果計(jì)數(shù)信號(hào)量的值為0,便使自己掛起,等待控制方的信號(hào)。
計(jì)數(shù)信號(hào)量適用于被控制方不能保證在下一次信號(hào)到來之前處理完本次控制方發(fā)出的信號(hào),但總體上可以響應(yīng)所有信號(hào)。
5.1.3 事件標(biāo)志組
需要將兩個(gè)以上的信號(hào)進(jìn)行某種邏輯運(yùn)算,且用邏輯運(yùn)算結(jié)果作為同步控制信號(hào)時(shí),簡單的通信方式難以實(shí)現(xiàn),可采用“事件標(biāo)志組”來實(shí)現(xiàn),事件標(biāo)志組是若干二值信號(hào)的組合,可以實(shí)現(xiàn)多個(gè)任務(wù)(包括 ISR)協(xié)同控制一個(gè)任務(wù),當(dāng)各個(gè)相關(guān)任務(wù)(包括ISR)先后發(fā)出自己的信號(hào)后,使事件標(biāo)志組的對(duì)應(yīng)標(biāo)志有效,預(yù)定的邏輯運(yùn)算結(jié)果有效,觸發(fā)被控制的任務(wù)。
事件標(biāo)志組的使用方法很靈活,可以將標(biāo)志定義為“1 有效”,也可以將標(biāo)志定義為“0 有效”,邏輯關(guān)系可以為“邏輯與”(全部標(biāo)志均有效),也可以為“邏輯或”( 只要任何一個(gè)標(biāo)志有效)??梢院唵卫斫鉃槟硞€(gè)變量,多個(gè)控制任務(wù)共同控制變量的對(duì)應(yīng)的位,被控制任務(wù)在全部或者某一位滿足要求時(shí)觸發(fā)運(yùn)行。
5.1.4 消息郵箱
用信號(hào)量進(jìn)行行為同步時(shí),只能提供同步的時(shí)刻信息,不能提供內(nèi)容信息,當(dāng)控制方對(duì)被控制方進(jìn)行控制,需要向被控制方提供內(nèi)容信息時(shí),消息郵箱是一種有效的方案。
關(guān)于郵箱,不同的RTOS其功能定義有一定差異。大多數(shù)RTOS的郵箱不支持緩存,后面發(fā)送的會(huì)覆蓋前面;但有的類似簡化版的消息隊(duì)列,支持緩存,只是消息內(nèi)容固定為一個(gè)指針,可以多次發(fā)送;有的RTOS不支持郵箱。
5.1.5 消息隊(duì)列
消息隊(duì)列是應(yīng)用比較多,隊(duì)列可以存放多個(gè)消息,能夠有效解決消息的臨時(shí)堆積問題,但仍然需要滿足一個(gè)條件,消息的平均生產(chǎn)時(shí)間比消息的平均消費(fèi)時(shí)間長,否則,再長的消息隊(duì)列也會(huì)溢出。
特別注意,當(dāng)需要傳輸?shù)臄?shù)據(jù)量較大時(shí),傳輸其內(nèi)容指針,而不是內(nèi)容本身。
5.1.6 通信方式的選擇
以上用于行為同步的通信方式,根據(jù)實(shí)際情況來選擇:
當(dāng)同步過程不需要傳輸具體內(nèi)容時(shí),可選擇二值信號(hào)量、計(jì)數(shù)信號(hào)量和事件標(biāo)志組。
當(dāng)同步過程需要傳輸具體內(nèi)容時(shí),可選擇消息郵箱、消息隊(duì)列。
當(dāng)“任何時(shí)候同步信息的生產(chǎn)速度都比同步信息的消費(fèi)速度慢”時(shí),可選擇二值信號(hào)量 、事件標(biāo)志組。
對(duì)于非周期性同步信息,當(dāng)不能保證“任何時(shí)候同步信息的生產(chǎn)速度都比同步信息的消費(fèi)速度慢"時(shí),可選擇有緩沖功能的計(jì)數(shù)信號(hào)量、消息隊(duì)列。
當(dāng)同步信號(hào)為多個(gè)信號(hào)的邏輯運(yùn)算結(jié)果時(shí),采用事件標(biāo)志組作為同步手段
5.2 行為同步
合理安排同步點(diǎn)和任務(wù)的優(yōu)先級(jí)是獲得預(yù)期同步效果的關(guān)鍵。
5.2.1 ISR 與任務(wù)之間的同步
一個(gè)任務(wù)(或 ISR)為控制方,發(fā)出控制信息,另一個(gè)任務(wù)為被控制方,獲取控制信息后即進(jìn)入就緒狀態(tài),若優(yōu)先級(jí)足夠高就可以很快進(jìn)入運(yùn)行狀態(tài),必要時(shí)可在ISR退出前進(jìn)行一次任務(wù)切換。
一個(gè)由異步亊件觸發(fā)的ISR 通常與一個(gè)任務(wù)關(guān)聯(lián),它們之間就是單向同步關(guān)系,與ISR關(guān)聯(lián)的任務(wù)總是處于等待狀態(tài),每當(dāng)ISR發(fā)出信息就被觸發(fā),其任務(wù)結(jié)構(gòu)為事件觸發(fā)型。
5.2.2 兩個(gè)任務(wù)之間的單向同步
如果單向同步發(fā)生在兩個(gè)任務(wù)之間,同步效果與兩個(gè)任務(wù)的優(yōu)先級(jí)有關(guān)。當(dāng)控制方任務(wù)的優(yōu)先級(jí)低于被控制方任務(wù)的優(yōu)先級(jí)時(shí),控制方任務(wù)發(fā)出信息,被控制方任務(wù)進(jìn)入就緒狀態(tài),并立即發(fā)生任務(wù)切換進(jìn)人運(yùn)行狀態(tài),瞬時(shí)同步效果較好。當(dāng)控制方任務(wù)的優(yōu)先級(jí)高于被控制方任務(wù)的優(yōu)先級(jí)時(shí),控制方任務(wù)發(fā)出信息后,雖然被控制方任務(wù)進(jìn)入就緒狀態(tài),但并不發(fā)生任務(wù)切換,只有當(dāng)控制方調(diào)用系統(tǒng)服務(wù)休眠或其它使自己掛起時(shí),被控制方任務(wù)才有運(yùn)行機(jī)會(huì),瞬時(shí)同步效果較差。不過,控制方在發(fā)出信息后立即調(diào)用延時(shí)函數(shù)( 延時(shí)時(shí)間大于被控制方任務(wù)的處理時(shí)間),主動(dòng)使自己掛起來,讓低優(yōu)先級(jí)的被控制方任務(wù)盡快得到運(yùn)行機(jī)會(huì),可改善同步效果。
5.2.3 兩個(gè)任務(wù)之間的雙向同步
在單向同步過程中,必須保證消息的平均生產(chǎn)時(shí)間比消息的平均消費(fèi)時(shí)間長,否則再長的消息隊(duì)列也會(huì)溢出。如果消息的生產(chǎn)者是外部物理世界,其消息生產(chǎn)速度是客觀的,為了不遺漏消息,只能提高系統(tǒng)處理速度來應(yīng)對(duì)。
如果消息的生產(chǎn)者是系統(tǒng)內(nèi)部的某個(gè)任務(wù),則可以通過協(xié)調(diào)生產(chǎn)者與消費(fèi)者的關(guān)系來建立一個(gè)產(chǎn)銷平衡的理想狀態(tài)。通信的雙方相互制約,生產(chǎn)者通過“提供消息”來同步消費(fèi)者,消費(fèi)者通過“回復(fù)消息”來同步生產(chǎn)者,即生產(chǎn)者必須得到消費(fèi)者的回復(fù)后,才進(jìn)行下一個(gè)消息的生產(chǎn),這種運(yùn)行方式稱為“雙向同步”,這和UART串口的流控比較類似,其實(shí)現(xiàn)方式是單向同步操作的兩倍。
5.2.4 多任務(wù)同步一個(gè)任務(wù)
當(dāng)需要兩個(gè)以上任務(wù)同步一個(gè)任務(wù)時(shí),簡單的通信方式難以實(shí)現(xiàn),可采用“事件標(biāo)志組”來實(shí)現(xiàn)。只要被同步任務(wù)的執(zhí)行速度足夠快,其執(zhí)行次數(shù)就可以“等于”各個(gè)同步任務(wù)發(fā)出信號(hào)次數(shù)的總和,否則也會(huì)遺漏個(gè)別消息。
5.2.5 多個(gè)任務(wù)相互同步
多個(gè)任務(wù)的運(yùn)行頻度保持一致,即一組關(guān)聯(lián)任務(wù)在特定點(diǎn)互相等待,每個(gè)相關(guān)任務(wù)在運(yùn)行到同步點(diǎn)時(shí)都必須等待其他任務(wù),只有相關(guān)任務(wù)都到達(dá)同步點(diǎn),才可以按優(yōu)先級(jí)順序依次離開同步點(diǎn),從而達(dá)到相關(guān)任務(wù)的運(yùn)行頻度保持一致的目的。類似一組人各自獨(dú)立的到達(dá)指定集合點(diǎn),都到齊統(tǒng)一簽到,再各回各家。
多個(gè)任務(wù)相互同步,理論上事件標(biāo)志組可用來實(shí)現(xiàn)多任務(wù)相互同步,每個(gè)相關(guān)任務(wù)運(yùn)行到同步點(diǎn)時(shí)都要“簽到”,即調(diào)用“發(fā)送標(biāo)志函數(shù)”將對(duì)應(yīng)標(biāo)志置位;然后調(diào)用“獲取標(biāo)志組標(biāo)志函數(shù)”進(jìn)入等待狀態(tài),當(dāng)最后一個(gè)相關(guān)任務(wù)運(yùn)行到同步點(diǎn)并“簽到”時(shí),通過邏輯運(yùn)算產(chǎn)生“全部到齊”的信號(hào)(多任務(wù)同步標(biāo)志),并將這個(gè)同步信號(hào)分發(fā)給各個(gè)相關(guān)任務(wù)( 進(jìn)入就緒狀態(tài))后,相關(guān)任務(wù)按優(yōu)先級(jí)次序先后運(yùn)行。但是,因?yàn)楦鱾€(gè)任務(wù)的運(yùn)行情況是動(dòng)態(tài)變化的,每個(gè)任務(wù)都有可能最后一個(gè)到達(dá)同步點(diǎn),只使用事件標(biāo)志組無法判斷在最后一個(gè)到達(dá)同步點(diǎn)的任務(wù)清除標(biāo)志,導(dǎo)致后續(xù)會(huì)不斷誤觸發(fā)。
其實(shí)使用最簡單的全局變量,記錄當(dāng)前已經(jīng)到達(dá)同步點(diǎn)任務(wù)的數(shù)量,這樣數(shù)值累加到一定程度,即可判斷出最后一個(gè)到達(dá)同步點(diǎn)的任務(wù),每個(gè)任務(wù)再同步點(diǎn)判斷計(jì)數(shù)值,再將同步信號(hào)分發(fā)給各個(gè)相關(guān)任務(wù)。這個(gè)全局變量在多個(gè)任務(wù)操作,也需進(jìn)行特殊處理,也就是下一章的資源同步。
6.資源同步
被兩個(gè)以上并發(fā)程序單元(任務(wù)或1SR )訪問的資源稱為共享資源,共享資源一定是全局資源。但全局資源不一定都是共享資源,固定只被一個(gè)任務(wù)(或 ISR ) 使用的全局資源并不是共享資源,而是這個(gè)任務(wù)( 或 ISR )的私有資源,對(duì)私有資源的讀寫操作是不受限制的。
任務(wù)對(duì)共享資源進(jìn)行訪問的代碼段落稱為關(guān)鍵段落,各個(gè)任務(wù)訪問同一共享資源的關(guān)鍵段落必須互斥,才能保障共享資源信息的可靠性和完整性。這種使得不同任務(wù)訪問共享資源時(shí)能夠確保共享資源信息可靠和完整的措施稱為資源同步。
資源同步有關(guān)中斷、關(guān)調(diào)度、使用互斥信號(hào)量、使用計(jì)數(shù)信號(hào)量幾種方法,它們都能夠在訪問共享資源時(shí),保障共享資源信息的可靠性和完整性。
并不是訪問所有共享資源都要采取資源同步措施,如共享資源具有“只讀”特性,其信息只能讀出,不能改寫。這類共享資源具有天然的完整性和可靠性,各個(gè)任務(wù)可以任意讀取,如系統(tǒng)內(nèi)固化的硬件參數(shù)信息。需要采取資源同步措施進(jìn)行訪問的必定是動(dòng)態(tài)共享資源,至少存一個(gè)任務(wù)( 或ISR)可以對(duì)其進(jìn)行“寫”操作。
6.1 關(guān)中斷
一個(gè)任務(wù)在對(duì)共享資源進(jìn)行訪問前將中斷關(guān)閉,然后執(zhí)行訪問共享資源的關(guān)鍵段落代碼,操作結(jié)束后再打開中斷。
當(dāng)中斷被關(guān)閉后,系統(tǒng)失去了對(duì)所有事件的反映能力,不能進(jìn)行任務(wù)切換,從而保證了對(duì)共享資源的獨(dú)占式訪問。(優(yōu)先級(jí)非常高的硬件中斷不受操作系統(tǒng)關(guān)中斷控制,具體與RTOS實(shí)現(xiàn)及其配置有關(guān))
當(dāng)參與訪問共享資源的并發(fā)程序單元中包含ISR 時(shí),關(guān)中斷是任務(wù)訪問共享資源的最簡單方法,也是唯一的方法。
關(guān)中斷的優(yōu)點(diǎn)是簡單,缺點(diǎn)是影響系統(tǒng)的實(shí)時(shí)性。為了減輕對(duì)系統(tǒng)實(shí)時(shí)性的不利影響,訪問共享資源的關(guān)鍵段落代碼必須盡量簡短,絕對(duì)不允許在關(guān)鍵段落代碼中包含有可能使自己掛起的系統(tǒng)服務(wù)函數(shù),否則將使系統(tǒng)死機(jī)。
當(dāng)需要對(duì)共享資源進(jìn)行“寫”訪問時(shí),先將需要“寫入”的信息提前準(zhǔn)備好,存放在自己的局部數(shù)據(jù)結(jié)構(gòu)內(nèi),這個(gè)局部數(shù)據(jù)結(jié)構(gòu)與共享資源的被訪問部分的數(shù)據(jù)結(jié)構(gòu)相同,然后關(guān)中斷,在關(guān)鍵段落代碼中只需要完成將局部數(shù)據(jù)結(jié)構(gòu)的內(nèi)容復(fù)制到共享資源中的操作即可,復(fù)制完畢就可以開中斷;由于兩者數(shù)據(jù)結(jié)構(gòu)相同,所以執(zhí)行復(fù)制功能的關(guān)鍵段落代碼自然非常簡單、 快捷。
當(dāng)需要對(duì)共享資源進(jìn)行“讀”訪問時(shí),先準(zhǔn)備一個(gè)與共享資源被訪問部分的數(shù)據(jù)結(jié)構(gòu)相同的局部數(shù)據(jù)結(jié)構(gòu),然后關(guān)中斷,在關(guān)鍵段落代碼中只需要完成將共享資源的有關(guān)內(nèi)容復(fù)制到局部數(shù)據(jù)結(jié)構(gòu)中的操作即可,復(fù)制完就可以開中斷。退出關(guān)鍵段落代碼后,再對(duì)復(fù)制到局部數(shù)據(jù)結(jié)構(gòu)中的信息進(jìn)行相關(guān)處理。
由于關(guān)中斷直接影響系統(tǒng)的實(shí)時(shí)性,因此只能用于對(duì)簡單共享資源的短暫訪問,一般用于對(duì)全局變量或小規(guī)模全局?jǐn)?shù)據(jù)結(jié)構(gòu)的訪問。
6.2 關(guān)調(diào)度
當(dāng)共享資源比較復(fù)雜或者規(guī)模比較大時(shí),關(guān)中斷的方式不可取。如果該共享資源的使用者全部是任務(wù)( 即不包含 ISR ),就可以采用關(guān)調(diào)度的方法來訪問共享資源。
關(guān)調(diào)度的方法使操作系統(tǒng)的任務(wù)調(diào)度器停止工作,不能進(jìn)行任務(wù)切換,從而保障關(guān)鍵段落代碼的執(zhí)行不會(huì)受到其他任務(wù)的干擾。
由于關(guān)調(diào)度的方法沒有將中斷關(guān)閉,故系統(tǒng)對(duì)各種異步事件仍然可以及時(shí)響應(yīng),并使相關(guān)任務(wù)進(jìn)入就緒狀態(tài),但不會(huì)立即進(jìn)入運(yùn)行狀態(tài)。這也是關(guān)調(diào)度的缺點(diǎn),導(dǎo)致所有任務(wù)受到牽連,即使它們的優(yōu)先級(jí)足夠高并被ISR 觸發(fā)到就緒狀態(tài)也無法運(yùn)行。
在關(guān)調(diào)度期間,必須盡可能快速完成訪問共享資源的工作,以縮短關(guān)調(diào)度的時(shí)間。如果在關(guān)調(diào)度期間調(diào)用系統(tǒng)服務(wù)函數(shù)而被掛起,其他任務(wù)又不能運(yùn)行,那么系統(tǒng)將崩潰。關(guān)調(diào)度的資源同步方法優(yōu)點(diǎn)不多,缺點(diǎn)不少,盡可能不要使用。
6.3 使用互斥信號(hào)量
當(dāng)需要訪問的共享資源比較復(fù)雜,且訪問過程比較費(fèi)時(shí)時(shí),關(guān)中斷、關(guān)凋度的措施不可取,它對(duì)系統(tǒng)實(shí)時(shí)性產(chǎn)生了嚴(yán)重影響。如果該共享資源的使用者全部是任務(wù)( 即不包含 ISR),可采用互斥信號(hào)量的方法來訪問。
但使用信號(hào)量存在一定風(fēng)險(xiǎn),可能出現(xiàn)優(yōu)先級(jí)反轉(zhuǎn)現(xiàn)象(優(yōu)先級(jí)反轉(zhuǎn)是指一個(gè)低優(yōu)先級(jí)的任務(wù)持有一個(gè)高優(yōu)先級(jí)任務(wù)所需要的共享資源,高優(yōu)先任務(wù)必須等到低優(yōu)先級(jí)任務(wù)釋放資源才能訪問。如果此時(shí)有個(gè)優(yōu)先級(jí)處于兩者之間的任務(wù),并且不需要那個(gè)共享資源,則該中優(yōu)先級(jí)的任務(wù)實(shí)際運(yùn)行效果優(yōu)先級(jí)最高。如果高優(yōu)先級(jí)任務(wù)等待資源時(shí)不是阻塞等待,而是循環(huán)忙檢測,則低優(yōu)先級(jí)任務(wù)無法執(zhí)行,一直占用共享資源,造成的后果就是高優(yōu)先級(jí)任務(wù)無法獲得資源一直處于等待狀態(tài),系統(tǒng)進(jìn)入假死狀態(tài))。
解決方案有兩種,設(shè)置優(yōu)先級(jí)上限,給臨界區(qū)一個(gè)高優(yōu)先級(jí),進(jìn)入臨界區(qū)的任務(wù)都將獲得這個(gè)高優(yōu)先級(jí),其他試圖進(jìn)入臨界區(qū)的任務(wù)的優(yōu)先級(jí)都低于這個(gè)高優(yōu)先級(jí),也就不存在優(yōu)先級(jí)反轉(zhuǎn);另一個(gè)方案是優(yōu)先級(jí)繼承,當(dāng)一個(gè)高優(yōu)先級(jí)任務(wù)等待一個(gè)低優(yōu)先級(jí)任務(wù)持有的資源時(shí),低優(yōu)先級(jí)任務(wù)將暫時(shí)獲得高優(yōu)先級(jí)進(jìn)程的優(yōu)先級(jí)別,在釋放共享資源后,低優(yōu)先級(jí)任務(wù)回到原來的優(yōu)先級(jí)別。這塊不需要應(yīng)用程序關(guān)注或?qū)崿F(xiàn),因?yàn)镽TOS自帶的互斥信號(hào)量(mutex)具有處理優(yōu)先級(jí)反轉(zhuǎn)的功能,特別適合對(duì)共享資源的互斥訪問。
互斥信號(hào)量與用于行為同步的二值信號(hào)量不同,互斥信號(hào)量的初始值為 1(unlock),表示共享資源有效( 尚未被使用),一個(gè)任務(wù)需要訪問某共享資源時(shí),首先獲取該共享資源對(duì)應(yīng)的互斥信號(hào)量(lock),如果已經(jīng)被其它任務(wù)占用則等待;若獲取成功,則說明該共享資源尚未被其他任務(wù)占用,就可以對(duì)該共享資源進(jìn)行使用,使用結(jié)束后必須及時(shí)發(fā)送互斥信號(hào)量,解除對(duì)該共享資源的占用,以便供其他任務(wù)使用??梢灶惐扔谶M(jìn)公廁,必須確保門未鎖,進(jìn)入后立刻鎖門,事畢出來再開鎖,其他人才可再進(jìn)入使用。
使用互斥信號(hào)量訪問共享資源時(shí),對(duì)中斷和任務(wù)調(diào)度沒有限制,系統(tǒng)可以正常響應(yīng)各種異步事件,其他與該共享資源無關(guān)的高優(yōu)先級(jí)任務(wù)仍然可以及時(shí)運(yùn)行( 即使任務(wù)正在運(yùn)行關(guān)鍵段落代碼),因此,使用互斥信號(hào)量進(jìn)行共享資源訪問對(duì)系統(tǒng)實(shí)時(shí)性影響最小。
在使用互斥信號(hào)量進(jìn)行資源同步時(shí),任何任務(wù)一旦獲得共享資源就可以一直使用到不需要為止,其他任務(wù)優(yōu)先級(jí)再高也不能奪去使用權(quán)。其原因是獲得共享資源的任務(wù)具有臨時(shí)的高優(yōu)先級(jí)(優(yōu)先級(jí)繼承值),其他需要訪問同一個(gè)共享資源的任務(wù)均達(dá)不到這樣高的優(yōu)先級(jí)。優(yōu)先級(jí)繼承值必須高于所有需要訪問這個(gè)共享資源的任務(wù)的優(yōu)先級(jí)。
需要注意的是,優(yōu)先級(jí)繼承值不能與其他任務(wù)的優(yōu)先級(jí)相冋,必須使用一個(gè)空閑的、高于全部使用該共享資源的任務(wù)的優(yōu)先級(jí)值,初始定義優(yōu)先級(jí)時(shí)不要將任務(wù)的優(yōu)先級(jí)安排得太緊密,中間留些間隔較好。
6.4 使用計(jì)數(shù)信號(hào)量
當(dāng)同一類型共享資源有多個(gè)實(shí)體,就允許多個(gè)任務(wù)同時(shí)使用這類共享資源,但每個(gè)任務(wù)所使用的共享資源實(shí)體是不同的,即對(duì)每一個(gè)實(shí)體的使用仍然是互斥的。
在嵌入式應(yīng)用系統(tǒng)中,多個(gè)實(shí)體,比如多路ADC,多路UART,其實(shí)對(duì)應(yīng)不同的硬件資源,并不是完全相同的,不能隨意選擇性使用,也就是感覺計(jì)數(shù)信號(hào)量管理多實(shí)體共享資源沒有實(shí)際意義,對(duì)于多路ADC或UART,一般是使用多個(gè)互斥信號(hào)量或者二值信號(hào)量各自管理其中一路。
7.數(shù)據(jù)通信
系統(tǒng)運(yùn)行過程中,ISR與任務(wù)之間、 任務(wù)與任務(wù)之間必然伴隨數(shù)據(jù)通信,可根據(jù)實(shí)際情況來選擇最合適的通信方式。
7.1 全局變量
全局變量(包括全局?jǐn)?shù)組和全局結(jié)構(gòu)體)可以充當(dāng)一種共享資源,用來在任務(wù)之間傳輸數(shù)據(jù),提供數(shù)據(jù)的任務(wù)或ISR對(duì)全局變量進(jìn)行寫操作,使用數(shù)據(jù)的任務(wù)或ISR對(duì)全局變量進(jìn)行讀操作,從而實(shí)現(xiàn)了數(shù)據(jù)的的傳輸。這種情況下全局變量作為共享資源,對(duì)其進(jìn)行的訪問必須遵循資源同步的規(guī)則。
全局變量雖然可以實(shí)現(xiàn)數(shù)據(jù)傳輸,但不能實(shí)現(xiàn)行為同步,即新的數(shù)據(jù)產(chǎn)生之后并不能自動(dòng)通知相關(guān)使用者,使用者也不知道當(dāng)前數(shù)據(jù)是何時(shí)更新的,因此,全局變鼂只能用于沒有行為同步要求的任務(wù)之間,即每次產(chǎn)生的新數(shù)據(jù)不要求立即使用,甚至可以不被使用。
在沒有行為同步要求的前提下,且傳輸?shù)臄?shù)據(jù)量不大,采用全局變量并配合關(guān)中斷的資源同步措施是一種最有效的方法。
也有種特殊情況,當(dāng)對(duì)共享資源進(jìn)行寫操作的任務(wù)只有一個(gè),且其優(yōu)先級(jí)高于所有其他進(jìn) 行讀操作的任務(wù),可以在進(jìn)行寫操作時(shí)不必關(guān)中斷,因?yàn)榈蛢?yōu)先級(jí)執(zhí)行讀操作任務(wù)不可能獲取運(yùn)行權(quán),而低優(yōu)先級(jí)執(zhí)行讀操作任務(wù)必須使用關(guān)中斷措施來訪問全局變量。
7.2 內(nèi)存數(shù)據(jù)塊
若需要傳輸?shù)臄?shù)據(jù)量很大時(shí),采用內(nèi)存塊來存放數(shù)據(jù)是最合適的選擇,也就是內(nèi)存動(dòng)態(tài)管理函數(shù),操作系統(tǒng)一般會(huì)適配動(dòng)態(tài)內(nèi)存申請(qǐng)、釋放的接口,且支持重入。
如果申請(qǐng)的內(nèi)存空間地址指針作為全局變量,其用法和全局變量一樣,必須遵循資源同步的規(guī)則。實(shí)際它少獨(dú)立使用,一般情況下是用于消息隊(duì)列通信方式的內(nèi)容緩沖區(qū),將申請(qǐng)的內(nèi)存塊地址作為臨時(shí)變量,作為消息內(nèi)容的參數(shù)傳輸。
7.3 消息郵箱
當(dāng)發(fā)送的數(shù)據(jù)要求接收方及時(shí)接收和處理,在數(shù)據(jù)通信的同時(shí)發(fā)生行為同步,當(dāng)通信雙方的執(zhí)行均具有周期性(且周期相同)時(shí),消息郵箱是合適的通信工具。(前提是RTOS支持郵箱,且不帶緩存,一次只能發(fā)送一條)。
使用消息郵箱發(fā)送消息時(shí),實(shí)際上只發(fā)送指針( 消息的地址〉,不管消息本身的數(shù)據(jù)類型,發(fā)送的指針都按 void *處理,接收方得到這個(gè)消息指針后,將指針強(qiáng)制類型轉(zhuǎn)換獲取真正的消息內(nèi)容。
郵箱內(nèi)容可以直接發(fā)送常量(或者數(shù)據(jù)強(qiáng)制轉(zhuǎn)為指針類型,因?yàn)樽兞?00和指針100,本質(zhì)都是100這個(gè)數(shù)字)。如果發(fā)送的是變量的地址,務(wù)必確保變量本身不會(huì)銷毀,一般是全局變量或者靜態(tài)局部變量的地址。
7.4 消息隊(duì)列
由于消息郵箱里只能存放一條消息(部分RTOS郵箱消息功能不同,但消息隊(duì)列,所有RTOS都表現(xiàn)一致)。通信雙方至少有一方?jīng)]有固定的執(zhí)行周期,無法保證消息總能在下一個(gè)消息產(chǎn)生之前處理完畢,可能丟失消息,這種情況應(yīng)該使用具有緩沖功能的消息隊(duì)列,事實(shí)上消息隊(duì)列最常用。
隊(duì)列是一種標(biāo)準(zhǔn)線性結(jié)構(gòu),消息的發(fā)送、接收就是消息內(nèi)容的入隊(duì)或出隊(duì)。在用戶層面,發(fā)送消息就是將消息內(nèi)容放入隊(duì)列,接收消息時(shí)就是從隊(duì)列中取出一條消息。
消息內(nèi)容的結(jié)構(gòu)和消息隊(duì)列的長度由用戶自行設(shè)置,消息長度按消息積壓的最壞情況決定,太短了不保險(xiǎn),太長了浪費(fèi)內(nèi)存資源。隊(duì)列是先進(jìn)先出,但入隊(duì)時(shí)可以選擇放入隊(duì)列頭部還是尾部,對(duì)重要消息可以小范圍的實(shí)現(xiàn)優(yōu)先處理。
消息內(nèi)容的要求和消息郵箱一樣,必須確保接收消息的任務(wù)還能取出數(shù)據(jù),不能使用臨時(shí)變量;也不能使用大量數(shù)據(jù)塊,可以動(dòng)態(tài)申請(qǐng)內(nèi)存,消息傳遞的是其指針,實(shí)現(xiàn)大數(shù)據(jù)的傳輸。
8.時(shí)間管理
操作系統(tǒng)可以多任務(wù)間進(jìn)行切換,就是靠一個(gè)系統(tǒng)定時(shí)器以一定頻率中斷,為系統(tǒng)提供調(diào)度(上下文切換)實(shí)現(xiàn)任務(wù)切換。而這個(gè)定時(shí)器,就是系統(tǒng)節(jié)拍(tick),任務(wù)調(diào)度、休眠延時(shí)都是基于節(jié)拍,一個(gè)節(jié)拍對(duì)應(yīng)的時(shí)間各不相同,一般配置1-10ms。
節(jié)拍對(duì)應(yīng)時(shí)間數(shù)值越小,系統(tǒng)實(shí)時(shí)性越高,但過小則會(huì)導(dǎo)致頻繁切換任務(wù)反而影響任務(wù)執(zhí)行效率。
時(shí)間管理服務(wù)函數(shù)以系統(tǒng)節(jié)拍為處理單位,最壞的情況下誤差接近一個(gè)系統(tǒng)節(jié)拍,因此,時(shí)間管理服務(wù)函數(shù)只能用在對(duì)時(shí)間精度要求不高的場合,或者時(shí)間間隔較長的場合。