0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

RT-Thread啟動(dòng)進(jìn)入就緒態(tài)最高優(yōu)先級(jí)線程的全過(guò)程與棧幀分析(下)

冬至子 ? 來(lái)源:lchnu ? 作者:lchnu ? 2023-11-08 12:53 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Step 11. 繼續(xù)單步到rt_hw_context_switch_to函數(shù)處。

在rt_system_scheduler_start函數(shù)中,會(huì)依次獲取最高優(yōu)先級(jí)線程的線程控制塊,將其復(fù)制給to_thread。如圖所示,在表達(dá)式窗口的to_thread就是main線程。

&to_thread->spthread->sp的地址,在Debug中,地址編號(hào)為0x200010C8,即0x200010C8內(nèi)存單元中存放的數(shù)據(jù)是0x200018F4。

1.jpg

Q2. 在單獨(dú)進(jìn)入到rt_hw_context_switch_to之前,觀察輸出結(jié)果,main線程被remove。為什么在啟動(dòng)調(diào)度器的函數(shù)中,要先將線程從就緒列表中移除呢?

A2. 下一步要啟動(dòng)main線程,將其從Ready狀態(tài)變成Running狀態(tài),所以需要將該線程從就緒列表中刪除,RT-Thread后續(xù)在調(diào)度時(shí)暫時(shí)不考慮該線程,直到該線程狀態(tài)再次從Running發(fā)生變化。

1.jpg

Step 12. 單步到進(jìn)入到rt_hw_context_switch_to函數(shù)處,該函數(shù)位于context_gcc.S文件,由匯編語(yǔ)言編寫實(shí)現(xiàn)。

rt_hw_context_switch_to僅僅在調(diào)度器啟動(dòng)時(shí)運(yùn)行一次。該函數(shù)的C語(yǔ)言實(shí)現(xiàn)接口中,有一個(gè)參數(shù),傳入thread->sp變量的地址。

對(duì)于參數(shù)個(gè)數(shù)不大于4的C語(yǔ)言接口函數(shù),編譯器會(huì)按參數(shù)在列表中的順序,自左向右 為參數(shù)分配寄存器r0-r3。
對(duì)于參數(shù)個(gè)數(shù)大于4的C語(yǔ)言接口函數(shù),編譯器會(huì)按參數(shù)在列表中的順序,多余參數(shù)按自右向左的順序壓入棧中,即參數(shù)入棧順序與參數(shù)順序相反。

如上述Tips,thread->sp的地址通過(guò)r0傳遞。在下圖左側(cè)寄存器窗口中,可以看到r0的值為0x200010C8。

165行,將變量rt_interrupt_to_thread變量的地址賦值給r1。

165行,將r0的值賦值給r1指向的單元,即將r0的值賦值給變量rt_interrupt_to_thread。如果此時(shí)在表達(dá)式窗口觀察rt_interrupt_to_thread,會(huì)發(fā)現(xiàn)它的值為0x200010C8。

1.jpg

此時(shí),main線程的線程結(jié)構(gòu)體和線程??臻g不變,但是r0, r1, rt_interrupr_to_thread的內(nèi)容均發(fā)生了變化。

1.jpg

對(duì)于rt_hw_context_switch_to函數(shù)的其他行,依次分析如下:

168行至172行,處理浮點(diǎn)寄存器入??刂?,與Cortex M4內(nèi)核的Lazy Stacking有關(guān),但與本文主線無(wú)關(guān),不做探討。

176至178行,將rt_interrupt_from_thread變量清零。因此本次是RT-Thread第一次調(diào)度最高優(yōu)先級(jí)線程,只有to,沒有from。

181至183行,將rt_thread_switch_interrupt_flag變量至1,該值將在PendSV中斷中使用。
186-194行,設(shè)置SysTick和PendSV中斷的優(yōu)先級(jí),且觸發(fā)PendSV,但現(xiàn)在不跳轉(zhuǎn),因?yàn)橹袛酁榻埂?/p>

