999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于STM32的mbedOS線程信號剖析

2022-02-15 07:00:30王浩波王宜懷劉長勇劉中華
計算機工程與設計 2022年1期
關鍵詞:設置信號

王浩波,王宜懷,劉長勇,劉中華

(1.蘇州大學 計算機科學與技術學院,江蘇 蘇州 215006; 2.武夷學院 數(shù)學與計算機學院,福建 武夷山 354300)

0 引 言

實時操作系統(tǒng)RTOS[1](real time operation system)是一種具備較高實時性及穩(wěn)定性的嵌入式系統(tǒng)。一個復雜的嵌入式系統(tǒng)整體功能可以在RTOS的支持下,通過任務間通信的方式保證各個任務間能協(xié)調(diào)有序、互不沖突地同步運行。線程信號作為RTOS的同步與通信方式中最基本的一種,用來通知線程發(fā)生了異步事件,進而實現(xiàn)線程間消息傳遞。截至目前,也有少數(shù)學者在線程信號響應機制原理方面展開研究。例如,uClinux實時操作系統(tǒng)是通過信號屏蔽字的方式實現(xiàn)任務間協(xié)同管理與控制[2]。而Vxworks的任務間同步與通信是在軟件信號[3]設立的基礎上完成。eCOS則是利用條件變量來完成任務間的通信[4]。

但是,這些研究僅針對線程信號的調(diào)用算法或應用展開研究,而對RTOS內(nèi)部的線程信號響應原理、響應時間性能或運行流程并未介紹,不足以讓讀者深刻理解同步與通信原理機制。為此,通過對RTOS的線程信號通信原理、響應流程以及其它關鍵技術要點的分析,在此基礎上提出基于printf方法輸出線程信號響應機制流程的剖析方法,以STM32L431芯片為例,在mbedOS測試工程中不僅給出了printf輸出語句的加入位置及方法,同時也對線程信號內(nèi)部響應機制流程及時間進行了系統(tǒng)分析[5]。結果分析表明,將線程信號內(nèi)部整個響應機制流程信息通過printf方法輸出顯示在PC機中,不僅有助于讀者從更加微觀的層面來理解同步與通信原理機制,也為深入理解或設計新的RTOS提供了重要的理論研究基礎。

1 線程信號響應機制原理及關鍵技術要點

在RTOS的同步與通信機制中,相比于通過事件字來表達多種可能的邏輯結果,線程信號是最簡單的同步手段,常應用于協(xié)調(diào)任務間或中斷與任務間的通信、僅表達某一具體的情況而無需傳遞數(shù)據(jù)的場景。

1.1 線程信號的作用及響應機制原理

線程信號作為線程間通信的重要媒介之一,用來通知線程發(fā)生了異步事件,操作系統(tǒng)內(nèi)核也可以因為內(nèi)部事件而給線程發(fā)送信號,通知線程發(fā)生了某個事件,在mbedOS中采用線程信號、eCOS中采用條件變量、uClinux中采用信號屏蔽字、Vxworks中采用軟件信號的方式來實現(xiàn)。

若兩個任務間的同步與通信是通過線程信號的方式來實現(xiàn),則其中必定會有一個任務通過某種方式在等待該線程信號,同時另外一個任務則采用某種方式或函數(shù)設置具體的線程信號值,例如在mbedOS中,線程調(diào)用signal_wait函數(shù)等待一個線程信號,實際上是將所要等待的線程信號值記錄在線程控制塊的waitFlags變量中;在uClinux實時操作系統(tǒng)中,等待信號的產(chǎn)生由sigwait函數(shù)完成;Vxworks則是在程序執(zhí)行到sig_suspend這一函數(shù)處,系統(tǒng)掛起當前任務并等待具體的軟件信號值;而eCOS在等待條件變量前會先調(diào)用cyg_cond_wait這一函數(shù)。這個時候任務狀態(tài)由就緒態(tài)切換為阻塞態(tài),并從就緒隊列移出再放到等待隊列中。之后會在另一任務設置線程信號值,如mbedOS通過調(diào)用線程設置函數(shù)signal_set設置線程信號值,實際是將要設置的具體線程信號值記錄在線程控制塊的threadFlags變量中;uClinux向特定的任務發(fā)送信號前會先調(diào)用signal函數(shù);Vxworks在kill函數(shù)的作用下,向特定的任務發(fā)送具體的信號值;而eCOS喚醒所有等待條件變量前,會事先調(diào)用cyg_cond_broadcast或cyg_cond_signal函數(shù),可分別喚醒多個或一個等待該條件變量的線程。之后它們會在各自的線程信號設置處判斷其中是否有等待具體信號值的任務或線程,若有則將其狀態(tài)由阻塞態(tài)切換為就緒態(tài),并從等待隊列移出再放到就緒隊列中。4種操作系統(tǒng)的線程信號調(diào)度對比過程如圖1所示。

