一、任務的定義
在嵌入式開發中,面對的都是單個 CPU 的情況,而在這個開發過程中,我們會涉及到裸機開發或者是跑操作系統的開發,在裸機開發的過程中,整個系統是以模塊的角度來看的,也就是系統在運行完了這個模塊之后,再去運行另外一個模塊。
但是,在有操作系統的情況下,我們是把系統處理的一件一件事情以任務的角度來進行劃分的,這任務與任務之間是并發執行的。每個任務的運行看起來是獨立的,從宏觀的角度看是多個任務同時在占據著 CPU 的執行,就像是多 CPU 一樣,在真正的多 CPU 系統中,每個 CPU 都有一套自己的寄存器,而為了實現這樣一種多 CPU 運行的機制,那么操作系統就為每個任務用一塊專用的存儲空間構建了一個“虛擬 CPU”,用來保存 CPU 內存各個寄存器的信息,這塊專用的存儲器空間就是“任務堆棧”,有多少個任務就會有多少個任務堆棧。
操作系統為了能夠有效地在各個任務之間進行切換,也就是任務之間的調度,那么就必須掌握各個任務的詳細動態信息。為此,操作系統為每個任務建立了檔案,用來記錄任務的這些信息,這就是“任務控制塊”。另外,任務有各自的內容,這就是作為開發者來編寫的任務函數,來實現這個任務所需要的功能。
綜上,我們知道了每個任務都會具有如下三種特征:
任務函數
任務堆棧
任務控制塊
二、任務的特性
任務的基本特性是獨立性、并發性和動態性。這也是任務和程序模塊的本質區別,程序模塊通常是用于沒有操作系統的裸機開發中。
1、獨立性
在傳統的程序模塊中,一個模塊是可以調用另外一個模塊的,但是在操作系統中,每個任務都具有自己的 CPU ,即 CPU 為自己獨占,這樣,一個任務也就不能夠像調用子程序那樣去調用另外一個任務了。這是關于獨立性一個體現。
關于獨立性的另一個體現就是任務之間傳遞信息時,模塊之間的傳遞信息時主模塊以實參的形式將信息傳遞給模塊的形參,子模塊以返回值的形式將結果傳輸給主模塊。但是在任務之間傳遞信息卻不是這樣的,任務與任務之間的傳遞信息需要借助于第三者,也就是跟操作系統相關聯的信號量、郵箱和消息隊列等,通過第三者來傳遞信息也就造成了信息傳輸是異步的,這也是任務獨立性的一個體現。
2、并發性
任務 A 在時刻 t1 到 t4 之間完成,任務 B 在時刻 t2 到 t3 之間完成,它們的運行時間段有重疊部分,這種運行方式稱為“并發”運行。在多 CPU 系統中,并發運行著的任務確實都有自己的 CPU ,它們的運行狀態就是真正的并發執行,如下圖所示:
任務并發執行
在單 CPU 中,操作系統的任務調度功能解決了這樣一個問題,嵌入式實時操作系統的內核都是采用 “可剝奪型”的任務調度算法,這也就意味著一個已經就緒的高優先級任務可以剝奪另一個正在運行的低優先級任務的運行權而進入運行狀態,如下圖所示:
單CPU任務并發執行
3、動態性
任務的狀態是動態變換的,這意味著這些任務并不是隨時都可以運行的,任務具有以下五種不同的狀態下圖用狀態圖的形式表示出來。
任務狀態圖
三、任務的劃分
對一個具體的嵌入式應用系統進行任務劃分,是基于實時操作系統應用軟件設計的關鍵,任務劃分是否合理將直接影響到軟件設計的質量。當任務劃分的合理時,軟件設計將比較簡單高效,否則將可能比較繁雜,甚至失敗。在進行任務劃分時,具備以下幾個原則:
首要目標是滿足實時性指標。
即使是系統處于最壞的情況下,系統中對于實時性要求的功能都能夠得到實現。
任務數目合理。
任務數目合理,當任務數比較多的時候,每個任務需要實現的功能就簡單一些,任務的設計也簡單一些,但是任務調度操作和任務之間的通信活動增加,使得系統的效率下降,資源開銷也變大。當任務劃分的數目比較少的時候,每個任務需要實現的功能就比較復雜一些,但是可以免除不少任務之間的通信工作,減少共享資源的數量,減輕系統的負擔,減少資源的開銷。因此關于任務數目的設計是比較關鍵的。
簡化軟件系統。
一個系統要實現功能,除了設計其本身的功能以外,還需要其具備相應的時間管理,任務同步,任務通信,內存管理等功能。合理地劃分任務,可以降低對操作系統的服務要求,能夠簡化系統軟件設計,減小軟件代碼規模。
降低資源需求。
減少或者簡化任務之間的同步和通信功能,就可以減少相應數據結構的內存模型,從而降低對系統資源的需求。
因此,為了使得任務劃分更加合理,通常采用以下幾種方法進行任務劃分:
四、設備依賴性任務劃分
假設,現在有如下一個具備輸入輸出功能的系統:
輸入輸出系統
通過上述框圖大致可以明白整個系統的工作流程,通過鍵盤輸入數據,以及攝像頭采集圖片信息,送至 CPU 進行處理,然后系統通過輸出設備液晶屏以及揚聲器輸出相關的信息,圍繞 CPU 為中心,那么我們就可以這樣來進行劃分任務:鍵盤任務,顯示任務,數據采集任務,控制輸出任務和通信任務。
五、關鍵任務的劃分
“關鍵性”是指某種功能在應用系統中的重要性,如果這種功能不能夠正常實現,則會造成重大影響,甚至能夠引發災難性后果。包含關鍵功能的任務稱為“關鍵任務”,關鍵任務必須得到運行機會,即使遺漏一次也是不可行的。
那如何使得關鍵任務能夠準確得到執行呢,我們第一時間所想到的就是提升關鍵任務的優先級,使其優先級為最高,但是這還不夠,我們假設現在有一個火災報警系統,火災報警系統大致完成這么幾件事,檢測火警信號,撥打火警電話,啟動噴淋滅火系統,生成并保存火警記錄以及打印火警記錄。
如果我們把這幾件事都包裝成一個任務,優先級設置為最高,在系統運行的過程當中,生成并保存火警記錄以及打印火警記錄時打印機出問題了,這個時候,就會導致當前任務被掛起,而任務被掛起之后,檢測火警信號也不能夠正常工作了,所以整個系統也就癱瘓了。
因此,對于關鍵功能來說:必須盡可能和其他功能進行剝離,獨立成為一個任務,然后通過通信方式再觸發其他任務,完成后續操作。
除了將關鍵任務和其他功能的任務相剝離,并設置最高優先級以外,還有一種方法能夠使得關鍵任務得到準確執行,那就是采用中斷的方式,比如說,在火警的報警系統中,讓傳感器的火警信號觸發一個外部中斷,中斷發生便完成了信號檢測功能,再由中斷服務函數使用某種通信機制通知其他任務。下面是示意圖:
火災系統
我們知道為了提高系統的實時性,中斷服務函數應該盡可能地短,所以,我們可以進一步進行劃分,將與任務通信這部分的程序剝離出來成為一個任務專門用于通信,這樣, ISR 負擔就更小了,下圖是示意圖:
用ISR完成關鍵功能
由上圖我們可以知道多出了一個任務,消息分發任務,消息任務的存在要不能干預到關鍵任務的運行,但是同時呢,又必須能夠及時地通知到其他任務的運行,因此,消息分發任務的優先級也就確定了,其優先級要低于所有關鍵任務,優先級要高于所有的操作任務。
還有一種情況,就是關鍵任務不能由中斷啟動,則可以將該關鍵功能用一個獨立的任務來實現,如下圖所示:
關鍵任務完成關鍵功能
這個時候,已經不能用中斷的方式來檢測報警信號了,那么就需要不停的查詢煙霧報警器的狀態,防止漏掉了重要的信息。當查詢到了報警信息的時候,在通過通信機制通知其他任務完成相應的操作。
最后,要指出的一點是,如果關鍵任務有嚴格的實時性要求,那么必須賦予它足夠高的優先級,以便及時獲得運行權,如果沒有實時性要求,那么高優先級并不是必須的,關鍵是將其他非關鍵的操作進行剝離,以免受其拖累。
六、緊迫任務的劃分
”緊迫性“是指某種功能必須在規定的時間內得到運行權(及時運行),并在規定的時刻前執行完畢(按時完成),可見這類功能有嚴格的實時性要求,大多數緊迫任務是由異步事件觸發的,這些異步事件一般能夠引發某種中斷。
在這種情況下,將緊迫任務安排在相應的 ISR 中是最有效的方法。如果緊迫任務不能夠安排在 ISR 中,那么為它安排盡可能高的優先級是解決“及時性”的有效方法。
要達到按時完成的目的,必須使得緊迫任務需要執行的時間盡可能的短。辦法就是對緊迫任務進行瘦身,盡可能地剝離不太緊迫的任務,只剩下必須立刻做的操作,將被剝離的不太緊迫的操作另外封裝成一個任務。
下圖是一個數據采集任務,數據采集時一個緊迫任務,通過峰值檢測電路觸發中斷,在中斷里完成 A/D 轉換,下圖是整個數據采集系統的示意圖:
數據采集系統框架
七、數據處理任務的劃分
用戶應用程序中消耗時間最多的就是各種數據處理單元,這種單元通常不止一個,他們通常為不同的功能服務。應該將這些單元劃分出來,分別包裝成不同的任務。由于這類任務需要消耗較多的時間,那么他們的優先級必須安排的比較低。
除此之外的方法,如果操作系統支持將多個任務安排相同優先級的機制,那么當有多個數據處理任務時,可安排相同的優先級,采用時間片輪轉的方式運行。如果操作系統不支持多個任務具有相同的優先級,那么可以將多個需要并行的數據處理任務分成多個數據處理任務,原理如下圖所示:
模擬時間片輪轉
八、功能聚合任務的劃分
正如標題的意思所示,功能聚合任務的劃分,也就是將關系緊密的任務組合成一個任務,達到功能聚合的效果,那什么樣的任務才能稱之為是關系緊密的任務呢,一般滿足以下兩點要求:
數據關聯緊密
時序關聯緊密
至于要將其組合成一個任務的原因也很簡單,是因為如果將關系密切的功能分別用不同的任務來實現,那么就需要進行大量的數據通信和同步通信,這對于系統而言是一個很大的負擔。
九、觸發條件相同任務的劃分
如果若干功能由相同的事件觸發,則可以將這些功能組合成為一個任務,從而免除將事件分發給多個任務的工作量。
但這也必須有一個條件,就是當以某種次序順序執行這些功能的時候,各個功能的實時性要求仍然可以得到滿足,這是關鍵。
同時,這里說的觸發條件相同的任務,通常外部觸發的任務一般是關鍵任務或者緊迫任務,需要按照前文所述的方法來進行任務的劃分,符合本類任務的觸發條件通常是內部事件,比如說一個時鐘事件,也就是說到了指定時間就觸發這個任務,或者說是某個任務運行之后得到一個結論,這結論又觸發了一個任務。如下圖示意圖所示:
觸發條件相同的任務
另外,需要注意的是,在任務內部,各個功能的執行順序要盡可能安排的合理一些:
如果各個功能之間存在有因果關系。則按因果關系安排執行順序,如先計算,后輸出結果
如果各個功能之間完全獨立,則按照實時性要求的強弱安排執行順序。
十、運行周期相同任務的劃分
將周期相同的功能組合在一起封裝成一個任務,就能可以避免一個時間觸發幾個任務,省略去事件分發操作和他們之間的通信,能夠減輕系統的負擔。
十一、順序操作的任務的劃分
如果若干功能按照固定的順序進行流水作業,相互之間完全沒有并發性,那么應該將這些功能組合成為一個任務。
十二、總結
通過上述的論述,我們知道了在一個 RTOS 中應該如何進行任務的劃分,在最后,再進行精煉一下,總結為如下幾點:
以 CPU 為中心,將與各種輸入/輸出相關的功能劃分為獨立的任務
將關鍵功能剝離出來用一個獨立的任務或者是 ISR 去完成,剩余的部分用另外一個任務實現,兩者之間通過通信機制進行溝通
將緊迫功能剝離出來用一個高優先級的任務或者 ISR 去完成,剩余部分用另外一個任務實現,兩者之間通過通信機制進行溝通
對于既關鍵又緊迫的功能,按照緊迫功能的處理方法對齊進行處理
將消耗 CPU 時間較多的數據處理功能劃分出來,封裝成低優先級的任務
將關系密切的若干任務組合成一個任務,達到功能聚合的效果
將由相同事件觸發的若干功能組合成為一個任務,從而免除事件分發機制
將運行周期相同的任務組合成為一個任務,從而免除時間事件分發機制
將若干按固定順序執行的功能組合成為一個功能,從而免除同步接力通信的麻煩
原文標題:RTOS是如何進行任務劃分的?
文章出處:【微信公眾號:嵌入式ARM】歡迎添加關注!文章轉載請注明出處。
審核編輯:湯梓紅
-
模塊
+關注
關注
7文章
2735瀏覽量
47754 -
嵌入式
+關注
關注
5093文章
19178瀏覽量
307717 -
cpu
+關注
關注
68文章
10905瀏覽量
213032
原文標題:RTOS是如何進行任務劃分的?
文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論