197-201行,很有意思的一段操作,將0x08000000處的棧頂指針?lè)胖玫組SP中,相當(dāng)于特權(quán)模式的棧頂指針復(fù)位了。CPU從匯編編寫的啟動(dòng)代碼,直到運(yùn)行到此處,均在特權(quán)模式下運(yùn)行,使用MSP作為棧頂指針。將來(lái)切換到線程后,會(huì)以PSP作為棧頂指針。啟動(dòng)流程不會(huì)重來(lái)一次,也沒有任何函數(shù)再需要返回。所以,對(duì)于截止到目前使用的MSP棧,可以舍棄棧中的數(shù)據(jù),MSP棧重置。

204-205行,使能中斷。首先在context_gcc.S的89行設(shè)置斷點(diǎn),然后當(dāng)PC運(yùn)行在204行時(shí)按F5,會(huì)運(yùn)行至PendSV中斷服務(wù)程序。

1.jpg

Step 13. PendSV函數(shù)分析。

在PendSV中斷服務(wù)程序中:

94行-96行,判斷rt_thread_switch_interrupt_flag的值,為0則退出,為1則繼續(xù);
99行-105行,rt_thread_switch_interrupt_flag清0,判斷rt_interrupt_from_thread的值,為0表示OS第一次進(jìn)行最高優(yōu)先級(jí)就緒狀態(tài)線程的運(yùn)行,無(wú)需恢復(fù)psp,直接跳轉(zhuǎn)到switch_to_thread;為1表示從from線程切換至to線程,需要恢復(fù)psp。Debug到此處,rt_interrupt_from_thread的值為0,是第一次進(jìn)行線程運(yùn)行。

此處直接分析127行開始的switch_to_thread部分。

128行,將rt_interrupt_to_thread的地址賦值給r1。

129行,從r1指向的地址中取出值,賦值給r1,此時(shí)r1指向到main線程的thread->sp。

130行,從r1指向的地址中取出值,賦值給r1,此時(shí)r1指向到0x200018F4,如下圖所示。

1.jpg

133行-136行,將r1指向的0x200018F4開始的單元內(nèi)容,依次裝載到r3, r4-r11中。執(zhí)行完畢后,R3中是flag的值,r4-r11中均為0xDEAFBEEF,且r1指向0x20001918。

1.jpg

139-140行,由于r3為0,浮點(diǎn)寄存器不做處理。r1保持不變。

143行,將r1的值賦值給PSP,線程棧頂指針PSP目前為0x20001918。后續(xù)PSP還會(huì)自動(dòng)更新。

1.jpg

155行,使得LR寄存器的Bit2為1,確保PendSV異常返回使用的棧指針是PSP。

156行,異常返回。此時(shí),線程棧中剩下內(nèi)容,即從0x20001918-0x20001934的內(nèi)容,會(huì)自動(dòng)加載到R0, R1, R2, R3, R12, R14 (線程返回地址), PC (線程入口地址), xPSR。且,PSP會(huì)自動(dòng)更新至0x20001938,即創(chuàng)建main線程時(shí)的棧頂指針。

1.jpg

Step 14. 光標(biāo)在BX LR上時(shí),按F5,自動(dòng)運(yùn)行到main線程入口地址main_thread_entry。

如下圖所示,棧幀中的r0-r15, xPSR均已順利從線程棧中進(jìn)行了恢復(fù),此時(shí)thread->sp = PSP = 0x20001938。開始順利執(zhí)行線程。

1.jpg

通過(guò)本文對(duì)線程啟動(dòng)過(guò)程的了解,對(duì)于兩個(gè)線程/多個(gè)線程之間的互相切換能奠定堅(jiān)實(shí)的基礎(chǔ),化繁為簡(jiǎn),結(jié)合論壇關(guān)于上下文切換的代碼注釋,能幫助快速抓住主線。