圖1 4種操作系統(tǒng)的線程信號調(diào)度對比過程

1.2 線程信號響應機制的關鍵技術要點

在線程信號響應機制的過程中,會涉及到線程信號的等待、線程信號的產(chǎn)生、線程信號的存儲、線程信號的識別、線程信號的響應以及線程信號的調(diào)度等關鍵技術要點。

(1)線程信號的等待:其定義請參見文獻[6];

(2)線程信號的產(chǎn)生:即指明線程信號由誰負責設置,在什么時間以及什么位置被設置,設置的線程信號值是多少;

(3)線程信號的存儲:即線程信號被設置完成后,指明線程信號值存儲的時間和存儲位置;

(4)線程信號的識別:線程信號被存儲后,指明線程信號被識別的時間和識別對象;

(5)線程信號的響應:其定義請參見文獻[6];

(6)線程信號的調(diào)度:其定義請參見文獻[6]。

2 基于printf方法分析線程信號響應機制原理

若任務間的同步與通信機制是通過線程信號的方式來實現(xiàn),則其內(nèi)部等待和設置線程信號的過程通常是隱藏在內(nèi)核程序中,通過printf措施將線程信號內(nèi)部響應的中間流程信息直觀地顯示在PC機中并加以剖析,可以幫助讀者捋清線程信號響應的整個脈絡結構,加深對該同步與通信方式的理解。

2.1 printf輸出可行性分析

要理解線程信號響應機制的過程,可以通過以下3種方法。第一種是直接查看源程序的方法,直接根據(jù)程序代碼含義來分析整個程序的執(zhí)行流程,該方法對于無操作系統(tǒng)程序或單一程序的分析是可行的[6]。但對RTOS而言,程序的執(zhí)行是非靜態(tài)且并非一次性運行完成,而是由RTOS根據(jù)調(diào)度策略(mbedOS中采用優(yōu)先級搶占以及時間片輪詢調(diào)度策略)對任務進行動態(tài)調(diào)度。因此,直接分析源程序這種靜態(tài)的方式很難模擬出RTOS輪詢調(diào)度的動態(tài)過程[7]。第二種是通過斷點調(diào)試手段,即在需要調(diào)試的語句上進行斷點設置,通過單步跟蹤的方式逐語句分析線程信號響應流程。但在有RTOS的情況下,其內(nèi)部會存在一個定時器中斷,該中斷會在每個時間嘀嗒到來時自動運行,若采取斷點調(diào)試的措施,則無法進入到定時器中斷內(nèi)部進行語句分析,也就無法分析線程信號的響應機制。還有一種是printf輸出方法,printf調(diào)試方法[8]作為動態(tài)分析的最原始形式之一,被廣泛應用在各個領域中。例如:在CPU仿真技術中通過printf方法可以打印輸出調(diào)試信息;在計算機視覺應用中通過printf調(diào)試方法將中間過程信息打印輸出;還可以在程序功能分析過程中采用printf調(diào)試方法輸出程序錯誤信息。因此,借鑒類PC機的printf調(diào)試方法,不但能夠實現(xiàn)將線程信號響應過程的各種狀態(tài)動態(tài)地輸出顯示在PC機中,也有助于更好地剖析線程信號響應機制的內(nèi)部過程。

2.2 printf插入法分析

為更好地剖析線程信號響應機制過程,可以考慮從以下兩個方面插入相應的printf語句輸出過程信息以及響應時間。

