單晶片lab10結報

tags: stm32
實驗日期 : 2021/12/16

上課教材

lab1

SPEC

利用RTOS中的Thread, Semaphore, Mutex完成跑馬燈,按下開發板上的按鈕切換至下一個狀態。

  1. 每隔1秒亮1顆LED,共3顆輪流亮。
  2. 每隔1秒同時亮2顆LED。(Semaphore狀態)
  3. 每隔1秒LED燈全部閃爍。(Mutex狀態)

實現方法

單晶片lab9結報 lab1實踐內容3個state的切換,這次改成在副程式觸發,因為程式會卡在副程式的while loop不斷執行。第2個狀態使用允許同一時間同一資源可以被2個執行緒訪問的Semaphore,並新增5個執行緒,加上原本的int main{},共6個執行緒,分別執行亮LED1+亮LED2、亮LED2+亮LED3、亮LED3+亮LED1,實現每隔1秒同時亮2顆LED。

第3個狀態使用(允許同一時間同一資源可以被1個執行緒訪問)mutex,間隔1秒,執行緒1反轉LED1燈亮暗狀態、執行緒2反轉LED2燈亮暗狀態、執行緒3反轉LED3燈亮暗狀態,由於訪問時間太快,導致看起來是同時3個LED會切換狀態,實現每隔1秒LED燈全部閃爍。

個人覺得是很沒有意義的實作,只是硬要用到multi-thread觀念,去做出不需要用到multi-thread的功能,多此一舉。

lab2

SPEC

利用RTOS中的Mail與使用Thread::wait()計時實現碼錶。

Serial monitor輸入值 功能
's' 開始計時(精度: 10ms)
'p' 顯示計時的秒數並停止計時
'r' 歸零並停止計時

實現方法

typedef struct {
    bool clock_start;
    float counter; //counter value
} mail_t;
Mail<mail_t, 16> mail_box;

新增一個自定義的結構體,命名為為mail_t,並將其結構給Mail這個template class,作為初始化資料型態,當Serial monitor輸入指定時,就直接改Mail類的對象,public變數mail->clock_start = false即可。

課後習題

Question 1

詳述Thread在Mbed平台中是如何運作。

Answer 1

單晶片lab9結報 Question 1

Question 2

解釋Mbed平台API中,wait()Thread::wait()兩者差別。

Answer 2

視版本而定,而有所差異。根據mbed_wait_api.h原始碼Thread API文檔描述 :

void wait_us(int us); This function spins the CPU to produce a small delay. As it is calculated based on the expected execution time of a software loop, it may well run slower than requested based on activity from other threads and interrupts.

Thread::static osStatus wait(uint32_t millisec) Wait for a specified time period in milliseconds Being tick-based, the delay will be up to the specified time - eg for a value of 1 the system waits until the next millisecond tick occurs, leading to a delay of 0-1 milliseconds.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

簡單來說,wait()使用程式的loop迴圈,讓CPU不斷運行,這種情況稱為spinlock;而Thread::wait()會將目前執行緒的狀態拉至waiting state,因此其他執行緒一樣不受影響,可以繼續執行,如果沒有其他執行緒在ready state,會讓整個MCU進入sleep以節省電源。

心得

劉永勝

不同於上次實驗,這次使用multithread來共享同一區塊的程式碼(資源),藉由開關的方式,控制每個thread執行的時間點。而我們這次的Lab1雖然可以依序執行功能,但可能是因為製造的thread太多,造成執行序無法順利進行,而無法反覆執行三項程序。期末專題的限期逐漸逼近,近期實作無作業系統的觀念也無心學習新知識,願之後實作能好懂些。

李宇洋

包含上次與這次的OS實作因為對於多執行緒實際的執行情況理解過少,因此在實作過程卡住了非常久,甚至到實驗完對於講義中提到multithread運用的Queue、Semaphore等方法如何互相交換主控權仍是一知半解。但是還是能大致推斷出因為我們在Lab 1中使用了Terminate的寫法,導致程序中的waitrelease尚未使用以及釋放記憶體空間便被終止,這導致了我們在實作中無法從mode 3回到mode 1。

陳旭祺

參考周志遠作業系統,多線程要共享資源時需要同步(Process Synchronization),以免線程之間取到的資源不同步,也就是race condition的情況,因此要找出他的critical section,使用Mutex(Mutual Exclusion)去鎖住critical section,確保同一時間內資料只會有單一存取。

而Semaphore算是一個比起Mutex更generalized的機制,本質上是一個計數,紀錄這個critical section可以同時被幾個線程共同執行,因此當數量為1時,代表這個critical section只能被一個線程執行,稱為binary Semaphore,等於前面講的Mutex。


老實說,我覺得這次實作內容很沒有意義,lab1不需要用多線程來寫,也不存在共享資源的衝突,硬要用多線程來寫;而lab2也不知道意義為何,直接訪問並改變這個類的變數即可。