使用的軟硬件環(huán)境如下:

IDE工具 - RT-Thread Studio 2.2.6
硬件 - STM32L431RCT6,Cortex M4內(nèi)核
軟件 - RT-Thread 4.0.5版本
配置 - 僅使能main線程和tidle0線程
一、工程設(shè)置
Step 1. 新建名稱為EVBMX_RTThread405_Switch的4.0.5版本工程

Step 2. 不使能軟件定時(shí)器,使能線程狀態(tài)更改的調(diào)試

關(guān)閉軟件定時(shí)器線程,避免干擾。

Step 3. 關(guān)閉msh shell,禁用Finsh

關(guān)閉tshell線程,避免干擾。僅僅保留main線程和tidle0線程。

Step 4. 修改main函數(shù)

修改main函數(shù)后,線程進(jìn)入一次,休眠且切換1次,再次切回且return,然后徹底退出,只留下tidle0線程。

#include
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include
int main(void)
{
rt_thread_mdelay(1000);
return RT_EOK;
}
Step 5. 下載程序,觀察輸出結(jié)果

讀完全文后,對(duì)下方輸出結(jié)果的每一行語(yǔ)句所代表的含義和發(fā)生時(shí)刻,能有更深刻體會(huì)。

二、調(diào)試運(yùn)行
Step 6. 在component.c中257行按F9設(shè)置斷點(diǎn);F5全速運(yùn)行到此處后,再按F9關(guān)閉此處斷點(diǎn)。

Step 7. 依次進(jìn)入rt_thread_create, _thread_init, 停留在thread.c的164行。

將變量thread添加到表達(dá)式窗口,可以查看各個(gè)成員的值,其中,thread->stack_addr = 0x20001138, thread->stack_size = 0x800,分別表示棧底位置和??臻g大小。

164行的函數(shù)rt_hw_stack_init對(duì)于理解線程切換是一個(gè)相當(dāng)重要的函數(shù),其形參分別為:

線程入口函數(shù):main_thread_entry
線程參數(shù)RT_NULL:
線程棧棧頂?shù)刂罚簍hread->stack_addr + thread->stack_size - 4 = 0x20001138 + 0x800 - 4 = 0x20001934
Q1:為什么此處需要減4?
A2: 很有意思的一個(gè)問(wèn)題。答案可參考本人在論壇的一個(gè)回答。RT-Thread-小白求助,關(guān)于rtt 的一段源碼RT-Thread問(wèn)答社區(qū) - RT-Thread

Step 8. 單步進(jìn)入到rt_hw_stack_init函數(shù)內(nèi)部,開展分析

149行,由于傳遞進(jìn)來(lái)的stack_addr = 0x20001934,執(zhí)行完畢后,stk為0x20001938。從0x20001138(含)到0x20001934(含),合計(jì)是0x800 = 2048字節(jié)。STM32使用的滿遞減棧,所以此處的stk是0x20001938。
150行,此處設(shè)置8字節(jié)對(duì)齊。由于0x20001938 = (536877368)Decimal,該數(shù)據(jù)除8等于67109671,能被8整除,該語(yǔ)句執(zhí)行棧對(duì)齊操作后,stk依然為0x20001938。

Step 9. 繼續(xù)了解rt_hw_stack_init函數(shù)。

151行,更新stk的值,減去struct stack_frame結(jié)構(gòu)體的大小。執(zhí)行完畢后,stk = 0x200018F4。
153行,stack_frame指針指向0x200018F4。
156至159行,通過(guò)for循環(huán)將0x200018F4至0x20001938的所有內(nèi)存變成0xdeadbeaf魔法字。
161行至168行,將stack_frame成員的exception_stack_frame中的r0~psr共8個(gè)寄存器分別設(shè)置為:線程參數(shù),4個(gè)0,線程返回地址,線程入口地址,0x01000000。
175行,返回stk的值,此時(shí)變成0x200018F4。這個(gè)值在初始化線程時(shí),將返回給thread->sp,即線程棧的臨時(shí)棧頂指針。
依次將線程的形參、r1-r3, r12, 線程返回地址、線程入口地址,線程的xPSR寫入異常棧幀結(jié)構(gòu)中。
在初入門時(shí),這里是難點(diǎn)。C語(yǔ)言中使用結(jié)構(gòu)體定義的棧結(jié)構(gòu),如何和實(shí)際寄存器的順序進(jìn)行一一對(duì)應(yīng)?,后文會(huì)通過(guò)逐步Debug揭示這個(gè)問(wèn)題答案。