線程信號整個響應流程信息輸出注重的是任務狀態(tài)的變化、任務處于哪個隊列、任務是怎樣進出隊列的、等待的線程信號是否發(fā)生改變以及在哪里被設置。因此,printf語句應該插入在調(diào)用線程信號等待、設置以及任務進出各種列表函數(shù)的前后等位置,這樣可以輸出各種狀態(tài)信息。

在剖析RTOS線程信號機制的響應時間時,應著重考慮線程信號響應的快慢和耗費的時間長短。在這一過程中,printf語句的執(zhí)行也需花費一定的執(zhí)行時間:由于主控芯片STM32L431采用的是48 MHz的內(nèi)核時鐘頻率,故通過printf調(diào)試手段打印輸出一個字符約需77 μs,由此可算出所有printf執(zhí)行的時間。按照無損檢測[9]的要求規(guī)定:待檢測對象性能的完整性不可以受到所選用的檢驗技術及檢測設備的干擾。因此,此處可以通過代碼插樁的方法來測試響應時間性能,即采用變量記錄響應時間并在任務獲得響應時才利用printf方式輸出顯示時間信息,而不是在源程序中所有位置都插入printf語句,通過這種方式才可以比較準確地計算出線程信號響應整個過程的時間。將任務執(zhí)行到線程信號等待語句signal_wait處的時刻設置為T0, 標志線程信號等待開始。將任務執(zhí)行到線程信號值設置語句signal_set處的時刻設置為T1, 標志線程信號的產(chǎn)生。將任務執(zhí)行到線程信號存儲語句處的時刻設置為T2, 標志該線程信號進入存儲待識別階段。將任務執(zhí)行到線程信號被識別語句處的時刻設置為T3, 標志該線程信號進入到被識別階段。將任務執(zhí)行到線程信號由被識別到進入就緒隊列語句處的時刻設置為T4。 最后將任務執(zhí)行到由就緒隊列取出到被RTOS調(diào)度語句處的時刻設置為T5。 完成上述時間刻度設置之后,便可以計算出線程信號在各個周期的時間差值:線程信號由產(chǎn)生到存儲為 (T2-T1)、 由存儲到被識別為 (T3-T2)、 由識別再到響應為 (T4-T3) 以及由等待線程信號到再次被mbedOS[10]調(diào)度執(zhí)行的時間間隔為 (T5-T0)。

3 mbedOS的線程信號響應分析與實踐

mbedOS是ARM公司在2014年推出的一款免費的、跨平臺的、專為物聯(lián)網(wǎng)(IoT)中的“事物”而設計的輕量級開源嵌入式操作系統(tǒng),不僅具備一般RTOS的基本功能,開發(fā)設計人員還可以在低成本開發(fā)板上快速構建IoT應用原型[11],被廣泛應用在物聯(lián)網(wǎng)設備平臺[12]以及通信與安全訪問服務機制[13]等領域。下面將通過實踐分析mbedOS的線程信號響應機制。

3.1 選擇printf插入位置

對線程信號響應機制的分析,主要在于要選擇好printf語句的插入位置,這樣才能輸出響應過程的關鍵信息。

(1)在線程信號等待語句“Thread::signal_wait(GREEN_SIGNAL)”前后位置加入相應的printf語句,用來顯示線程在等待線程信號前和獲得線程信號后的關鍵信息,在該語句之后用T5記錄線程被調(diào)度的時刻;在線程信號設置語句“thd_greenlight.signal_set(GREEN_SIGNAL)”的前后位置加入相應的printf輸出信息,則可以顯示設置線程信號值前后的狀態(tài)變化信息,并在該語句之前用T1記錄線程信號產(chǎn)生的時刻。

(2)在“thread->waitFlags=flag”前后位置加入相應的printf語句,用來輸出當前線程信號等待標志waitFlags值的變化情況,并在“osRtxThreadDelayInsert(thread, timeout)”語句之前用T0記錄線程開始等待線程信號時刻;然后在“threadFlags = threadFlagSet(thread,flag)”這一語句后面加入對應的printf輸出語句,并用T2記錄線程信號存儲的時刻。

