第一節
RTOS即時作業系統
以Task(工作)為主
每個Task(工作)基本上為一無窮執行的函數(副程式)
為了要使進入無窮迴圈能在跳出來,故我們要使用Context(文本)
每種微控制器之文本可能有些微之差異,但基本必具有:
- 暫存器(register file)
- 堆疊指標(stack pointer)
- 程式計數器(program counter,PC)
- 狀態暫存器(status register)
每一個工作都有專屬的文本
舉例:
a. 以前的程式(單一工作)
main(){
while(1){
keyscan();//←keyscan副程式 非無窮迴圈
lcdDisplay();//←lcdDisplay副程式 非無窮迴圈
uartTRx();//←uartTRx副程式 非無窮迴圈
}
}
b. 多工作業概述(程式執行可設定時間,可較分配均勻、程式執行可設定優先權、可寫成模組化)
main(){
Taskkeyscan();//←建立keyscan工作 無窮迴圈
TaskLCDdisplay();//←建立LCD Display工作 無窮迴圈
TaskUART();//←建立UART傳輸工作 無窮迴圈
。
。
statTaskScheduler();//←開始工作排程 無窮迴圈
while(1);
}
while(1);不會造成程式在此停擺嗎?
單一與多工 工作時序圖
多工作業之優點:
- 可以分配每一個工作時間
- 可以使程式具有模組化
- 可以分配工作的優先順序
多工作業之缺點:
- 實作上較複雜
- preemption(強佔式即時)優先順序將造成低優先工作不被執行之可能
(合作式穩定)
-------------------------------------------------------------------------------------
第二節 第三節
商業三多工
- 多使用者
- 使用者底下可以執行多應用程式
- 應用程式可以執行多工
多工排程(scheduling) http://www.freertos.org/implementation/a00005.html
- Task1執行中
- kernel將Task1擱置suspend
- resume(重新執行)Task2
- Task2執行中 鎖住且獨占週邊存取
- 核心擱置Task2
- resume(重新執行)Task3
- Task3要使用被Task2鎖住之週邊,造成無法執行,故Task3自行進入阻斷狀態,Task3離開
- resume Task1
- Task2執行中且完成,解鎖週邊
- Task3執行中,因週邊以解鎖故可正常執行
Context Switching 文本切換 http://www.freertos.org/implementation/a00006.html
文本如下圖
RTOS之工作時間中斷之時機(Timing),當滴答聲產生且需工作切換時,在Tick中斷服務程式=system tick中會執行
- 滴答計數器+1
- 若需工作切換時,將執行文本切換
system tick為system計時中斷之計數器每次系統計時中斷產生時,system tick計數器會加1
多工作業系統一定會系統滴答(system tick)(優先權最高),系統滴答進入中斷後Tick就會加1
多工作業系統一定會系統滴答(system tick)(優先權最高),系統滴答進入中斷後Tick就會加1
對程式來說是文本切換,對我們來看是工作切換
每經過一個時間就會累計滴答數,可設定多少滴答做工作切換??
遇到三個問題
- 滴答何時會累加 在滴答中斷產生時會累加1,而滴答多久中斷可以設定,而若滴答中斷還不一定會文本切換,需看你的TickISR
- 滴答何地一張圖的時間設定有關嗎
- 其實這是一個模擬多工的系統?是 ,其把多個長工作時間系分成短工作時間,每個Task工作時間很短就切換文本,以模擬成多工
切換文本之兩大動作
- 儲存現有工作文本(saving executing context)
- 回存下一工作文本(restoring next context)
- 當Tick中斷產生時,會將現有工作之PC存放在現有工作堆疊區中
- 當要工作切換時,要將現有工作之暫存器檔(register file)和PSW(狀態暫存器)儲存到現有工作之堆疊區(使用PUSH指令)
- 將堆疊指標儲存到現有工作之工作控制區(Task Control Block,TCB)
一個問題
SP不是存放至data memory嗎?老師圖中SP指向data memory必非指存入,且存入後SP值會在改變,故不可,是存入TCB
回存下一工作文本之步驟
- 讀取下一工作之工作控制區中之堆疊指標
- 讀取存放在下一工作堆疊區中之 register file,PSW(使用POP)
- 由Tick中斷服務程式返回時,會將下一工作的PC存入PC中,得到執行下一工作之結果
為了避免延遲造成工作停頓,所以利用block api 來延遲,當所要延遲的時間到,則進入就緒,由CPU來告知,必開始執行所要的動作,其目的可以讓在該程式延遲過程中,不停頓使其他程式可以繼續執行
問block api block done??後續說明
呼叫block api :當執行中的程式需要延遲時間的話
blockapi由工作呼叫,其他由OS呼叫
初始值為ready的狀態
只有在ready時接受到tick才能工作切換
建立工作
一工作之基本架構
void 工作名稱(void *pvParameters) {
變數宣告。。。
while(1) {
工作內容;
。
}
vTaskdelete(NULL);//若有工作有問題,會跳出while迴圈時,我們要把記憶體資料清除,此副程式名稱是固定的
}
當建立工作要告訴O.S.有建這份工作
創建一工作,需呼叫
xTaskCreate(工作名稱,描述工作之字串,工作堆疊區深度,工作所需之參數指標,優先順序,工作處理指標)
工作處理指標:讓其他工作或O.S.可以存取你的工作
問工作所需之參數指標、描述工作之字串
當工作創建後,需再呼叫xTaskStartScheduler()後,才會開始多工作業
例1.
void vTask1(void *ptr) {
char *str="Task 1\n";
unsigned long ul;
while(1) {
printf(str);
for(ul=0;ul<0xffff;ul++);//delay
}
vTaskDelete(NULL);
}
int main(void) {
xTaskCreate(vTask1,"my Task 1",1000,NULL,1,NULL);
vTaskStartSchedular();
while(1);
}
沒有留言:
張貼留言
文章有誤或有問題麻煩您留言告知! 謝謝您~~