我們通常認為,在中斷中,不能執行耗時的操作,否則會影響系統的穩定性,尤其對於嵌入式程式設計。對於帶作業系統的程式而言,可以通過作業系統的排程,將中斷處理分成兩個部分,耗時的操作可以放到執行緒中去執行,但是對於沒有作業系統的情況,又應該如何處理呢
比較常見的,我們可能會定義一些全域性變數,作為flag
,然後在mainloop
中不停的判斷這些flag
,再在中斷中修改這些flag
,最後在mainloop
中執行具體的邏輯,但是這樣,無疑會增加耦合,增加程式維護成本
cpost正是應用在這種情況下的乙個簡單但又十分方便的工具,它可以特別方便的進行上下文的切換,減少模組耦合
cpost
借鑑的android的handler機制,通過在mainloop
中跑乙個任務,然後在其他地方,可以是中斷,也可以是模組邏輯中,直接丟擲需要執行的函式,使其脫離呼叫處的上下文,執行在mainloop
中。cpost
還支援延遲處理,可以指定函式在丟擲後多久執行
cpost
的使用十分簡單,這裡以使用在嵌入式無作業系統中為例,主要用作中斷延遲處理的情況
配置系統tick
配置cpost.h
中的巨集cpost_get_tick()
,配置成獲取系統tick,以stm32 hal為例
#define cpost_get_tick() hal_gettick()
配置處理程序
在mainloop
呼叫cpostprocess
函式
丟擲任務int
main
(void
)return0;
}
在中斷等需要進行上下文切換的地方呼叫cpsot
介面,使其在mainloop
中執行
cpost
(inthandler)
;
cpost
的原理其實很簡單,其**量也十分少,總共加起來就只有幾十行**,cpost
維護了乙個而全域性的陣列
其中,陣列的每乙個元素表示包含了需要執行的函式和引數,當呼叫cposthandler cposhhandlers[cpost_max_handler_size]
=;
cpost
介面時,被post的函式和引數會被儲存在這個陣列中,然後mainloop
中執行的cpostprocess
函式會遍歷這個陣列,當滿足條件時,執行對應的函式,從而達到上下文切換的目的
其實,cpost的方式,和一開始提到的使用全域性的flag進行上下文切換的方法很像,只不過,cpost通過乙個陣列的維護和直接post函式的方式,省去了維護flag的成本,也不需要將需要執行的函式耦合到mianloop中,從而變得簡單易用void
cpostprocess
(void)}
}}
筆記 cpu上下文,上下文切換
cpu 上下文 cpu 暫存器,是 cpu 內建的容量小 但速度極快的記憶體。而程式計數器,則是用來儲存 cpu 正在執行的指令位置 或者即將執行的下一條指令位置。它們都是 cpu 在執行任何任務前,必須的依賴環境。cpu 上下文切換 就是先把前乙個任務的 cpu 上下文 也就是 cpu 暫存器和程...
上下文切換
1 系統呼叫 一次系統呼叫其實是發生了兩次cpu上下文的切換 首先將使用者態的cpu暫存器中的指令儲存在系統核心中。為了執行核心態 需要將暫存器更新為核心態指令的位置,然後跳轉到核心空間去執行任務。當核心態的指令執行完成的時候,cpu暫存器將恢復儲存在系統核心中的上一次執行的使用者態,然後切換到使用...
上下文切換
上下文切換 有時也稱做程序切換或任務切換 是指 cpu 從乙個程序或執行緒切換到另乙個程序或執行緒。上下文切換與模式切換 上下文切換只能發生在核心態中。核心態是 cpu 的一種有特權的模式,在這種模式下只有核心執行並且可以訪問所有記憶體和其他系統資源。其他的程式,如應用程式,在最開始都是執行在使用者...