返回的stk指向0x200018F4部分。

至此,main線程創(chuàng)建完畢后,線程結(jié)構(gòu)體和線程??臻g如下所示。

Step 10. 繼續(xù)單步到rt_system_scheduler_start函數(shù)處,并單獨(dú)跟蹤進(jìn)入到該函數(shù)內(nèi)部。

期間,RT-Thread會(huì)調(diào)用rt_thread_idle_init函數(shù),在該函數(shù)中使用靜態(tài)創(chuàng)建方式初始化tidle0線程??梢园凑丈鲜鲞^(guò)程記錄tidle0線程的??臻g。

Step 11. 繼續(xù)單步到rt_hw_context_switch_to函數(shù)處。

在rt_system_scheduler_start函數(shù)中,會(huì)依次獲取最高優(yōu)先級(jí)線程的線程控制塊,將其復(fù)制給to_thread。如圖所示,在表達(dá)式窗口的to_thread就是main線程。
&to_thread->spthread->sp的地址,在Debug中,地址編號(hào)為0x200010C8,即0x200010C8內(nèi)存單元中存放的數(shù)據(jù)是0x200018F4。

Q2. 在單獨(dú)進(jìn)入到rt_hw_context_switch_to之前,觀察輸出結(jié)果,main線程被remove。為什么在啟動(dòng)調(diào)度器的函數(shù)中,要先將線程從就緒列表中移除呢?
A2. 下一步要啟動(dòng)main線程,將其從Ready狀態(tài)變成Running狀態(tài),所以需要將該線程從就緒列表中刪除,RT-Thread后續(xù)在調(diào)度時(shí)暫時(shí)不考慮該線程,直到該線程狀態(tài)再次從Running發(fā)生變化。

Step 12. 單步到進(jìn)入到rt_hw_context_switch_to函數(shù)處,該函數(shù)位于context_gcc.S文件,由匯編語(yǔ)言編寫實(shí)現(xiàn)。

rt_hw_context_switch_to僅僅在調(diào)度器啟動(dòng)時(shí)運(yùn)行一次。該函數(shù)的C語(yǔ)言實(shí)現(xiàn)接口中,有一個(gè)參數(shù),傳入thread->sp變量的地址。

對(duì)于參數(shù)個(gè)數(shù)不大于4的C語(yǔ)言接口函數(shù),編譯器會(huì)按參數(shù)在列表中的順序,自左向右 為參數(shù)分配寄存器r0-r3。
對(duì)于參數(shù)個(gè)數(shù)大于4的C語(yǔ)言接口函數(shù),編譯器會(huì)按參數(shù)在列表中的順序,多余參數(shù)按自右向左的順序壓入棧中,即參數(shù)入棧順序與參數(shù)順序相反。

如上述Tips,thread->sp的地址通過(guò)r0傳遞。在下圖左側(cè)寄存器窗口中,可以看到r0的值為0x200010C8。

165行,將變量rt_interrupt_to_thread變量的地址賦值給r1。
165行,將r0的值賦值給r1指向的單元,即將r0的值賦值給變量rt_interrupt_to_thread。如果此時(shí)在表達(dá)式窗口觀察rt_interrupt_to_thread,會(huì)發(fā)現(xiàn)它的值為0x200010C8。