(3)在延時等待隊列移除線程函數(shù)osRtxThreadDelayRemove之前可用T3記錄識別到等待線程信號的具體線程的時刻;在線程進隊函數(shù)osRtxThreadReadyPut之后可用T4記錄將等待線程信號的線程放入到就緒隊列的時刻。

(4)除此之外,還可以在線程移出函數(shù)osRtxThreadWaitExit、線程延時等待函數(shù)osRtxThreadWaitEnter等前后位置加入對應的printf輸出信息,不僅可以直觀地跟蹤程序運行狀態(tài),還可以顯示線程進出各種隊列的變化情況。

3.2 響應時間性能及關鍵代碼分析

mbedOS作為一款廣泛應用于物聯(lián)網(wǎng)平臺的實時操作系統(tǒng),其內(nèi)部通過兩種機制來設置線程信號:第一種機制是在某個線程中等待線程信號,在另一線程中通過觸發(fā)SVC中斷來設置線程信號;第二種機制是在某個線程中等待線程信號,而設置具體的線程信號值則是通過PendSV中斷機制來實現(xiàn)。為準確測試出線程信號的響應時間,可以在mbedOS測試樣例工程中只設定包含兩個優(yōu)先級相同的線程,即藍燈線程和綠燈線程,并運行在STM32L431微控制器上。mbedOS內(nèi)部的定時器中斷SysTick是通過時間嘀嗒的方式來產(chǎn)生中斷,即每個時間嘀嗒(1 ms)可以產(chǎn)生一次中斷,對應SysTick中的計數(shù)器需要計數(shù)48 000次(STM32L431芯片內(nèi)核時鐘頻率是48 MHz,計數(shù)器采用減1的方式進行計數(shù));而在線程的優(yōu)先級相同的情況下,mbedOS是利用時間片輪詢調(diào)度策略來選擇某個線程進行調(diào)度,即每個時間片大小為5個時間嘀嗒。實時性能的軟件測試[14]作為一個設計和考核實時操作系統(tǒng)性能的重要方法之一,主要是通過系統(tǒng)調(diào)用的方式來獲得操作系統(tǒng)內(nèi)核中任意兩處代碼執(zhí)行的時間間隔。本文采用SVC中斷的方式來分析線程信號的響應時間,主要有:線程信號由產(chǎn)生到存儲 (T2-T1)、 由存儲到被識別 (T3-T2)、 由識別再到響應 (T4-T3) 以及由等待線程信號到再次被mbedOS調(diào)度執(zhí)行的時間間隔 (T5-T0)。 測試方法是在時間嘀嗒中斷服務例程SysTick_Handler函數(shù)中將全局變量TimerCount(用來記錄SysTick中斷次數(shù))加1,即先取得TimerCount變量存放的絕對地址,然后給該地址存放的內(nèi)容執(zhí)行加1操作再重新賦值給該地址,通過比較不同時刻的Systick中斷計數(shù)值VAL以及中斷次數(shù)SUM(由TimerCount變量值的大小決定),采用Δt公式計算求得實際執(zhí)行時間,即線程信號在某個執(zhí)行過程需耗費實際時間的計算公式為: Δt=Tend-Tbegin=((VALbegin-VALend)+48000*(SUMend-SUMbegin))/48(μs)。 表1給出了基于SVC中斷的線程信號響應時間分析情況,其中 (T2-T1)、 (T3-T2)、 (T4-T3) 的響應時間都較短,在8 μs之內(nèi),說明線程信號作為同步與通信手段能滿足實時性的要求。而綠燈線程由等待線程信號到再次被調(diào)度執(zhí)行的時間都在5 ms~6 ms之內(nèi),則可以說明在線程優(yōu)先級相同的情況下,mbedOS實時操作系統(tǒng)是采用時間片輪詢的方式來對線程進行調(diào)度,響應時間同樣也比較快,實時性要求能得到滿足。

表1 基于SVC中斷的線程信號響應時間分析

基于篇幅的有限性,這里僅給出測試線程信號由產(chǎn)生到存儲 (T2-T1) 過程中的關鍵代碼,其余各時間段的測試流程分析與此類似。

(1)在時間嘀嗒中斷服務例程處理函數(shù)SysTick_Handler中設置SysTick中斷次數(shù)累加的關鍵代碼如下:

SysTick_Handler:

//棧指針(MSP或PSP)和LR(EXC_RETURN)入棧

PUSH {R0,LR}

ldr r2,=0x20001884

ldr r3,[r2]

adds r3,r3,#1

str r3,[r2]

//調(diào)用SysTick中斷服務例程osRtxTick_Handler

BL osRtxTick_Handler

//R0←堆棧中保存的R0;

//LR←堆棧中保存的LR(EXC_RETURN)

POP {R0,LR}

代碼段分析:其中0x20001884是全局變量TimerCount(用來記錄SysTick中斷次數(shù))編譯后的地址,可通過編譯后生成的Debug目錄文件下的.map文件找到該地址,先將該地址存放的數(shù)據(jù)賦值給寄存器r3,再將自加1后的數(shù)據(jù)存放回原地址即可實現(xiàn)每次觸發(fā)SysTick中斷時次數(shù)累加1。

(2)在藍燈線程調(diào)用signal_set函數(shù)之前記為T1時刻的關鍵代碼:

//T1時刻

n0=TimerCount;

v0=SysTick->VAL;

//設置綠燈信號

thd_greenlight.signal_set(GREEN_SIGNAL);

代碼段分析:n0用來記錄T1時刻觸發(fā)的SysTick中斷次數(shù);v0則記錄T1時刻Systick的計數(shù)值VAL, GREEN_SIGNAL是綠燈等待的線程信號值,大小為0x47。這個值的大小可以在宏定義處自己設定。

(3)在SVC實際處理線程信號設置函數(shù)svcRtxThreadFlagSet中,線程信號值被賦值給threadFlags變量之后記為T2時刻的關鍵代碼:

//(2)設置線程信號值

threadFlags = ThreadFlagSet(thread, flag);

//T2時刻

n5=TimerCount;

v5=SysTick->VAL;

if(v5>v0)

printf("%d ",v0-v5+(n5-n0)*48000);

else

printf("%d ",v0-v5);

代碼段分析:調(diào)用ThreadFlagSet函數(shù)將對應線程(綠燈線程)的線程信號值設置為0x47,并存儲在threadFlags變量中,n5用來記錄T2時刻觸發(fā)的SysTick中斷次數(shù);v5則記錄T2時刻Systick的計數(shù)值VAL。

4 mbedOS的線程信號響應流程

mbedOS線程信號響應機制的測試樣例程序是基于Cortex-M4F內(nèi)核的STM32L431微控制器和STM32CubeIDE 1.0.0集成開發(fā)環(huán)境進行的。STM32L431采用的是256 KB的片內(nèi)Flash和64 KB的靜態(tài)隨機存儲器SRAM,F(xiàn)lash主要用于程序代碼及中斷向量表的存儲,而片內(nèi)RAM主要用于各類變量的存儲[15]等。芯片采用LQFP-64封裝,不僅具有豐富的功能模塊:包括GPIO引腳、ADC模塊、PWM定時器等,還包含具備強大運算能力的浮點運算單元FPU。STM32L431微控制器不僅包括ARM Cortex-M4F內(nèi)核以及各種外設、存儲器模塊,還包含了高性能系統(tǒng)和外設兩種總線。另外,STM32L431微控制器還提供可擴展總線用來連接其它外圍設備,其結構如圖2所示。

圖2 STM32L431微控制器結構

4.1 功能設計與流程分析

本文用到的測試工程的功能主要是在mbedOS啟動后通過主線程來創(chuàng)建3個相同優(yōu)先級的用戶線程,分別是藍燈線程、綠燈線程以及紅燈線程。然后在綠燈線程中調(diào)用signal_wait函數(shù)等待綠燈線程信號(GREEN_SIGNAL),從而實現(xiàn)綠燈的亮暗切換;而藍燈線程則是通過調(diào)用signal_wait函數(shù)來等待藍燈線程信號(BLUE_SIGNAL),進而實現(xiàn)藍燈的亮暗切換;在紅燈線程中通過調(diào)用signal_set函數(shù)分別設置綠燈線程和藍燈線程的線程等待信號。圖3給出了mbedOS測試樣例程序的執(zhí)行流程。

