有時候為了實現一些簡單的、對實時性要求不高的任務,採用作業系統不僅增加了程式的複雜性,對低效能微控制器的資源占用也是值得考慮的問題。這時候作業系統可能不是必要的,可以通過一種簡單的方法,在裸機程式設計中實現類似「多工切換」的方法。
比如,在某個應用中,我們需要10ms做一次a/d轉換,1s串列埠傳送一次資料,500ms讀一次外部io,並且這些任務都不是對時間要求嚴格的任務,這時候就可以使用下面的方法實現「多工」,不僅使程式結構更加清晰,也使我們的程式設計思路更加清晰。
以51微控制器為例,通過簡單的封裝,main.c可以更簡短清晰:
#include
"common.h"
#include
"stdio.h"
void
main()
}
首先實現乙個定時器,用於遞增計數器變數。定義乙個uint32_t
型別的timeflag
。這裡定時器中斷定時為1ms,如果幾個任務的執行週期比較長,定義為10ms也是可以的。如果是stm32可以直接開啟stm32的systick中斷用於遞增計數器。
/**
* @brief 定時器0
* @note timeflag為計數器,每毫秒遞增一次
* @retval none
*/void
timer0
() interrupt 1
然後分別定義兩個任務的時間變數threadtime1
,threadtime2
,用於與計數器比較,實現方法如下:
基本思路為:用計數器變數減去任務的時間變數,如果時間大於等於執行週期,則執行func()
,即我們的任務,否則不執行。然後將最新的計數器值賦值給任務的時間變數用於下一次比較。
uint32_t delay1 =
500;
//這裡的值與上述中斷時間有關 ,執行週期 = delay * 中斷時間
uint32_t delay2 =
100;
void
main()
if(timeflag - threadtime2 >= delay2)
//時間變數與計數器變數作比較 100ms
}}
將時間變數比較的功能部分提公升為巨集的形式,這裡沒有判斷引數是否合法。
uint32_t threadtime[4]
=;//定義四個任務的時間變數
#define thread(time, delay, func) \
\ if
(timeflag - time >= delay) \
然後就可以在大迴圈中這樣寫,是不是顯得很簡潔。
這樣rain_capture_thread
任務將會每10ms執行一次,msg_thread
1s執行一次,in_capture_thread
500ms執行一次。
while(1
)
這樣就可以使用乙個定時器實現多個對時間要求不高的任務啦。 多工設計 玩轉嵌入式多工程式設計筆記三
目錄 2 核 4 執行緒 1mhz 就是 1us 大小核 big.little 核心指令 opcode 手動排程 編譯時刻排程 compile time schedule 自動排程 runtime schedule 任務平面 task plane 任務多元化原則 資料完整性 共享資源 2 核 cpu...
嵌入式Linux多工程式設計 程序 管道 命名管道
pid t new pid new pid fork switch new pid char envp char ar execv char ar execvp char ar execve if execl bin echo echo executed by execl nullptr 0 per...
ARM嵌入式裸機程式學習(一)
這裡不用ads整合開發環境,因為ads相容性存在問題,而且通過自己手動編譯 鏈結對學習有好處,所以我們下面都在linux環境下進行arm開發。開發環境 linux作業系統 ubuntu 開發工具 arm linux gdb 7.5 eclipse cpp helios sr2 linux gtc a...