系統資料:
1)當前的pid
2)所有的程序總數pamount
//多工系統的初始化
1. 設定msp值
2. 設定臨時的psp值(因為這段實際上只在啟動定時器之前有效)
3. 設定control[1]=1(設定雙堆疊),馬上會自動切換到psp上
4. 設定pid=0,設定pamount=0
5. 設定為程序資訊表起始位址到plist(注意程序資訊表是向上生長的)
6. 設定為程序堆疊分配的起始位址到pstack(堆疊是向下生長的)
//呼叫
addtask
新增任務
1. 寫入配置資訊到任務表中(任務起始位址,堆疊位址(首次進行分配)xpsr等等)
a) 至於輸入引數,就存放在任務的堆疊中
//啟動任務切換
1. 設定systick定時器的詳細配置(定時間,開中斷)
2. 啟動定時器
//程序的切換過程
1. 當中斷觸發時,硬體會按照下表自動進行暫存器的入棧(如果當響應異常時,當前的**正在使用
psp,則壓入
psp,即使用執行緒堆疊;否則壓入
msp,使用主堆疊。一旦進入了服務例程,就將一直使用主堆疊),通常
systick
中斷都是在
psp的情況下發生的,所以資料壓入
psp中。
2. 入棧完畢,將堆疊切換到msp,開始執行systick服務程式:
a) 將當前的堆疊切換為msp
b) 取得程序堆疊指標,將堆疊指標備份到pid備份區域
c) 將r4到r11儲存到pid對應的程式堆疊區域
d) 開始執行程式計算下乙個pid=pid+1>pamount?1: pid+1;
e) 讀取下乙個pid程序堆疊指標,並將堆疊中的備份恢復到到r4到r11暫存器中
g) 進行中斷返回,同時這樣會觸發中斷返回的硬體過程,硬體會將堆疊切換為psp並將psp的內容恢復到相應暫存器中
3. 出棧完畢,硬體自動清除nvic暫存器
4. 現場恢復完畢,繼續執行任務
//任務的退出
1. 在寫入程序資訊的時候,已經把lr暫存器的值設定成為了exittask函式的位址,所以,當函式退出之後,會自動執行收尾。
補充資料:
1. 關於堆疊
a) 堆疊是向下生長的
b) 堆疊指標總是指向最後被壓入堆疊的資料
c) 只有在control[1]=1時,才會使用雙堆疊
d) 因為 c m 3 使用的是向下生長的滿棧,所以 msp 的初始值必須是堆疊記憶體的末位址加1 。
舉例來說,如果你的堆疊區域在 0x20007c00 ‐ 0x20007fff 之間,那麼 msp 的初始值就必須是0 x 20008000。
e) 在handler模式下control[1]不可以寫入1,但是可以讀取psp的值
f) 堆疊的位址指標會和4對齊,例如:向sp寫入0x20006001或者0x20006002或者0x20006003時,會自動變成0x20006000,而寫入0x20006004就是直接寫入0x20006004
g) 堆疊總是指向最後乙個元素的,當寫入四個位元組的字時,會先指標減去4,再進行入棧。當堆疊指標為sp=0x20006004時,寫入乙個字 0x12345678時,會在0x20006000位元組、0x20006001位元組、0x20006002位元組、0x20006003位元組分別寫入0x78、0x56、0x34、0x12。要想執行類似的操作可以使用儲存指令(例如str)將資料存到0x20006000單元,會達到相同的效果
stm32多工程式的實現
實現功能 在stm32下完成乙個基於freertos的多工程式,執行3個週期性task。task1,每間隔500ms閃爍 變化 一次led task2,每間隔2000ms,向串列埠傳送一次指令資料 helloworld task3,每間隔5000ms,從aht20採集一次溫濕度資料 不考慮硬體情況,...
STM32 簡單多任務排程的方法與程式例程
多工處理是指使用者可以在同一時間內執行多個應用程式,每個應用程式被稱作乙個任務.linux windows就是支援多工的作業系統,比起單任務系統它的功能增強了許多。當多工作業系統使用某種任務排程策略允許兩個或更多程序併發共享乙個處理器時,事實上處理器在某一時刻只會給一件任務提供服務。因為任務排程機制...
基於STM32的FreeRTOS任務管理
freertos是一款實時作業系統,可以設定任務的優先順序。freertos用於mcu,占用irom約4 9kbyte,freertos支援裁剪功能 可裁剪性強 freertos 與 ucos ii區別 在商用條件下,freertos免費開源,而ucos ii需要收費 非商用免費 任務設計上更容易。...