此時(shí),main線程的線程結(jié)構(gòu)體和線程??臻g不變,但是r0, r1, rt_interrupr_to_thread的內(nèi)容均發(fā)生了變化。

對(duì)于rt_hw_context_switch_to函數(shù)的其他行,依次分析如下:

168行至172行,處理浮點(diǎn)寄存器入??刂疲cCortex M4內(nèi)核的Lazy Stacking有關(guān),但與本文主線無(wú)關(guān),不做探討。
176至178行,將rt_interrupt_from_thread變量清零。因此本次是RT-Thread第一次調(diào)度最高優(yōu)先級(jí)線程,只有to,沒有from。
181至183行,將rt_thread_switch_interrupt_flag變量至1,該值將在PendSV中斷中使用。
186-194行,設(shè)置SysTick和PendSV中斷的優(yōu)先級(jí),且觸發(fā)PendSV,但現(xiàn)在不跳轉(zhuǎn),因?yàn)橹袛酁榻埂?br /> 197-201行,很有意思的一段操作,將0x08000000處的棧頂指針?lè)胖玫組SP中,相當(dāng)于特權(quán)模式的棧頂指針復(fù)位了。CPU從匯編編寫的啟動(dòng)代碼,直到運(yùn)行到此處,均在特權(quán)模式下運(yùn)行,使用MSP作為棧頂指針。將來(lái)切換到線程后,會(huì)以PSP作為棧頂指針。啟動(dòng)流程不會(huì)重來(lái)一次,也沒有任何函數(shù)再需要返回。所以,對(duì)于截止到目前使用的MSP棧,可以舍棄棧中的數(shù)據(jù),MSP棧重置。
204-205行,使能中斷。首先在context_gcc.S的89行設(shè)置斷點(diǎn),然后當(dāng)PC運(yùn)行在204行時(shí)按F5,會(huì)運(yùn)行至PendSV中斷服務(wù)程序。

Step 13. PendSV函數(shù)分析。

在PendSV中斷服務(wù)程序中:

94行-96行,判斷rt_thread_switch_interrupt_flag的值,為0則退出,為1則繼續(xù);
99行-105行,rt_thread_switch_interrupt_flag清0,判斷rt_interrupt_from_thread的值,為0表示OS第一次進(jìn)行最高優(yōu)先級(jí)就緒狀態(tài)線程的運(yùn)行,無(wú)需恢復(fù)psp,直接跳轉(zhuǎn)到switch_to_thread;為1表示從from線程切換至to線程,需要恢復(fù)psp。Debug到此處,rt_interrupt_from_thread的值為0,是第一次進(jìn)行線程運(yùn)行。
此處直接分析127行開始的switch_to_thread部分。

128行,將rt_interrupt_to_thread的地址賦值給r1。
129行,從r1指向的地址中取出值,賦值給r1,此時(shí)r1指向到main線程的thread->sp。
130行,從r1指向的地址中取出值,賦值給r1,此時(shí)r1指向到0x200018F4,如下圖所示。

133行-136行,將r1指向的0x200018F4開始的單元內(nèi)容,依次裝載到r3, r4-r11中。執(zhí)行完畢后,R3中是flag的值,r4-r11中均為0xDEAFBEEF,且r1指向0x20001918。

139-140行,由于r3為0,浮點(diǎn)寄存器不做處理。r1保持不變。
143行,將r1的值賦值給PSP,線程棧頂指針PSP目前為0x20001918。后續(xù)PSP還會(huì)自動(dòng)更新。

155行,使得LR寄存器的Bit2為1,確保PendSV異常返回使用的棧指針是PSP。
156行,異常返回。此時(shí),線程棧中剩下內(nèi)容,即從0x20001918-0x20001934的內(nèi)容,會(huì)自動(dòng)加載到R0, R1, R2, R3, R12, R14 (線程返回地址), PC (線程入口地址), xPSR。且,PSP會(huì)自動(dòng)更新至0x20001938,即創(chuàng)建main線程時(shí)的棧頂指針。