圖3 mbedOS測試樣例程序的執(zhí)行流程

在測試程序中,當程序執(zhí)行到“Thread::signal_wait(GREEN_SIGNAL)”語句時,則表示此時綠燈線程需要等待綠燈線程信號(GREEN_SIGNAL),綠燈線程阻塞被放入到等待隊列中。當測試程序執(zhí)行到“thd_greenlight.signal_set(GREEN_SIGNAL)”語句時,則相當于此時向綠燈線程發(fā)送了一個線程信號,綠燈線程收到該信號后,會將之前阻塞的綠燈線程從等待隊列移出并放入到就緒隊列中,由mbedOS通過時間片輪詢的調(diào)度策略,將線程狀態(tài)由阻塞態(tài)更改為激活態(tài),并進行上下文切換,然后執(zhí)行后續(xù)的語句,即執(zhí)行gpio_reverse(LIGHT_GREEN)語句實現(xiàn)切換綠燈亮暗。藍燈線程的運行流程與綠燈線程一樣。

4.2 時序剖析

在STM32L431微控制器的基礎上,以測量有關的確定性時序分析[16]方法為例。即在mbedOS測試工程中的對應語句前后位置插入printf來輸出信息,圖4給出了基于線程信號工作原理的線程調(diào)度過程時序圖。

結合前面內(nèi)容分析,可以將線程信號響應的流程分析大致分為以下9個步驟,基于篇幅局限性的原因,本文僅給出與綠燈線程相關的printf輸出信息。其中,藍燈線程的地址是20001774,綠燈線程的地址是20001834,紅燈線程的地址是200016B4,定時器線程的地址是2000136C,空閑線程地址是20001328,缺省處理函數(shù)DefaultISR的地址是8001A21。而地址200001E4表示等待隊列,地址200001D0表示就緒隊列。

(1)啟動線程

從芯片上電到操作系統(tǒng)的啟動,其中包括上電復位及mbedOS啟動兩大部分,在mbedOS啟動后,測試程序會先執(zhí)行對應的主線程函數(shù)app_init,由該函數(shù)依次創(chuàng)建紅燈、綠燈和藍燈3個用戶線程,接著啟動這3個用戶線程,然后主線程被阻塞[17]。此時,CPU的控制權交由mbedOS內(nèi)核,開始對用戶線程的調(diào)度,即取出并激活就緒隊列中優(yōu)先級最高的紅燈線程運行。

(2)綠燈線程等待綠燈信號

mbedOS內(nèi)部的SysTick中斷會每隔1 ms中斷一次并按照每個時間片(5 ms)為周期的方式對線程進行輪詢調(diào)度,此時綠燈線程被激活,并通過執(zhí)行“Thread::signal_wait(GREEN_SIGNAL)”語句來等待綠燈信號GREEN_SIGNAL(0x47),在執(zhí)行該語句的過程中,由于綠燈信號此時還未產(chǎn)生,綠燈線程狀態(tài)會從激活態(tài)轉換成為阻塞態(tài),并移入等待隊列中,同時,從就緒隊列中取出優(yōu)先級最高的紅燈線程激活運行。

printf輸出結果如下:

2.當前運行的線程=20001834(綠燈)開始。

2-1.當前運行的線程=20001834(綠燈)調(diào)用signal_wait(GREEN_SIGNAL)等待線程信號0x47。

2-1-1.設置前當前運行線程=20001834的等待標識=0

5-1.調(diào)用osRtxThreadWaitEnter前等待隊列=200001E4中的線程: 2000136C->0->8001A21

5-2.調(diào)用osRtxThreadWaitEnter前就緒隊列=200001D0中的線程: 20001774->200016B4->20001328

6-1.調(diào)用osRtxThreadWaitEnter->osRtxThreadDelayInsert將當前運行線程=20001834放到等待隊列

6-2.調(diào)用osRtxThreadWaitEnter->osRtxThreadListGet從就緒隊列獲取優(yōu)先級最高的線程=20001774

6-3.調(diào)用osRtxThreadWaitEnter->osRtxThreadSwitch將線程=20001774設置為激活態(tài)準備運行

