2014年9月26日

2014/09/26進階微控制器應用

--------------------------------------------------------------
第一節
RTOS即時作業系統

以Task(工作)為主
每個Task(工作)基本上為一無窮執行的函數(副程式)

為了要使進入無窮迴圈能在跳出來,故我們要使用Context(文本)
每種微控制器之文本可能有些微之差異,但基本必具有:



  1. 暫存器(register file)
  2. 堆疊指標(stack pointer)
  3. 程式計數器(program counter,PC)
  4. 狀態暫存器(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);不會造成程式在此停擺嗎?

單一與多工 工作時序圖

多工作業之優點:
  1. 可以分配每一個工作時間
  2. 可以使程式具有模組化
  3. 可以分配工作的優先順序
多工作業之缺點:
  1. 實作上較複雜
  2. preemption(強佔式即時)優先順序將造成低優先工作不被執行之可能
(合作式穩定)

-------------------------------------------------------------------------------------
第二節 第三節


商業三多工
  1. 多使用者
  2. 使用者底下可以執行多應用程式
  3. 應用程式可以執行多工
  1. Task1執行中
  2. kernel將Task1擱置suspend
  3. resume(重新執行)Task2
  4. Task2執行中 鎖住且獨占週邊存取
  5. 核心擱置Task2
  6. resume(重新執行)Task3
  7. Task3要使用被Task2鎖住之週邊,造成無法執行,故Task3自行進入阻斷狀態,Task3離開
  8. resume Task1
  9. Task2執行中且完成,解鎖週邊
  10. Task3執行中,因週邊以解鎖故可正常執行

文本如下圖
RTOS之工作時間中斷之時機(Timing),當滴答聲產生且需工作切換時,在Tick中斷服務程式=system tick中會執行
  1. 滴答計數器+1
  2. 若需工作切換時,將執行文本切換
system tick為system計時中斷之計數器每次系統計時中斷產生時,system tick計數器會加1
多工作業系統一定會系統滴答(system tick)(優先權最高),系統滴答進入中斷後Tick就會加1

對程式來說是文本切換,對我們來看是工作切換
每經過一個時間就會累計滴答數,可設定多少滴答做工作切換??

遇到三個問題 
  1. 滴答何時會累加 在滴答中斷產生時會累加1,而滴答多久中斷可以設定,而若滴答中斷還不一定會文本切換,需看你的TickISR
  2. 滴答何地一張圖的時間設定有關嗎
  3. 其實這是一個模擬多工的系統?是 ,其把多個長工作時間系分成短工作時間,每個Task工作時間很短就切換文本,以模擬成多工

切換文本之兩大動作
  1. 儲存現有工作文本(saving executing context)
  2. 回存下一工作文本(restoring next context)
儲存現有本文之步驟
  1. 當Tick中斷產生時,會將現有工作之PC存放在現有工作堆疊區中
  2. 當要工作切換時,要將現有工作之暫存器檔(register file)和PSW(狀態暫存器)儲存到現有工作之堆疊區(使用PUSH指令)
  3. 將堆疊指標儲存到現有工作之工作控制區(Task Control Block,TCB)
一個問題
SP不是存放至data memory嗎?老師圖中SP指向data memory必非指存入,且存入後SP值會在改變,故不可,是存入TCB

回存下一工作文本之步驟
  1. 讀取下一工作之工作控制區中之堆疊指標
  2. 讀取存放在下一工作堆疊區中之 register file,PSW(使用POP)
  3. 由Tick中斷服務程式返回時,會將下一工作的PC存入PC中,得到執行下一工作之結果

工作狀態(Task state) suspended與blocked之差異?
為了避免延遲造成工作停頓,所以利用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);
}

沒有留言:

張貼留言

文章有誤或有問題麻煩您留言告知! 謝謝您~~