Step 14. 光標(biāo)在BX LR上時(shí),按F5,自動(dòng)運(yùn)行到main線程入口地址main_thread_entry。

如下圖所示,棧幀中的r0-r15, xPSR均已順利從線程棧中進(jìn)行了恢復(fù),此時(shí)thread->sp = PSP = 0x20001938。開始順利執(zhí)行線程。

三、修改rt_hw_context_switch_to函數(shù),使用SVC進(jìn)入第一個(gè)線程

FreeRTOS使用SVC進(jìn)入第一個(gè)線程,通過(guò)簡(jiǎn)單修改,在STM32L431RCT6 Cortex-M4內(nèi)核上也可以支持用SVC進(jìn)入第一個(gè)線程。 計(jì)劃在線下課程中,與學(xué)生們面對(duì)面深入探討一次。

對(duì)rt_hw_context_switch_to函數(shù)的修改過(guò)程如下:

刪除對(duì)rt_interrupt_from_thread的清零
刪除對(duì)rt_thread_switch_interrupt_flag的置1
刪除對(duì)PendSV的觸發(fā)
新增dsb isb
新增SVC 0
毫無(wú)意義,對(duì)R0賦值,通過(guò)Debug觀察到該語(yǔ)句不會(huì)被執(zhí)行

1.jpg

修改后的rt_hw_context_switch_to函數(shù)和SVC_Handler函數(shù)如下:

.global rt_hw_context_switch_to
.type rt_hw_context_switch_to, %function
rt_hw_context_switch_to:
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
#if defined ( VFP_FP ) && !defined( SOFTFP )
/* CLEAR CONTROL.FPCA /
MRS r2, CONTROL /
read /
BIC r2, #0x04 /
modify /
MSR CONTROL, r2 /
write-back /
#endif
/
set the PendSV and SysTick exception priority /
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] /
read /
ORR r1,r1,r2 /
modify /
STR r1, [r0] /
write-back /
/
restore MSP /
LDR r0, =SCB_VTOR
LDR r0, [r0]
LDR r0, [r0]
NOP
MSR msp, r0
/
enable interrupts at processor level /
CPSIE F
CPSIE I
dsb
isb
SVC 0
/
never reach here! /
LDR r0, =0x12345678 / debug according to blta's comment /
.global SVC_Handler
.type SVC_Handler, %function
SVC_Handler:
/
disable interrupt to protect context switch /
MRS r2, PRIMASK
CPSID I
/
get rt_thread_switch_interrupt_flag /
switch_to_first_thread:
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] /
load thread stack pointer /
#if defined ( VFP_FP ) && !defined( SOFTFP )
LDMFD r1!, {r3} /
pop flag /
#endif
LDMFD r1!, {r4 - r11} /
pop r4 - r11 register /
#if defined ( VFP_FP ) && !defined( SOFTFP )
CMP r3, #0 /
if(flag_r3 != 0) */
VLDMIANE r1!, {d8 - d15} /* pop FPU register s16~s31 */
#endif
MSR psp, r1 /* update stack pointer */
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
ORR lr, lr, #0x10 /* lr |= (1 << 4), clean FPCA. */
CMP r3, #0 /* if(flag_r3 != 0) */
BICNE lr, lr, #0x10 /* lr &= ~(1 << 4), set FPCA. */
#endif
svc_exit:
/* restore interrupt */
MSR PRIMASK, r2
ORR lr, lr, #0x04
BX lr

四、小結(jié)

本文簡(jiǎn)單探討了RT-Thread 4.0.5版本在STM32L431RCTx Cortex-M4內(nèi)核上,創(chuàng)建main線程、tidle0線程后,從使用MSP的特權(quán)模式,啟動(dòng)至使用PSP線程模式的main線程棧幀恢復(fù)全過(guò)程。