7-1.調(diào)用osRtxThreadWaitEnter后等待隊列:2000136C->20001834->0

7-2.調(diào)用osRtxThreadWaitEnter后就緒隊列: 200016B4->20001328->0

(3)藍燈線程等待藍燈信號

藍燈線程通過執(zhí)行“Thread::signal_wait(BLUE_SIGNAL)”語句來等待藍燈信號BLUE_SIGNAL(0x42),在執(zhí)行該語句的過程中藍燈線程狀態(tài)由激活態(tài)更改為阻塞態(tài),放入到等待隊列中,然后取出就緒隊列中優(yōu)先級最高的紅燈線程,并將其激活運行。

(4)紅燈線程設置綠燈信號

在紅燈線程中通過調(diào)用“thd_greenlight。signal_set(GREEN_SIGNAL)”函數(shù)來設置綠燈信號,此時mbedOS會將綠燈線程由等待隊列移出并將其放入到就緒隊列中。基于線程優(yōu)先級相同的原因,此時綠燈線程并不會搶占當前正在運行的藍燈線程,而是會在SysTick中斷中通過輪詢調(diào)度的方式將綠燈線程激活運行。

printf輸出結果如下:

1-1.當前運行的線程=200016B4 (紅燈),調(diào)用signal_set(GREEN_SIGNAL)設置綠燈等待線程信號0x47。

1-1-1.線程信號設置前的值=0

1-1-2.線程信號設置后的值=47

8-1.調(diào)用osRtxThreadWaitExit前等待隊列=200001E4中的程:2000136C->20001834->20001774

8-2.調(diào)用osRtxThreadWaitExit前就緒隊列=200001D0中的線程:20001328->0->8001A21

9-1.調(diào)用osRtxThreadWaitExit->osRtxThreadDelayRemove將線程=20001834從等待隊列中移出

9-2.調(diào)用osRtxThreadWaitExit->osRtxThreadReadyPut->osRtxThreadListPut將線程=20001834放到放到就緒隊列

10-1.調(diào)用osRtxThreadWaitExit后等待隊列:2000136C->20001774->0

10-2.調(diào)用osRtxThreadWaitExit后就緒隊列=200001D0中的線程:20001834->20001328->0

11.調(diào)用signal_set()結束。

(5)輪詢調(diào)度激活綠燈線程

在藍燈線程中設置完綠燈信號后,mbedOS內(nèi)部機制的SysTick中斷會每隔1 ms中斷一次并按照每個時間片(5 ms)為周期的方式對線程進行輪詢調(diào)度,此時將激活綠燈線程運行。

printf輸出結果如下:

12.進入SysTick_Handler觸發(fā)osRtxTick_Handler對優(yōu)先級相同的線程進行輪詢調(diào)度,將線程=20001834切換為激活態(tài)。

(6)綠燈線程獲得綠燈信號

綠燈線程在獲得綠燈信號后,會從等待隊列移出進入就緒隊列,然后被激活運行,實現(xiàn)切換綠燈亮暗,即執(zhí)行“Thread::signal_wait(GREEN_SIGNAL)”后續(xù)的語句。然后綠燈線程開始等待下一次的線程信號(即重復4-7步,如圖4所示),再激活紅燈線程運行。

printf輸出結果如下:

2-2.當前運行的線程=20001834(綠燈)已等到線程信0x47,綠燈反轉。

2.當前運行的線程=20001834(綠燈)結束。

(7)紅燈線程設置藍燈信號

在紅燈線程中通過調(diào)用“thd_bluelight.signal_set(BLUE_SIGNAL)”函數(shù)來設置藍燈信號,此時mbedOS會將藍燈線程從等待隊列移出,此時線程狀態(tài)會由阻塞態(tài)更換為就緒態(tài),并放入到就緒隊列中。由于mbedOS對優(yōu)先級相同的線程采用輪詢調(diào)度策略,此時藍燈線程并不會搶占當前正在運行的紅燈線程,而是會在SysTick中斷中通過輪詢調(diào)度的方式將藍燈線程激活運行。

(8)輪詢調(diào)度激活藍燈線程

