01
前言
前幾天和一個(gè)在某研究所的發(fā)小聊天,他說(shuō):現(xiàn)在的航空、航天和導(dǎo)彈等武器裝備中,控制系統(tǒng)幾乎都是用單片機(jī),而不是嵌入式系統(tǒng)。
乍一聽,和我們的直覺(jué)有矛盾?。耗敲锤叽笊系脑O(shè)備,其中的控制邏輯一定很復(fù)雜,不用嵌入式系統(tǒng)怎么來(lái)完成那么復(fù)雜的功能控制???然后仔細(xì)了解了一下,才明白答案是:安全+可控。
這篇文章我們就來(lái)聊一下關(guān)于單片機(jī)與嵌入式、操作系統(tǒng)與 RTOS 之間的那些事!通過(guò)這篇文章,讓你操作系統(tǒng)的實(shí)時(shí)性有一個(gè)系統(tǒng)、全面的理解!
02
關(guān)于單片機(jī)與嵌入式系統(tǒng)之間界定
說(shuō)實(shí)話,關(guān)于它倆的區(qū)分,沒(méi)有人可以給出一個(gè)標(biāo)準(zhǔn)的、正確的答案。每個(gè)人理解的單片機(jī)與嵌入式系統(tǒng),都是略有差別的。
拋開硬件,從應(yīng)用程序開發(fā)的角度來(lái)看,我是這樣來(lái)理解的:
單片機(jī):可以直接使用狀態(tài)機(jī)來(lái)實(shí)現(xiàn)程序框架,也可以利用一些 RTOS(ucOS、FreeRTOS、vxWorks、RT-Thread)等來(lái)完成一些調(diào)度功能。
嵌入式系統(tǒng):利用嵌入式 Linux 操作系統(tǒng)以及一些變種來(lái)編寫應(yīng)用程序。
我知道自己的理解可能是不對(duì)的,至少不嚴(yán)謹(jǐn)、范圍狹隘,既然沒(méi)有標(biāo)準(zhǔn)答案,那姑且引用維基百科中的定義吧,畢竟概念是死的,更重要的是我們如何根據(jù)實(shí)際的需要來(lái)進(jìn)行選擇。
1. 單片機(jī)
2. 嵌入式系統(tǒng)
- 嵌入式系統(tǒng)(Embedded System),是一種嵌入機(jī)械或電氣系統(tǒng)內(nèi)部、具有專一功能和實(shí)時(shí)計(jì)算性能的計(jì)算機(jī)系統(tǒng)。
- 嵌入式系統(tǒng)常被用于高效控制許多常見設(shè)備,被嵌入的系統(tǒng)通常是包含數(shù)字硬件和機(jī)械部件的完整設(shè)備,例如汽車的防鎖死剎車系統(tǒng)。
- 現(xiàn)代嵌入式系統(tǒng)通常是基于微控制器(如含集成內(nèi)存和/或外設(shè)接口的中央處理單元)的,但在較復(fù)雜的系統(tǒng)中普通微處理器(使用外部存儲(chǔ)芯片和外設(shè)接口電路)也很常見。
3. 嵌入式Linux
- 嵌入式Linux(英語(yǔ):Embedded Linux)是一類嵌入式操作系統(tǒng)的概稱,這類型的操作系統(tǒng)皆以Linux內(nèi)核為基礎(chǔ),被設(shè)計(jì)來(lái)使用于嵌入式設(shè)備。
- 與電腦端運(yùn)行的linux系統(tǒng)本質(zhì)上是一樣的,雖然經(jīng)過(guò)了一些功能上的裁剪,但是本質(zhì)上是一樣的,主要利用 Linux 內(nèi)核中的的任務(wù)調(diào)度、內(nèi)存管理、硬件抽象等功能。
4. RTOS
- 實(shí)時(shí)操作系統(tǒng)(RTOS),又稱即時(shí)操作系統(tǒng),它會(huì)按照排序運(yùn)行、管理系統(tǒng)資源,并為開發(fā)應(yīng)用程序提供一致的基礎(chǔ)。
- 實(shí)時(shí)操作系統(tǒng)與一般的操作系統(tǒng)相比,最大的特色就是“實(shí)時(shí)性”,如果有一個(gè)任務(wù)需要執(zhí)行,實(shí)時(shí)操作系統(tǒng)會(huì)馬上(在較短時(shí)間內(nèi))執(zhí)行該任務(wù),不會(huì)有較長(zhǎng)的延時(shí)。這種特性保證了各個(gè)任務(wù)的及時(shí)執(zhí)行。
03
非實(shí)時(shí)、軟實(shí)時(shí)、硬實(shí)時(shí)
首先要明白什么叫實(shí)時(shí)性?實(shí)時(shí)性考慮的不是速度、性能、吞吐量,而是確定性,也就是說(shuō):當(dāng)一個(gè)事件發(fā)生的時(shí)候,可以確定性的保證在多長(zhǎng)時(shí)間內(nèi)得到處理,只要能滿足這個(gè)要求,就可以成為硬實(shí)時(shí)。比如:
操作系統(tǒng)1:當(dāng)中斷發(fā)生時(shí),可以保證在 1 秒內(nèi)得到這里,那么它就是硬實(shí)時(shí)系統(tǒng),雖然響應(yīng)時(shí)間長(zhǎng),但它是確定的;
操作系統(tǒng)2:當(dāng)中斷發(fā)生時(shí),幾乎都可以在 1 毫秒內(nèi)完成,那么那就不能成為硬實(shí)系統(tǒng),雖然響應(yīng)時(shí)間短,但是它不確定。
也看到有文章說(shuō):應(yīng)該取消軟實(shí)時(shí)這個(gè)模棱兩可的說(shuō)法,要么是實(shí)時(shí),要么是非實(shí)時(shí)!
操作系統(tǒng)包含的功能很多:任務(wù)調(diào)度、內(nèi)存管理、文件管理等等,其中最核心的就是任務(wù)調(diào)度,這也是非實(shí)時(shí)、軟實(shí)時(shí)、硬實(shí)時(shí)的最大區(qū)別。
也就是說(shuō),衡量實(shí)時(shí)性的指標(biāo)就是:
1. 中斷延時(shí):一個(gè)外部事件引發(fā)的中斷發(fā)生時(shí),到相應(yīng)的中斷處理程序第一條指令被執(zhí)行時(shí),所經(jīng)過(guò)的時(shí)間;
2. 任務(wù)搶占延時(shí):當(dāng)一個(gè)高優(yōu)先級(jí)的任務(wù)準(zhǔn)備就緒時(shí),從正在執(zhí)行的低優(yōu)先級(jí)任務(wù)中搶奪 CPU 資源所經(jīng)過(guò)的時(shí)間;
不同的操作系統(tǒng),其任務(wù)調(diào)度機(jī)制也是不一樣的,而這個(gè)調(diào)度機(jī)制的策略,又是與實(shí)際的使用場(chǎng)景相關(guān)的。因此,并不存在哪個(gè)好、哪個(gè)不好這樣的說(shuō)法,合適的就是最好的!
比如:我們的桌面系統(tǒng),需要考慮的是多任務(wù)、并發(fā),需要同時(shí)執(zhí)行多個(gè)程序,哪個(gè)程序慢一點(diǎn),用戶無(wú)所謂,甚至覺(jué)察不到;但是對(duì)于一個(gè)導(dǎo)彈控制系統(tǒng),當(dāng)一個(gè)外部傳感器輸入信號(hào),觸發(fā)一個(gè)事件時(shí),對(duì)應(yīng)的處理必須立刻執(zhí)行,否則耽擱 1 毫秒,結(jié)果可能就是差之千里!
04
x86 Linux系統(tǒng)的調(diào)度策略
我們?nèi)粘J褂玫?PC 機(jī),它的主要目標(biāo)是并行執(zhí)行多任務(wù),強(qiáng)調(diào)的是吞吐率(盡可能多的執(zhí)行很多應(yīng)用程序的代碼),因此,采用的是分時(shí)操作系統(tǒng),也就是每個(gè)任務(wù)都有一個(gè)時(shí)間片,當(dāng)一個(gè)任務(wù)分配的時(shí)間片用完了,就自動(dòng)換出(調(diào)度),然后執(zhí)行下一個(gè)任務(wù)。
我們平常在寫 x86 平臺(tái)上寫普通的客戶端程序時(shí),很少需要指定應(yīng)用程序的調(diào)度策略和優(yōu)先級(jí),使用的是系統(tǒng)默認(rèn)的調(diào)度機(jī)制。反過(guò)來(lái)說(shuō),也就是在某些需要的場(chǎng)合下,是可以設(shè)置進(jìn)程的調(diào)度策略和優(yōu)先級(jí)的。
例如在 Linux 系統(tǒng)中,可以通過(guò) sched_setscheduler()
系統(tǒng)函數(shù) 設(shè)置 3 種調(diào)度策略:
1. SCHED_OTHER: 系統(tǒng)默認(rèn)的調(diào)度策略,計(jì)算動(dòng)態(tài)優(yōu)先級(jí)(counter+20-nice),當(dāng)時(shí)間片用完之后放在就緒隊(duì)列尾;
2. SCHED_FIFO: 實(shí)時(shí)調(diào)度策略,根據(jù)優(yōu)先級(jí)進(jìn)行調(diào)度,一旦占用CPU就一直執(zhí)行,直到自己放棄執(zhí)行或者有更高優(yōu)先級(jí)的任務(wù)需要執(zhí)行;
3. SCHED_RR: 也是實(shí)時(shí)調(diào)度策略,在 SCHED_FIFO 的基礎(chǔ)上添加了時(shí)間片。在執(zhí)行時(shí),可以被更高優(yōu)先級(jí)的任務(wù)打斷,如果沒(méi)有更高優(yōu)先級(jí)的任務(wù),那么當(dāng)任務(wù)的執(zhí)行時(shí)間片用完之后,就會(huì)查找相同優(yōu)先級(jí)的任務(wù)來(lái)執(zhí)行。
1. 為什么 Linux 系統(tǒng)是軟實(shí)時(shí)的?
可能有小伙伴會(huì)有疑問(wèn):既然 Linux 系統(tǒng)中提供了 SCHED_FIFO 基于優(yōu)先級(jí)的調(diào)度策略,為什么仍然不能稱之為真正的硬實(shí)時(shí)操作系統(tǒng)?這就要從 Linux 的發(fā)展歷史說(shuō)起了。
Linux 操作系統(tǒng)在設(shè)計(jì)之初,就是為了桌面應(yīng)用而開發(fā)的,在那個(gè)時(shí)代,多個(gè)終端(電傳打字機(jī)和屏幕)連接到同一個(gè)電腦主機(jī),需要處理的是多任務(wù)、并行操作,并不需要考慮實(shí)時(shí)性,因此,在 Linux 內(nèi)核中的一些基因,嚴(yán)重影響了它的實(shí)時(shí)性,例如有如下幾個(gè)因素:
(1) 內(nèi)核不可搶占
我們知道,一個(gè)應(yīng)用程序在執(zhí)行時(shí),可以在用戶態(tài)和內(nèi)核態(tài)執(zhí)行(當(dāng)調(diào)用一個(gè)系統(tǒng)函數(shù),例如:write 時(shí),就會(huì)進(jìn)入內(nèi)核態(tài)執(zhí)行),此時(shí)任務(wù)是不可搶占的。
即使有優(yōu)先級(jí)更高的任務(wù)準(zhǔn)備就緒,當(dāng)前的任務(wù)也不能立刻停止執(zhí)行。而是必須等到當(dāng)前這個(gè)任務(wù)返回到用戶態(tài),或者在內(nèi)核態(tài)中需要等待某個(gè)資源而睡眠時(shí),高優(yōu)先級(jí)任務(wù)才可以執(zhí)行。
因此,這就很顯然無(wú)法保證高優(yōu)先級(jí)任務(wù)的實(shí)時(shí)性了。
(2) 自旋鎖
自旋鎖是用于多線程同步的一種鎖,用來(lái)對(duì)共享資源的一種同步機(jī)制,線程反復(fù)檢查鎖變量是否可用。由于線程在這一過(guò)程中保持執(zhí)行,因此是一種忙等待。一旦獲取了自旋鎖,線程會(huì)一直保持該鎖,直至顯式釋放自旋鎖。
自旋鎖避免了進(jìn)程上下文的調(diào)度開銷,因此對(duì)于線程只會(huì)阻塞很短時(shí)間的場(chǎng)合是有效的,也就是說(shuō),只能在阻塞很短的時(shí)間才適合使用自旋鎖。
但是,在自旋鎖期間,任務(wù)搶占將會(huì)失效,這就是說(shuō),即使自旋鎖的阻塞時(shí)間很短,但是這仍然會(huì)增加任務(wù)搶占延時(shí),讓調(diào)度變得不確定。
(3) 中斷的優(yōu)先級(jí)是最高的
任何時(shí)刻,只要中斷發(fā)生,就會(huì)立刻執(zhí)行中斷服務(wù)程序,也就是中斷的優(yōu)先級(jí)是最高的。只有當(dāng)所有的外部中斷和軟終端都處理結(jié)束了,正常的任務(wù)才能得到執(zhí)行。
這看起來(lái)是好事情,但是想一想,如果有比中斷優(yōu)先級(jí)更高的任務(wù)呢?假如系統(tǒng)在運(yùn)行中,網(wǎng)口持續(xù)接收到數(shù)據(jù),那么中斷就一直被執(zhí)行,那么其他任務(wù)就可能一直得不到執(zhí)行的機(jī)會(huì),這是影響 Linux 系統(tǒng)實(shí)時(shí)性的巨大挑戰(zhàn)。
(4) 同步操作時(shí)關(guān)閉中斷
如果去看 Linux 內(nèi)核的代碼,可以看到在很多地方都執(zhí)行了關(guān)中斷指令,如果在這期間發(fā)生了中斷,那么中斷響應(yīng)時(shí)間就沒(méi)法保證了。
2. Linux 系統(tǒng)如何改成硬實(shí)時(shí)?
以上描述的幾個(gè)因素,對(duì) Linux 實(shí)現(xiàn)真正的實(shí)時(shí)性構(gòu)成了很大的障礙,但是現(xiàn)實(shí)世界又的確有很多場(chǎng)合需要 Linux 具有硬實(shí)時(shí),那么就要針對(duì)上面的每一個(gè)因素提出解決方案。
目前主流的解決方案有 2 個(gè):
- 單內(nèi)核解決方案:給 Linux 內(nèi)核打補(bǔ)丁,解決上面提到的幾個(gè)問(wèn)題,例如:RT-Preempt;
- 雙內(nèi)核解決方案:在硬件抽象層之上,運(yùn)行 2 個(gè)內(nèi)核:實(shí)時(shí)內(nèi)核 + Linux 內(nèi)核,它們分別向上層提供 API 函數(shù),例如:Xenomai;
這 2 種解決方案分別有不同的實(shí)現(xiàn),從調(diào)研情況來(lái)看,RT-Preempt 和 Xenomai 是使用比較多的,下面分別來(lái)看一下他們的優(yōu)缺點(diǎn)。
(1)RT-Preempt
這種方式主要是對(duì) Linux 內(nèi)核進(jìn)行打補(bǔ)丁,解決了上面所說(shuō)的幾個(gè)問(wèn)題:內(nèi)核不可搶占、自旋鎖、關(guān)中斷以及終端優(yōu)先級(jí)的問(wèn)題。
至于每一個(gè)問(wèn)題是如何解決的,由于篇幅關(guān)系,這里就不介紹了,感興趣的小伙伴如果需要的話,可以深入了解一下。
由于是直接在 Linux 內(nèi)核上打補(bǔ)丁(以后肯定會(huì)合并到主分支中的),因此對(duì)于應(yīng)用程序開發(fā)來(lái)說(shuō),操作系統(tǒng)向上層提供的 API 接口函數(shù)可以保持不變,這對(duì)應(yīng)用程序開發(fā)來(lái)說(shuō)是一件好事情。
(2)Xenomai
Xenomai是一個(gè) Linux 內(nèi)核的實(shí)時(shí)開發(fā)框架,它希望通過(guò)無(wú)縫地集成到 Linux 環(huán)境中來(lái)給用戶空間應(yīng)用程序提供全面的,與接口無(wú)關(guān)的硬實(shí)時(shí)性能。下面是 Xenomai 的架構(gòu)圖:
在硬件抽象層之上,是 2 個(gè)并列的域(內(nèi)核),這 2 個(gè)內(nèi)核分別向上層提供自己的 API 接口函數(shù)。
圖中 glibc 是 Linux 系統(tǒng)提供的庫(kù)函數(shù),應(yīng)用程序通過(guò)調(diào)用庫(kù)函數(shù)和系統(tǒng)調(diào)用來(lái)編寫程序。
Xenomai 也提供了相應(yīng)的庫(kù)函數(shù) libcobalt ,這個(gè)庫(kù)函數(shù)是需要我們?cè)谟脩魧泳幾g、安裝的,就像安裝第三方庫(kù)一樣。
此外,Xenomai 還參考不同的操作系統(tǒng)風(fēng)格,提供了好幾套 API 函數(shù)(之前的說(shuō)法是:皮膚),API 接口函數(shù)在這里:
從圖中可以看到,Alchemy API 這套接口提供的功能更完善,提供了:定時(shí)器、內(nèi)存管理、條件變量、事件、互斥鎖、消息隊(duì)列、任務(wù)(可以理解為線程)等 API 函數(shù)。這一套 API 函數(shù)中具體的功能與 POSIX 標(biāo)準(zhǔn)大體相同,在一些細(xì)節(jié)上存在一些差異。
由于 Xenomai 向應(yīng)用層提供的 API 函數(shù)是獨(dú)立的一套,因此,如果我們需要?jiǎng)?chuàng)建實(shí)時(shí)任務(wù),那么就要調(diào)用這一套接口函數(shù)來(lái)創(chuàng)建任務(wù),包括使用其中的一些資源(例如:內(nèi)存分配)。而且文檔中也提出了一些注意點(diǎn),例如:某些資源不能在 Xenomai 與 Linux 系統(tǒng)之間混用。
05
RTOS 的優(yōu)勢(shì)
上面已經(jīng)說(shuō)到,Linux 桌面系統(tǒng)的主要目標(biāo)是吞吐量,在單位時(shí)間內(nèi)執(zhí)行更多的代碼。
但是對(duì)于單片機(jī)來(lái)說(shuō),首要目標(biāo)不是吞吐量,而是確定性,因此衡量一個(gè)實(shí)時(shí)操作系統(tǒng)堅(jiān)固性的重要指標(biāo),是系統(tǒng)從接收一個(gè)任務(wù),到完成該任務(wù)所需的時(shí)間。也就是說(shuō),任務(wù)調(diào)度才是第一考量要素。
在單片機(jī)開發(fā)中,一般有 2 種編程模型:基于狀態(tài)機(jī)(裸跑),基于 RTOS。
如果基于狀態(tài)機(jī),就不存在任務(wù)調(diào)度問(wèn)題了,因?yàn)橹挥幸粋€(gè)執(zhí)行序列,所有的操作都是串行執(zhí)行的,唯一需要注意的控制流程就是中斷處理。
如果基于 RTOS,主要利用的就是任務(wù)調(diào)度,實(shí)現(xiàn)真正的硬實(shí)時(shí)。這方面最牛逼的就是VxWorks
了,當(dāng)然價(jià)格也是非??捎^的,有些公司購(gòu)買之后,甚至?xí)殉?span style="color:#FFA500;">任務(wù)調(diào)度模塊之外的其他模塊全部重寫一遍,這也足以證明了 VxWorks 在任務(wù)調(diào)度處理上的確很厲害,這也是它的看家本領(lǐng)!
當(dāng)然,對(duì)于簡(jiǎn)單、需要嚴(yán)格控制執(zhí)行序列的關(guān)鍵程序來(lái)說(shuō),使用有限狀態(tài)機(jī)的編程框架,一切都在自己的掌握中。只要代碼中沒(méi)有 bug,那么理論上,一切行為都是在控制之中的,這也是為什么很多軍事設(shè)備上使用單片機(jī)的原因!
06
總結(jié)
關(guān)于任務(wù)調(diào)度的問(wèn)題,是一個(gè)操作系統(tǒng)的重中之重,其中需要學(xué)習(xí)的內(nèi)容還有很多,最近剛買了一本陳海波老師的新書,也就是華為的鴻蒙系統(tǒng)背后的靈魂人物。
如果有新的學(xué)習(xí)心得,再跟大家分享。
-
單片機(jī)
+關(guān)注
關(guān)注
6030文章
44499瀏覽量
632171 -
嵌入式
+關(guān)注
關(guān)注
5060文章
18979瀏覽量
302235
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論