SP寄存器有兩個(gè),分別是MSP和PSP,其中,從復(fù)位啟動(dòng)后使用MSP,通過(guò)啟動(dòng)代碼、RT-Thread初始化、啟動(dòng)調(diào)度器的過(guò)程,切換至使用PSP的線程中運(yùn)行。

每個(gè)線程均有獨(dú)立的棧。使用rt_thread_create創(chuàng)建的線程,棧位于heap中;使用rt_thread_init創(chuàng)建的棧,棧位于自定義的數(shù)組中。

線程切換,即保存所有寄存器的快照到線程棧中,r0-r15, xPSR,浮點(diǎn)寄存器。線程恢復(fù),即從線程棧中恢復(fù)寄存器快照。

在線程模式下,如果發(fā)生中斷,會(huì)繼續(xù)使用MSP。

Cortex M4發(fā)生中斷,會(huì)有系列寄存器自動(dòng)入棧處理的操作,本文不展開討論。

RT-Thread的上下文切換的Context_gcc.S文件中rt_hw_context_switch_to也可以用SVC進(jìn)行線程處理。

1.jpg

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5429

    瀏覽量

    123847
  • Cortex-M4
    +關(guān)注

    關(guān)注

    6

    文章

    98

    瀏覽量

    47118
  • SVC
    SVC
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    12410
  • RT-Thread
    +關(guān)注

    關(guān)注

    32

    文章

    1384

    瀏覽量

    41650
  • STM32L4
    +關(guān)注

    關(guān)注

    1

    文章

    42

    瀏覽量

    9634
