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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

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

冬至子 ? 來源:lchnu ? 作者:lchnu ? 2023-11-08 12:53 ? 次閱讀

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

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

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

1.jpg

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

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

1.jpg

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

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

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

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

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

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

1.jpg

此時,main線程的線程結構體和線程??臻g不變,但是r0, r1, rt_interrupr_to_thread的內容均發(fā)生了變化。

1.jpg

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

168行至172行,處理浮點寄存器入??刂?,與Cortex M4內核的Lazy Stacking有關,但與本文主線無關,不做探討。

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

181至183行,將rt_thread_switch_interrupt_flag變量至1,該值將在PendSV中斷中使用。
186-194行,設置SysTick和PendSV中斷的優(yōu)先級,且觸發(fā)PendSV,但現(xiàn)在不跳轉,因為中斷為禁止。

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

204-205行,使能中斷。首先在context_gcc.S的89行設置斷點,然后當PC運行在204行時按F5,會運行至PendSV中斷服務程序。

1.jpg

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

在PendSV中斷服務程序中:

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

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

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

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

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

1.jpg

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

1.jpg

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

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

1.jpg

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

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

1.jpg

Step 14. 光標在BX LR上時,按F5,自動運行到main線程入口地址main_thread_entry。

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

1.jpg

通過本文對線程啟動過程的了解,對于兩個線程/多個線程之間的互相切換能奠定堅實的基礎,化繁為簡,結合論壇關于上下文切換的代碼注釋,能幫助快速抓住主線。

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

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

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

關閉軟件定時器線程,避免干擾。

Step 3. 關閉msh shell,禁用Finsh

關閉tshell線程,避免干擾。僅僅保留main線程和tidle0線程。

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

修改main函數(shù)后,線程進入一次,休眠且切換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. 下載程序,觀察輸出結果

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

二、調試運行
Step 6. 在component.c中257行按F9設置斷點;F5全速運行到此處后,再按F9關閉此處斷點。

Step 7. 依次進入rt_thread_create, _thread_init, 停留在thread.c的164行。

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

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

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

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

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

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

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

返回的stk指向0x200018F4部分。

至此,main線程創(chuàng)建完畢后,線程結構體和線程棧空間如下所示。

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

期間,RT-Thread會調用rt_thread_idle_init函數(shù),在該函數(shù)中使用靜態(tài)創(chuàng)建方式初始化tidle0線程。可以按照上述過程記錄tidle0線程的??臻g。

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

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

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

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

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

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

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

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

此時,main線程的線程結構體和線程??臻g不變,但是r0, r1, rt_interrupr_to_thread的內容均發(fā)生了變化。

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

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

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

在PendSV中斷服務程序中:

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

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

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

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

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

Step 14. 光標在BX LR上時,按F5,自動運行到main線程入口地址main_thread_entry。

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

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

FreeRTOS使用SVC進入第一個線程,通過簡單修改,在STM32L431RCT6 Cortex-M4內核上也可以支持用SVC進入第一個線程。 計劃在線下課程中,與學生們面對面深入探討一次。

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

刪除對rt_interrupt_from_thread的清零
刪除對rt_thread_switch_interrupt_flag的置1
刪除對PendSV的觸發(fā)
新增dsb isb
新增SVC 0
毫無意義,對R0賦值,通過Debug觀察到該語句不會被執(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

四、小結

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

SP寄存器有兩個,分別是MSP和PSP,其中,從復位啟動后使用MSP,通過啟動代碼、RT-Thread初始化、啟動調度器的過程,切換至使用PSP的線程中運行。

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

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

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

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

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

1.jpg

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

    關注

    31

    文章

    5301

    瀏覽量

    119861
  • Cortex-M4
    +關注

    關注

    6

    文章

    89

    瀏覽量

    46494
  • SVC
    SVC
    +關注

    關注

    0

    文章

    33

    瀏覽量

    12100
  • RT-Thread
    +關注

    關注

    31

    文章

    1265

    瀏覽量

    39852
  • STM32L4
    +關注

    關注

    1

    文章

    42

    瀏覽量

    9376
收藏 人收藏

    評論

    相關推薦

    RT-Thread啟動進入就緒態(tài)最高優(yōu)先級線程全過程分析(上)

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

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

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

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

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

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

    )A、256.0 B、32.32 C、512.0D、256.2562、rt_thread_create()函數(shù)有哪幾個參數(shù)?請說明(問答)3、啟動線程后,線程
    發(fā)表于 05-21 10:04

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

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

    基于STM32L475VET5的RT-Thread線程管理學習

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

    RT-Thread代碼啟動線程切換過程的實現(xiàn)

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

    探討一RT-Thread任務調度的啟動順序

    (時間復雜度O(1),即與就緒線程的多少無關),通過位圖的定位快速的獲得優(yōu)先級最高線程。大致來說,就是每次調度的時間是恒定的:無論當前的系
    發(fā)表于 05-09 14:13

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

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

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

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

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

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

    RT-Thread系統(tǒng)線程調度器的設計實現(xiàn)

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

    RT-Thread線程管理手冊指南

    _resume (rt_thread_t thread)使線程恢復運行詳細描述線程管理接口RT-Thread操作系統(tǒng)是基于
    發(fā)表于 08-26 16:22

    RT-Thread實時系統(tǒng)的線程設計應該注意什么要點

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

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

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