免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
RT-Thread2
[
你可以任意轉(zhuǎn)載本文,但轉(zhuǎn)載請(qǐng)保留本段聲明。
作者將盡量追求內(nèi)容的正確,但不對(duì)正確性作出保證。
未經(jīng)作者許可,不得用于商業(yè)目的。
作者:byeyear/告別年代
Email: byeyear@hotmail.com
]

首先糾正一下上一篇中的一個(gè)錯(cuò)誤。對(duì)象類型(是否為系統(tǒng)對(duì)象)記錄在rt_thread結(jié)構(gòu)的type成員里,而不是flag成員里。

何謂線程

所謂“線程”,其實(shí)就是一段子程序。只是它和普通子程序的區(qū)別在于,這段子程序可能隨時(shí)被操作系統(tǒng)所中斷,并在將來的某個(gè)時(shí)間點(diǎn)恢復(fù)運(yùn)行。為了達(dá)到這個(gè)目的,我們需要一些基礎(chǔ)設(shè)施。例如,我們需要在中斷一個(gè)線程的運(yùn)行時(shí)保存當(dāng)前的PC寄存器,這樣我們才能在恢復(fù)其運(yùn)行時(shí)知道從何處重新開始;我們還需要保存當(dāng)前CPU的所有其他寄存器,因?yàn)檫@些寄存器可能被其他線程所破壞。

線程的創(chuàng)建

有兩個(gè)函數(shù)可用于創(chuàng)建線程:rt_thread_initrt_thread_create。這兩者的區(qū)別在于,前者需要調(diào)用者自己分配線程對(duì)象和線程棧,而后者由操作系統(tǒng)分配線程對(duì)象和??臻g。換句話說,rt_thread_creatert_thread_init多了資源分配的操作。這里,我們先看rt_thread_init。

rt_thread_init首先對(duì)調(diào)用者提供的線程對(duì)象進(jìn)行初始化:

rt_err_t rt_thread_init(...)

{

  rt_object_init((rt_object_t)thread,

                   RT_Object_Class_Thread, name);

  ...

}

rt_object_init的代碼做以下幾個(gè)工作:

1. 將對(duì)象類型設(shè)置為RT_Object_Class_Static

    這個(gè)標(biāo)記表明該對(duì)象是由用戶分配而不是操作系統(tǒng)分配的。

    一般來說,硬件資源的分配遵循“誰申請(qǐng),誰釋放”的原則。因此,當(dāng)線程退出運(yùn)行時(shí),操作系統(tǒng)需要判斷線程對(duì)象和線程棧占用的存儲(chǔ)空間是用戶分配的還是系統(tǒng)分配的。如果這些存儲(chǔ)空間是用戶分配的,那么操作系統(tǒng)不會(huì)對(duì)這些內(nèi)存做什么事情;但如果這些存儲(chǔ)空間是系統(tǒng)分配的(當(dāng)你用rt_thread_create創(chuàng)建線程時(shí)),操作系統(tǒng)就要負(fù)責(zé)釋放線程對(duì)象和線程棧所占用的存儲(chǔ)空間。判斷的依據(jù)就是線程對(duì)象類型。

2. 將name參數(shù)(對(duì)象名稱)復(fù)制到線程對(duì)象中

3. 將該線程對(duì)象加入線程對(duì)象鏈表,方便后面的管理。

線程對(duì)象初始化完畢后,就調(diào)用_rt_thread_init進(jìn)行實(shí)際的初始化工作:

1. 首先初始化該線程的tlist成員。

    我們前面說過,tlist成員是用來將該線程掛入某個(gè)狀態(tài)隊(duì)列的。但是該線程目前還沒有初始化完成,所以目前不將其掛入任何一個(gè)隊(duì)列,僅將其prevnext字段指向自身。

2. 將entry、parameterstack_start、stack_size四個(gè)參數(shù)保存到線程對(duì)象中。

entryparameter是線程入口地址和線程參數(shù);stack_start是線程棧起始地址。在后面將線程投入運(yùn)行時(shí),這些參數(shù)都是必須的。

stack_size并不是一個(gè)線程運(yùn)行所必須的參數(shù);但該變量可以幫助我們檢查線程在運(yùn)行過程中是否發(fā)生了堆棧溢出。RTT將線程??臻g全部初始化為'#'。這樣,在線程運(yùn)行過程中,通過檢查堆棧內(nèi)容,就可以判斷該線程實(shí)際使用的最大堆棧空間,以及線程堆??臻g是否溢出。

3. 初始化線程棧

  rt_hw_stack_init(...)

  這個(gè)函數(shù)的作用是將線程棧模擬成這個(gè)線程剛剛被切換出去的樣子。當(dāng)調(diào)度器將該線程投入運(yùn)行時(shí),它不會(huì)知道這個(gè)線程到底是真的曾經(jīng)被切換出去,還是被模擬成這個(gè)樣子。這是一個(gè)體系結(jié)構(gòu)相關(guān)的函數(shù),比較關(guān)鍵的是這一句(以arm7為例):

   *(--stk) = (unsigned long)texit; /* lr */

   texitRTT提供的系統(tǒng)函數(shù)。我們結(jié)合一個(gè)最簡單的線程作為例子來說明這一句的作用:

    void SampleThread(void *param)

    {

    }

    這個(gè)線程什么也不做,投入運(yùn)行后直接退出。函數(shù)返回時(shí)將執(zhí)行bx lr指令,即將lr寄存器的內(nèi)容從堆棧中彈入pc。而lr的值就是上面那條語句中的texit入口地址。因此,該線程退出后將執(zhí)行texit()函數(shù)。texit()會(huì)做一些必要的清理工作,然后進(jìn)行一次調(diào)度(因?yàn)楫?dāng)前線程已經(jīng)退出運(yùn)行了)。我們后面還要回到texit()函數(shù)中去。

    從這里我們看到,RTT不像uc/OS那樣要求線程一定要有一個(gè)while(1)循環(huán)。對(duì)于RTT來說,當(dāng)一個(gè)線程不再需要時(shí),可以像函數(shù)返回一樣使用return語句令其退出運(yùn)行。(插一句話,RTT關(guān)于texit的設(shè)計(jì)是激發(fā)我當(dāng)初學(xué)習(xí)RTT的主要原因之一。)

4. 將優(yōu)先級(jí)、初始tick都保存到線程對(duì)象。這里我們看到,RTTinit_tickremaining_tick都設(shè)置為相同的值。

5. 初始化thread_timer成員。thread_timer的作用我們前面已經(jīng)說過了,rt_timer_init函數(shù)我們留到定時(shí)器相關(guān)內(nèi)容中分析。


本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
rt-thread的線程調(diào)度與管理
RT-Thread Nano 移植原理
關(guān)于RT-Thread的啟動(dòng)問題
BOOST 線程庫
python線程障礙對(duì)象Barrier(34)
RT-thread內(nèi)核原理_rtthread
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服