stm32
利用RTOS中3條以上thread完成跑馬燈,按下開發板上的按鈕切換至下一個狀態。
volatile int counter = 0;
volatile int counter_thread3 = 0;
使用兩個全局volatile
變數,紀錄LED亮到哪一顆燈,因為是全局變數,在不同執行緒之間都可以共享。
switch (state % 4) {
case 0:
thread1.signal_set(0x1); break;
case 1:
thread2.signal_set(0x1); break;
case 2:
thread1.signal_set(0x1);
thread3.signal_set(0x1); break;
case 3:
thread4.signal_set(0x1); break;
}
state
為紀錄狀態的變數,當按鈕被按下時,state++
,以state % 4
判斷就會在0到3之間之間循環。使用4個執行緒,狀態1使用執行緒1、狀態2使用執行緒2、狀態3使用執行緒1與執行緒3、狀態4使用執行緒4。
實際程式測試時,發現切換至不同執行緒,一開始會執行切換後的執行緒,之後再回去執行前一個執行緒,造成LED閃爍未符合預期。推測原因是未執行完但已signal觸發的執行緒會排在queue裡面,等到執行完切換後的執行緒後,會再回去執行尚未執行的task,不過這方面原因有待商榷。
利用RTOS中的signals。在serial monitor輸入指令控制開發板的LED。輸入'1'
亮綠燈、輸入'2'
亮藍燈、輸入'3'
亮紅燈。
利用RTOS中的signals。將超音波模組測量到的距離(cm)顯示2位於七段顯示器,並控制開發板的LED為
距離(cm) | LED |
---|---|
紅燈 | |
藍燈 | |
綠燈 | |
全亮 |
使用別人寫好的超音波函式庫,接口使用如下
// call dist when the distance changes
ultrasonic mu(p6, p7, .1, 1, &dist);
// start measuring the distance
mu.startUpdates();
// call checkDistance() as much as possible, as this is
// where the class checks if dist needs to be called.
mu.checkDistance();
參照lab1 實現方法使用signal觸發讓LED亮功能的個別執行緒,再使用lab8 lab6實現方法觀念顯示2位數在七段顯示器上。
請詳述thread在Mbed平台中是如何運作的。
參照官方RTOS doc範例說明
Thread thread;
建立thread
這個類的對象,也就是創建一個執行緒。
void led2_thread() {
while (true) {
led2 = !led2;
Thread::wait(1000);
}
}
thread.start(led2_thread);
開啟執行緒,並賦予其函數,led2_thread
的函式可以視為是另一個int main(){}
的函式入口,也就是說除了原本main function
的執行緒外,又新增了1個執行緒,共有2個執行緒同時執行。
signal是用來告知process有一個event要發生,像是std::this_thread::sleep_for(2000ms);
就是讓執行緒休息,2秒後收到一個signal再wake up起來,不同執行緒之間互相溝通也是需要signal。
請解釋執行多執行緒之死結(Deadlock)的問題,以及如何避免。
因此這邊可以總結deadlock必須要滿足以下四個條件
條件 | 說明 |
---|---|
Mutual exclusion | 一個資源一次只能被一個process所使用。 |
Hold and Wait | process取得一個資源之後等待其他的資源。 |
No preemption | 資源只能由process自己釋放,不能由其他方式釋放。 |
Circular wait | 每個process都握有另一個process請求的資源,導致每一個process都在等待另一個process釋放資源。 |
解決方法有2個 - deadlock prevention與deadlock avoidance。
請解釋program、process、thread彼此之間的關係,並舉例說明。
不過以Linux來說,thread(light-weighted process)跟process從kernel角度看幾乎是一樣的。
這次實作基礎的mbed OS程式,我們常需要搭載許多模組在同一個開發版上使用,若只使用一個程序性的main function,可能造成多數元件處於靜止的狀態,無法有效分配開發版的作業效能。利用這次OS的觀念,可以讓其他模組以thread的方式,保持隨時可觸發狀態,即時的操作模組,開發版資源也能被有效運用。
這次實驗主要是了解Thread跟Signal的概念,並且在實作Lab時實現多執行緒。一開始由於對於Thread如何使用不理解,所以卡住了將近2小時在研究他的執行流程,Thread.start()
後會一直不斷處於Idle狀態並且等待Signal後執行相應Method。原本認為Signal Flag的設定是類似密碼的概念,但是其實只是讓Stm32判定是要讓哪個Thread執行動作,在Method裡面還是要自行處理後判定何時讓Thread回到Idle狀態。
這次實驗只有3個實作,內容較簡單,學習創建新的thread與用signal(用來告知process有一個event發生)去觸發指定的thread運作。multi-thread programming是個寫程式很進階的topic,有很多需要注意的問題,像是2個執行緒搶同一份資源、如何解決deadlock,這部分可能未來需要修作業系統等課程比較能深刻了解,就本此實驗而言,算是對multi-thread一個很粗淺的了解,因為我們也沒有相關的知識背景。