一般看《計算機操作系統(tǒng)》的書籍,都會有進程(Process),線程(Thread)的概念。但是在嵌入式RTOS里面,比如應(yīng)用于汽車軟件的OSEK/VDX Operating System Specification 2.2.3規(guī)范里沒有這兩個概念,有的是任務(wù)(Task)。那么這三個概念是什么關(guān)系呢?本文闡述一下作者的理解。
進程的概念
進程是一個具有獨立功能的程序關(guān)于某個數(shù)據(jù)集合的一次運行活動。它可以申請和擁有系統(tǒng)資源,是系統(tǒng)進行資源分配和調(diào)度的基本單位。進程是一個動態(tài)的概念,是一個活動的實體。
“獨立功能”表示進程是面向使用者的定義,它關(guān)心的是要做什么?比如,在電腦上我要寫一篇文章,打開Word。那么計算機就會創(chuàng)建一個Microsoft Word的進程,如果我想同步寫兩篇文章,就要再打開一個Word,計算機就又創(chuàng)建一個Microsoft Word的進程。
普通的計算機機可以同步做幾件事情,比如“上網(wǎng)”,“看電影”,“打游戲”,就是說可以運行很多進程。但是嵌入式計算機通常設(shè)計成只做一件事情,比如在汽車領(lǐng)域,整車控制器VCU,發(fā)動機噴油點火控制器ECU,變速箱換擋控制器TCU,車身控制器BCM等。這樣類比,傳統(tǒng)的一個電子控制單元ECU相當于只運行一個進程。未來的XCU就是可以運行多進程的ECU
“資源分配”表示進程操作的對象,它關(guān)心的是用什么做?比如整車控制器VCU,
輸入資源:加速踏板傳感器,剎車踏板傳感器等
輸出資源:驅(qū)動水泵的PWM模塊等
通信資源:與TCU,EMS交互數(shù)據(jù)的CAN通信等。
每個具體的電氣資源都會抽象成軟件里面的一個具體對象(變量)。
“資源調(diào)度”表示進程操作對象的方法,它關(guān)心的是怎么用?調(diào)度是操作系統(tǒng)的核心,如果沒有調(diào)度,就算給ECU通電,執(zhí)行器也不能動作,就不能實現(xiàn)控制功能。
調(diào)度的過程是多樣的,怎樣調(diào)度才能最有效的利用資源是軟件設(shè)計師要考慮的問題。在所有資源中,“CPU”資源是最核心的資源。傳感器不夠了,可以擴展電路增加一個。但是在單CPU系統(tǒng)中,特別的又只有一個Core,不可能簡單的增加一個CPU,這無異于重新設(shè)計一個ECU系統(tǒng)。而在原來的CPU上增加一個Core,不是ECU開發(fā)商能做的事情。圍繞如何有效的利用“CPU資源”,引入了線程。
線程的概念
線程(英語:thread)是操作系統(tǒng)能夠進行運算調(diào)度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務(wù)。
“運算調(diào)度”,表示線程是面向運算器的,即CPU的。在這個層面上,它只關(guān)心CPU一個資源,其它的資源不考慮。
“最小單位”,表示一旦被定義為線程,就不應(yīng)該再向下分子線程了,如果可以分那么在設(shè)計程序時應(yīng)該先分。比如,某個Thread_10ms(),分析發(fā)現(xiàn)當中的某些邏輯執(zhí)行周期應(yīng)該是2ms,那么就應(yīng)該把它拆分成Thread_10ms()和Thread_2ms()
“單一順序流”,表示一個線程一旦啟動,它就應(yīng)該按順序從頭執(zhí)行完。如果中間被暫停應(yīng)該記錄暫停點,等恢復(fù)后從暫停點繼續(xù)執(zhí)行。如果恢復(fù)后沒有從暫停點繼續(xù)執(zhí)行,應(yīng)該為錯誤。
“不同的任務(wù)”,表示一個任務(wù)只能交給一個線程執(zhí)行。否則的話,會導(dǎo)致非預(yù)期的結(jié)果。比如,有一個任務(wù)Task_Printf(“Hello World”),當把它單獨掛在10ms進程里,那么屏幕上每隔10ms輸出一個“Hello World”;當把它單獨掛在2ms進程里,那么屏幕上每隔2ms輸出一個“Hello World”。但是在一個可搶占式操作系統(tǒng)里,如果把它們都掛在2個線程里,2ms任務(wù)可能會搶占10ms任務(wù)。屏幕上可能會輸出“Hello Wo Hello World rld”等奇怪的字符串。
任務(wù)的概念
筆者翻了很多資料和文章,發(fā)現(xiàn)對任務(wù)的定義可謂五花八門,例如:
百度的定義:
在多道程序或多進程環(huán)境中,要由計算機來完成的基本工作元,它是由控制程序處理的一 個或多個指令序列。
OSEK OS 2.2.3的定義:
復(fù)雜的控制軟件可以方便地細分為根據(jù)其實時性要求執(zhí)行的部件。這些部件可以通過任務(wù)來實現(xiàn)。任務(wù)提供了執(zhí)行功能的框架。操作系統(tǒng)提供任務(wù)的并發(fā)和異步執(zhí)行。調(diào)度程序組織任務(wù)執(zhí)行的順序。
μCOS-III的定義:
任務(wù)(也稱為線程)是一個簡單的程序,認為它本身具有中央處理器(CPU)。在單個CPU上,任何給定時間只能執(zhí)行一個任務(wù)。
任務(wù)看起來就像任何其他C函數(shù)一樣,除了一些小的區(qū)別。任務(wù)有兩種類型:完成運行(清單5-1)和無限循環(huán)(清單5-2)。在大多數(shù)嵌入式系統(tǒng)中,任務(wù)通常采取無限循環(huán)的形式。同樣,不允許任何任務(wù)像其他C函數(shù)一樣返回。鑒于任務(wù)是常規(guī)C函數(shù),它可以聲明局部變量。
TASKING-OS的定義:
任務(wù)是具有特定目的的半獨立程序段。大多數(shù)現(xiàn)代的實時應(yīng)用程序需要多個任務(wù)。任務(wù)提供了執(zhí)行功能的框架。RTOS提供任務(wù)的并發(fā)和異步執(zhí)行。調(diào)度程序組織任務(wù)執(zhí)行的順序,包括一種在沒有其他系統(tǒng)或應(yīng)用程序功能處于活動狀態(tài)時處于活動狀態(tài)的機制:空閑機制。
任務(wù)具有靜態(tài)優(yōu)先級,是否可以被搶占,可以或不能進入等待狀態(tài),是否是或不是優(yōu)先級的唯一所有者,依此類推。
SylixOS的定義:
總結(jié)下來,在通用計算機操作系統(tǒng)里,只強調(diào)進程和線程的概念。而在嵌入式操作系統(tǒng)里,任務(wù)就是線程的意思。怎么會這樣呢?這是因為一個嵌入式系統(tǒng)設(shè)計為只實現(xiàn)一個具體功能的是專用計算機系統(tǒng),在通用計算機系統(tǒng)只相當于一個進程。而且,通用計算機的一個進程可衍生出幾個獨立進程,好比你可以打開兩個Word文檔交互編輯。但是,一個汽車ECU不可能用軟件復(fù)制的方法控制兩臺發(fā)動機。所以,在一般的嵌入式系統(tǒng)里說進程沒有意義(智能手機等多用途設(shè)備除外)。從事嵌入式開發(fā)的很多都不是計算機專業(yè)科班出身的,大多數(shù)是電子技術(shù)專業(yè)畢業(yè),因為硬件開發(fā)需要才轉(zhuǎn)入研究嵌入式計算機系統(tǒng),而線程是計算機術(shù)語,沒有進程的襯托,一般人不好理解。而任務(wù)本身就面向人的詞語,所以在大多數(shù)嵌入式RTOS里都只講任務(wù)(Task)
然而,筆者覺得還是有必要從計算機術(shù)語的角度對這些概念加以清晰的理解。理由有兩點:
嵌入式系統(tǒng)的功能逐漸強大,越來越接近通用計算機功能,比如智能手機。在汽車電子領(lǐng)域,XCU是發(fā)展的方向,一個XCU肯定是多進程的,光定義任務(wù)不夠,還要定義它屬于發(fā)動機,或者變速箱。
任務(wù)和線程還是不一樣的。比如下面這兩句話。
老板給員工說:“你到我辦公室來一下”
老板給員工說:“你5點鐘到我辦公室來一下”
定義“到辦公室來”是任務(wù)。第一句話沒有調(diào)度的概念,就是沒有線程,什么時候“到辦公室來”沒有講(這里不附加默認是現(xiàn)在的意義),那么員工在任何時候都可以去辦公室,所以這個任務(wù)的執(zhí)行是不確定的。第二句話,增加了調(diào)度時刻“5點鐘”,那么這件事情就清晰了。從而,我們可以嚴格定義進程、線程、任務(wù)的關(guān)系。
OSEK OS的Application modes:
筆者不打算推翻嵌入RTOS的概念,當然也沒有這個必要。在面對計算機時,軟件工程師一般都清楚他要做什么,雖然表達上有差異,但不影響對內(nèi)涵的理解。就像有人喜歡叫“貓”,有人喜歡叫“咪”,都是同一個事情。注意到,在OSEK OS里有Application modes的概念
應(yīng)用程序模式旨在允許OSEK操作系統(tǒng)在不同的操作模式下運行。許多ECU可能會執(zhí)行完全獨立的應(yīng)用程序,例如工廠測試,F(xiàn)lash編程或正常運行。應(yīng)用模式是一種根據(jù)這些不同條件構(gòu)造在ECU中運行的軟件的方法,并且是開發(fā)完全獨立的系統(tǒng)的簡潔機制。通常,每種應(yīng)用程序模式都使用其自己的所有任務(wù),ISR,警報和計時條件的子集,盡管在不同模式下運行任務(wù)或ISR不受限制。如果再次需要相同的功能,建議在不同模式之間共享任務(wù)/ ISR /警報。
這看起來有點兒像“進程”的概念,前面我們說一個執(zhí)行特定功能的ECU只有一個進程,但這個只是主進程。一個只有主進程的ECU功能上還是受限制的。比如,ECU在出廠前要測試功能,執(zhí)行測試的程序肯定與正常工作的程序不一樣。舊的程序需要被更新到新的程序,此時需要切換到Boot程序里運行。這實際上就是不同的進程。只是,嵌入式軟件里的進程和通用計算機里的進程還不一樣。
通用計算機里的進程執(zhí)行到一半可以切換到另一個進程,比如打字到一半不關(guān)閉Word,而切換到看電影。在汽車里面,發(fā)動機控制器程序運行到一半暫停,跑到Boot模式,過一會兒再切回發(fā)動機控制器程序繼續(xù)運行?這個在技術(shù)上也可以做到,但是肯定不會這樣干。有幾個理由:
帶來安全問題
Boot和App程序要分配獨立RAM空間保存各自狀態(tài),浪費資源
沒有必要,從頭開始運行App程序到執(zhí)行到某個斷點也就幾十到幾百毫秒,保護現(xiàn)場的進程切換節(jié)省不了多少時間。
達不到控制目的,汽車軟件的一個程序只要運行中停止了,無論是主動的行為還是被動的異常,都會導(dǎo)致當前功能的喪失。程序必須要重新運行才能重啟功能。
第4條是最主要的功能,所以汽車軟件的進程就三個狀態(tài)。這樣就不需要進程控制塊,不需要進程棧。必須要先結(jié)束一個進程才能切換到另一個進程。
AutoSar OS的OsApplication
在AutoSarOS標準里新增加了OsApplication的概念,乍一看和OSEK OS的Application modes一樣, AUTOSAR OS必須能夠支持構(gòu)成內(nèi)聚功能單元的一系列操作系統(tǒng)對象(任務(wù),ISR,警報,計劃表,計數(shù)器)。該對象集合稱為OS應(yīng)用程序。但本質(zhì)上是不一樣的。
AutoSarOS引入OS-Application的目的是為了防止程序的錯誤傳播,引入Trusted OS-A和Non-trusted OS-A屬于功能安全的要求。Non-trusted OS-A可以訪問Trusted OS-A,反之不可。這類似于面向?qū)ο缶幊痰摹皃ublic”和“private”屬性。Private可訪問public對象,反之不可。
一個OS Application mode下面可以有很多個OS-Application, OS-Application不是運行實體。它只是定義了資源的隸屬關(guān)系,當某個調(diào)度表/任務(wù)訪問某個資源的時候,要首先判定我沒有這個權(quán)限?這個權(quán)限來自一張靜態(tài)定義的OS Application表。
與OS Application類似的是,汽車診斷規(guī)范里定義了不同的會話模式能訪問的診斷服務(wù)的權(quán)限。例如,默認會話下不能調(diào)用$27服務(wù)。但會話模式既不是一個進程,也不是一個OS Application,這個純粹是軟件設(shè)計邏輯,與用什么操作系統(tǒng)沒關(guān)系。