在紅燈線程中設置完藍燈信號后,mbedOS內(nèi)部機制的SysTick中斷會每隔1 ms中斷一次并按照每個時間片(5 ms)為周期的方式對線程進行輪詢調(diào)度,此時將會激活藍燈線程運行。

(9)藍燈線程獲得藍燈信號

藍燈線程獲得藍燈信號后執(zhí)行“Thread::signal_wait(BLUE_SIGNAL)”后續(xù)的語句,實現(xiàn)切換藍燈亮暗。然后藍燈線程開始新一輪的等待信號(即重復9-13步,如圖4所示),再激活紅燈線程運行。

5 結束語

本文闡述了mbedOS同步與通信手段——線程信號的響應機制,并在STM32L431微控制器上進行實驗測試,通過printf調(diào)試手段將線程信號工作原理的整個調(diào)度過程信息輸出到PC機中,并在mbedOS測試工程中以時序圖的方式進行分析總結。可以讓讀者更加透明地理解線程信號響應的整個脈絡結構,不僅有助于從微觀的層面來理解RTOS的調(diào)度過程。同時,也為進一步剖析RTOS的其它同步與通信方式提供了方法借鑒。后續(xù)將進一步對RTOS的其它同步與通信方式進行理解與分析。

猜你喜歡
設置信號
中隊崗位該如何設置
少先隊活動(2021年4期)2021-07-23 01:46:22
信號
鴨綠江(2021年35期)2021-04-19 12:24:18
完形填空二則
7招教你手動設置參數(shù)
孩子停止長個的信號
基于LabVIEW的力加載信號采集與PID控制
本刊欄目設置說明
中俄臨床醫(yī)學專業(yè)課程設置的比較與思考
一種基于極大似然估計的信號盲抽取算法
艦船人員編制的設置與控制
主站蜘蛛池模板: 丝袜高跟美脚国产1区| 日韩欧美色综合| 国产精品lululu在线观看| 在线国产91| 波多野结衣一区二区三区AV| 亚洲床戏一区| 国产打屁股免费区网站| 五月激情综合网| 欧美日韩一区二区在线播放| 波多野结衣视频网站| 日韩无码视频网站| 天堂网国产| 青草视频免费在线观看| 99这里只有精品6| 日韩专区第一页| 免费人欧美成又黄又爽的视频| 亚洲女人在线| 欧美日韩国产精品综合| 中文字幕乱码中文乱码51精品| 99热这里只有精品免费国产| www亚洲天堂| 亚洲高清中文字幕| 再看日本中文字幕在线观看| 91视频青青草| 欧美日韩激情在线| 中日无码在线观看| 亚洲αv毛片| 就去色综合| 精品无码日韩国产不卡av| 国产在线观看一区二区三区| 亚洲成A人V欧美综合天堂| 999精品免费视频| 亚洲国产成熟视频在线多多| 国产原创演绎剧情有字幕的| aⅴ免费在线观看| 精品福利网| 97色婷婷成人综合在线观看| 国产网站免费看| 天堂在线视频精品| 1024国产在线| 亚洲美女操| 久青草免费视频| 在线亚洲天堂| 欧美无专区| 任我操在线视频| 国产精品视频白浆免费视频| 成人午夜精品一级毛片| 97在线免费| 午夜国产在线观看| 日韩无码视频播放| 亚洲天堂视频网站| 久久特级毛片| 8090成人午夜精品| 国内精品视频| 午夜成人在线视频| 国产网友愉拍精品| 丁香六月激情综合| 成年网址网站在线观看| 久久精品日日躁夜夜躁欧美| 久久国产精品电影| 欧美亚洲日韩中文| 青草精品视频| 国产人成乱码视频免费观看| 国产精品hd在线播放| 精品无码国产自产野外拍在线| 巨熟乳波霸若妻中文观看免费| 国产天天色| 狠狠色狠狠综合久久| 一级看片免费视频| 97青青青国产在线播放| 久久黄色毛片| 亚洲欧美色中文字幕| 国产一在线| 91精品国产情侣高潮露脸| 欧美一级专区免费大片| 精品欧美视频| 日韩AV无码一区| 日本精品视频| 99国产精品免费观看视频| 国产精品一区二区国产主播| 伦精品一区二区三区视频| 国产黄在线观看|