單片機上實現實時多任務的一種方法

 雖然單片機的處理能力低下,可是咱們仍是要儘可能榨乾它,以最少的資源幹更多的事情,因此在單片機上進行多任務處理仍是很常見的事情,任務多了,資源仍是那些,每一個任務獲得執行的週期一定拉長,勢必會影響任務的實時性。
    遇到這種狀況,爲了保證明時性,都會引入任務調度機制,對於ARM7或更高級的16位或32處理器,咱們能夠加入一個RTOS來處理,但RTOS的任務調度和系統開銷會佔用很大一部分處理器資源的,對於通常的低檔8位機顯然難以承受。怎麼辦?想一想,引入RTOS不就是爲了實時任務調度麼,咱們本身調度一下不就完了嘛,費那事。不過本身調度是挺費事的,不過8位機也不會安排太多任務,下面就介紹一種保證明時性的任務調度方法。
    通常無OS的單片機程序都是在初始化後直接進入死循環,幾個要執行的任務都放在死循環中去週期循環調用。由於這個循環週期沒法保證,因此死循環中每一個任務被調用執行的週期就沒法保證,固然具備實時性要求的任務就沒法保證在規定時間內獲得處理。如今以一個範例來講明這種任務調度方法,假定爲某單片機安排了5個任務用Task1~Task5表示,其各任務的實時性要求和實測得最長執行時間以下表:
 
Task1
Task2
Task3
Task4
Task5
實時性要求(ms)
1
2
5
10
100
最長執行時間(ms)
0.1
0.2
0.5
0.3
1.2
    由上表能夠看出,五個任務放在一個死循環中順序執行,最長的執行週期達到了2.3ms,這對於Task1和Task2來講是沒法忍受的,並且響應系統中斷也要花費時間,雖然通常系統中斷處理函數都很短。現假設有3箇中斷處理函數Int1~Int3,其最小中斷週期和最長執行時間見下表:
 
Int1
Int2
Int3
最小中斷週期(ms)
0.2
2
10
最長執行時間(ms)
0.02
0.05
0.05
    如今我要保證最短的Task1的1ms響應時間,必須使得程序初始化後進入的死循環執行週期在1ms內,因而乎我對某些任務進行如下加工:
    Task3拆分紅5個最長執行時間爲0.1ms的任務Task3.1~Task3.5。
    Task5拆分紅4個最長執行時間爲0.3ms的任務Task5.1~Task5.4。
    作完拆分後將這些子任務安排到5個組(Class1~Class5)裏,分配以下:
 
Class1
Class2
Class3
Class4
Class5
任務
Task1,Task2
Task3.1,Task4
Task1,Task3.2
Task5.1
Task1,Task2
Task3.3,Task5.2
Task1,Task3.4
Task5.3
Task1,Task2
Task3.5,Task5.4
最長執行時間(ms)
0.7
0.5
0.7
0.5
0.7
    如上表,再算上期間各中斷的執行時間,每組的執行時間也不可能超過1ms吧。
    好了,將這五個組按順序放在死循環裏,而且保證被拆分的每一個子任務在執行以前都去判斷排在它前頭的那個子任務是否被執行到,若是被執行過了則本段子任務執行,不然不執行(例Task3.3在執行前要去判斷Task3.2是否被執行,並且本段子程序在執行後要給出標誌,告知下段子程序Task3.4我執行過了)。這麼作看看能不能知足每一個任務要求的實時響應時間?都在容許範圍內吧。
    若是但願Task1可以實現精準的1ms定時執行,能夠設置一個1ms的定時器來定時順序切換這5個組。
    上面的這種作法也算是實現一種簡單的實時任務調度,其優勢是:任務調度都在編程時作好了,在程序實際運行過程當中幾乎不會佔用額外的硬件資源和處理器時間。缺點是:編程麻煩,必須預先算準各任務和拆分的子任務的最長執行時間,不能有誤差,並且編寫出來的程序可讀性差。
    總的來講,這種調度方法對於低檔8位單片機來講仍是一種不錯的實時多任務的解決方案,行之有效,就是費點事。
相關文章
相關標籤/搜索