收藏 0人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    RT-Thread啟動(dòng)進(jìn)入就緒態(tài)最高優(yōu)先級(jí)線程全過(guò)程分析(上)

    本文簡(jiǎn)單討論RT-Thread啟動(dòng)后,逐步進(jìn)入到處于就緒態(tài)最高
    的頭像 發(fā)表于 11-08 12:47 ?1733次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>啟動(dòng)</b><b class='flag-5'>進(jìn)入</b><b class='flag-5'>就緒</b><b class='flag-5'>態(tài)</b><b class='flag-5'>最高</b><b class='flag-5'>優(yōu)先級(jí)</b><b class='flag-5'>線程</b>的<b class='flag-5'>全過(guò)程</b>與<b class='flag-5'>棧</b><b class='flag-5'>幀</b><b class='flag-5'>分析</b>(上)

    深度剖析 RT-Thread 線程調(diào)度流程

    rt_system_scheduler_start:調(diào)度系統(tǒng)第一個(gè)線程rt_hw_context_switch_to:初始化上下文切換環(huán)境,觸發(fā)PendSV異常first_thread
    的頭像 發(fā)表于 06-25 18:24 ?198次閱讀
    深度剖析 <b class='flag-5'>RT-Thread</b> <b class='flag-5'>線程</b>調(diào)度流程

    靈動(dòng)微課堂 (第135講) | 基于MM32 MCU的OS移植與應(yīng)用——RT-Thread 線程管理

    的屬性,如線程控制塊、線程、入口函數(shù)等。圖 1 對(duì)象容器與線程對(duì)象線程的調(diào)度RT-Thread
    發(fā)表于 09-03 17:40

    什么是RT-Thread線程管理看完你就懂了

    RT_THREAD_INIT就緒狀態(tài)在就緒狀態(tài),線程按照優(yōu)先級(jí)排隊(duì),等待被執(zhí)行;一旦當(dāng)前
    發(fā)表于 03-29 06:16

    【每日一練】RT-Thread Nano-線程創(chuàng)建1(第五節(jié)學(xué)習(xí)視頻)

    )A、256.0 B、32.32 C、512.0D、256.2562、rt_thread_create()函數(shù)有哪幾個(gè)參數(shù)?請(qǐng)說(shuō)明(問(wèn)答)3、啟動(dòng)線程后,線程會(huì)
    發(fā)表于 05-21 10:04

    RT-Thread基于優(yōu)先級(jí)的全搶占式調(diào)度算法的實(shí)現(xiàn)

    ,通過(guò)查找這個(gè)表,我們就能夠知道當(dāng)前就緒任務(wù)中最高優(yōu)先級(jí)的任務(wù)是哪一個(gè),然后直接執(zhí)行該優(yōu)先級(jí)的任務(wù)即可。具體來(lái)說(shuō),這個(gè)
    發(fā)表于 04-20 14:17

    基于STM32L475VET5的RT-Thread線程管理學(xué)習(xí)

    調(diào)度。此狀態(tài)在 RT-Thread 中的宏定義為 RT_THREAD_INIT。(2)就緒狀態(tài):在就緒狀態(tài),
    發(fā)表于 04-22 15:00

    RT-Thread代碼啟動(dòng)線程切換過(guò)程的實(shí)現(xiàn)

    的,換一函數(shù)名就好了2、RT-Thread線程切換過(guò)程首先查看RT-Thread內(nèi)核架構(gòu)這一章節(jié),明白
    發(fā)表于 04-25 11:38

    探討一RT-Thread任務(wù)調(diào)度的啟動(dòng)順序

    (時(shí)間復(fù)雜度O(1),即與就緒線程的多少無(wú)關(guān)),通過(guò)位圖的定位快速的獲得優(yōu)先級(jí)最高線程。大致來(lái)說(shuō),就是每次調(diào)度的時(shí)間是恒定的:無(wú)論當(dāng)前的系
    發(fā)表于 05-09 14:13

    RT-Thread嵌入式操作系統(tǒng)線程優(yōu)先級(jí)該怎樣去實(shí)現(xiàn)呢

    就緒列表RT-Thread 要支持多優(yōu)先級(jí),需要靠就緒列表的支持,從代碼上看,就緒列表由兩個(gè)在 scheduler.c 文件定義的全局變量組
    發(fā)表于 05-09 14:32

    rt-thread優(yōu)先級(jí)線程可以調(diào)度執(zhí)行嗎?

    請(qǐng)教下,在rt-thread中,如果低優(yōu)先級(jí)線程中用while(1){}直接死循環(huán),是不是高優(yōu)先級(jí)線程也無(wú)法調(diào)度執(zhí)行了?如果高
    發(fā)表于 05-13 10:51

    RT-Thread線程優(yōu)先級(jí)鏈表與位圖算法的介紹

    隊(duì)列為當(dāng)前系統(tǒng)最高優(yōu)先級(jí),則調(diào)用rt_list_insert_before(&(rt_thread_priority_table[thread
    發(fā)表于 05-13 15:38

    RT-Thread系統(tǒng)線程調(diào)度器的設(shè)計(jì)實(shí)現(xiàn)

    就將演變?yōu)樵?b class='flag-5'>優(yōu)先級(jí)數(shù)組中尋找具有最高優(yōu)先級(jí)線程的非空鏈表。RT-Thread內(nèi)核中采用了基于位圖的優(yōu)先級(jí)
    發(fā)表于 08-23 15:24

    RT-Thread實(shí)時(shí)系統(tǒng)的線程設(shè)計(jì)應(yīng)該注意什么要點(diǎn)

    key線程來(lái)處理按鍵。線程的狀態(tài)躍遷這里說(shuō)的狀態(tài)躍遷指的是線程運(yùn)行中狀態(tài)的變化,從就緒態(tài)過(guò)渡到掛起態(tài)
    發(fā)表于 09-14 15:45

    如何去處理RT-Thread線程優(yōu)先級(jí)的問(wèn)題呢

    RT-Thread優(yōu)先級(jí)問(wèn)題,官方文檔互斥量一節(jié),線程2的優(yōu)先級(jí)線程1高,但在線程2runni
    發(fā)表于 12-05 11:51

    電子發(fā)燒友

    中國(guó)電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品