Homework 7 開發紀錄(A)

程式測試

02-ContextSwitch-1
  • 經過測試後,在這個部分,有兩個疑問
  • 1.不懂 context_switch.S裡mrs ip, psr該行指令用意,因為拿掉的話程式也能順利執行
  • 2.換成psp後,為什麼要pop { r4, r5, r6, r7, r8, r9, r10, r11, lr },為什麼不要直接將usertask_stack_start[0]設成usertask的位址,然後直接pop { lr }就好?
  •  
03-ContextSwitch-2
  • 此部分的syscal是為了把usertask切換回OS。
  • 一開始OS在執行時遇到activate便切換到usertask(動作包括push register,切換成psp,跳到usertask位址),usertask遇到syscall時,則用svc_handler處理,svc_handler會把user state切換成kernel state,以此類推後面的程式碼。
  •  

作業需求

  • 提供基本的 shell,然後能夠用新建立的 thread 計算 fibonacci 數列
 

shell實做

  •  
  • 目前設計的方式是在main裡先產生一個thread來執行我的shell的功能,可以輸入指令,當使用者輸入指令後,再產生另外一個thread來執行該指令。
  •  
I/O: read from RX
  • USART2_SR為序列傳輸狀態暫存器
  • RXNE為讀入數據暫存器,當此位置被設為1時,表示RX有收到資料了,即可從USART2_DR接收該資料
  • 因此這部分我在設計時,我會讓shell一直等說有沒有input,當鍵盤有輸入時,便抓取被鍵入的字元,然後給RX輸出,便可以即時檢視我們打下的指令是什麼了。
  •  
提示字元
  • 我的設定為"guest@mini-arm-os$",一開始進入shell或是每次按下enter,都會在螢幕上印出該命令提示字元
  •  
Backspace and enter
  • 從USART2_DR抓資料時,會做兩個特殊判斷,一個是backspace,另一個就是enter。
  • Backspace
  • backspace在實做上有一點要注意的是要把最後的character變成空白,並且游標的位置要退後一格,因此,我用的方式是用一個buffer儲存已經鍵入的字元,假設目前長度為n,當發現按下backspace時,先輸出回車鍵(\r),輸出提示字元,輸出buffer裡面前n-1個字元,輸出一個空白鍵,然後重複輸出回車鍵(\r),輸出提示字元,輸出buffer裡面前n-1個字元,這樣就可以達到backspace的效果了。舉例來說
  • 目前shell畫面為
  • "guest@mini-arm-os$abcd"
  • 按下backspace後,畫面變化依序為
  • "guest@mini-arm-os$abcd" -> "guest@mini-arm-os$abc " ->  "guest@mini-arm-os$abc"
  • Enter
  • Enter則是用來指示說已經輸入完指令,並且嘗試執行指令。在畫面上則是輸出換行和回車,和提示字元。
  •  
執行fibonacci
  • 這部分如同作業一,在shell裡去呼叫外部用ARM assembly寫的fibonacci函式,目前用的是recursive的版本。
  •  
thread執行fibonacci
  • 關於thread的操作,中間我有遇到一些不習慣的地方,一開始的範例是有三個thread被create出來,然後有一個thread_start()去開始執行thread,而上次作業我所使用的pthread.h則是當thread被create就會開始執行被賦予的任務,這是兩者不太一樣的地方。除此之外,我以為是每create一次或多次後總要呼叫thread_start()才會啟動,結果則是當呼叫一次thread_start()後,之後若是有create,則就直接開始執行thread,不用再thread_start()一次。
  •  

Exclusive lock

  • 新增一個exclusive lock,來避免shell和fibonacci搶TX,造成輸出不連續。
  •  

Priority scheduling

  • 找到threads.c底下切換task的地方,從round-robin改為round-robin based priority scheduling的方式,每個時槽都會先去檢查哪個task有最高優先權,擁有最高優先權的task會搶到CPU,而其他的task則必須等待直到下一個時槽,因此高優先權的會先執行完成。不過缺點是有可能造成低priority的task的starvation。
  • 改善的方法是採用aging的機制,讓低優先權的task可以隨著時間增加priority。