1優(yōu)先級查找
位圖是指一組連續(xù)的標(biāo)志位,是一種常見的優(yōu)先級框架的實現(xiàn)方式。每個比特位通常用來對應(yīng)一個優(yōu)先級,越低位的優(yōu)先級越高,其狀態(tài)標(biāo)識該優(yōu)先級是否有就緒狀態(tài)的任務(wù)。以下圖32位為例,存在優(yōu)先級為1、7、9、16……24、25、31的就緒態(tài)任務(wù)。每個優(yōu)先級存在對應(yīng)的任務(wù)鏈表,同一個優(yōu)先級中采用“先就緒先執(zhí)行”的原則。
那么,CPU的任務(wù)從“尋找優(yōu)先級最高的任務(wù)”變成了“尋找位圖中最低位的1”。如果按照上圖中依次按位查找,速度是較慢的,系統(tǒng)的實時性可能會有一定程度的影響,下面介紹一種較為巧妙的方法——分組查表法。? ? ? ? ? ? ? ? ? ? ?? ? ??圖2 分組查表法
const rt_uint8_t __lowest_bit_bitmap[] =
{
/* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
/* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
int __rt_ffs(int value)
{
if (value == 0) return 0;
if (value & 0xff)
return __lowest_bit_bitmap[value & 0xff] + 1;
if (value & 0xff00)
return __lowest_bit_bitmap[(value & 0xff00) >> 8] + 9;
if (value & 0xff0000)
return __lowest_bit_bitmap[(value & 0xff0000) >> 16] + 17;
return __lowest_bit_bitmap[(value & 0xff000000) >> 24] + 25;
這種方法將32位共分成4組,每組8位,那么每組的8位二進(jìn)制數(shù)0x00~0xFF對應(yīng)數(shù)組bitmap的序號0-255,數(shù)組中的值的含義為其對應(yīng)8位二進(jìn)制數(shù)最低位“1”的序號。那么通過這樣巧妙的分組查表方式,通過至多四次查找,便可得到位圖的最低位“1”的位置。除此之外,還有更為巧妙的利用匯編指令CLZ和RBIT組合實現(xiàn)這個目的,其中CLZ可以統(tǒng)計出現(xiàn)“1”的最高位位置,RBIT是數(shù)據(jù)進(jìn)行按位反轉(zhuǎn)的指令。這樣就可以先通過RBIT進(jìn)行位反轉(zhuǎn),再通過CLZ獲取反轉(zhuǎn)后最高位“1”的位置,即原數(shù)據(jù)中最低位“1”的位置。
2臨界區(qū)保護(hù)和線程同步
在RTOS中,時常會出現(xiàn)多個線程訪問公用資源的情況,即都需要訪問公用的程序片段,如若沒有對應(yīng)的處理機制,可能會對系統(tǒng)造成意想不到的混亂。常用的方法有調(diào)度器上鎖和禁止中斷,這兩者相互依賴,例如在調(diào)度器上鎖時需要禁止中斷。除此之外,還可以采用互斥機制來進(jìn)行臨界區(qū)保護(hù),如信號量和互斥量,這兩者也用于線程的同步機制。
圖3 信號量類比
圖4 互斥量類比
互斥量的作用類似于二值信號量,它是一種特殊的信號量,只具有“上鎖”和“解鎖”兩種狀態(tài),對應(yīng)的臨界資源具有極強的排他性。就像景區(qū)的豪華單間衛(wèi)生間,每個人在使用的時候都不能被打擾。雖然功能類似,但是二值信號量和互斥量還是有區(qū)別的,后續(xù)會進(jìn)行相應(yīng)的介紹。
3優(yōu)先級反轉(zhuǎn)問題
當(dāng)隱入互斥量的機制后,讀者可以思考一下,這會不會和優(yōu)先級機制產(chǎn)生沖突?
一個是根據(jù)優(yōu)先級制定的“國家法律”,一個是根據(jù)臨界資源制定的“地方法律”,當(dāng)遵守“地方法律“的時候會不會違背“國家法律”?這就是優(yōu)先級反轉(zhuǎn)問題。
? ? ? ? ? ? ? ? ? ? ? ? ??? ? ? ? ? ? 圖6? 優(yōu)先級反轉(zhuǎn)
如上圖,假設(shè)我們有三個線程,它們的優(yōu)先級Thread1 > Thread2 > Thread3,t0之前Thread3獲取某資源的互斥量,互斥量值變locked狀態(tài),t0時刻Thread2線程就緒,由于優(yōu)先級Thread2 > Thread3,Thread3讓出CPU執(zhí)行權(quán)給Thread2,但沒有解開互斥量。到t1時刻,Thread1就緒,Thread2讓出CPU,Thread1執(zhí)行過程申請Thread3所占有的互斥量,由于互斥量為locked狀態(tài),在t2時刻Thread1被掛起等待,剩余兩個就緒態(tài)的線程Thread2優(yōu)先級高于Thread1,因此繼續(xù)執(zhí)行。
至此,我們發(fā)現(xiàn),都處于就緒態(tài)的線程,低優(yōu)先級的Thread2反而能比高優(yōu)先級的Thread1優(yōu)先執(zhí)行,其原因是更低優(yōu)先級的Thread3占有信號量并被搶占,造成了優(yōu)先級反轉(zhuǎn)。所以為了讓“地方法律”更加適配“國家法律”,常用的做法是優(yōu)先級繼承。即可以讓Thread3短暫地提升到Thread1的優(yōu)先級,得以搶占CPU快速執(zhí)行完將互斥量解鎖,從而讓Thread1及時獲取到互斥量得以執(zhí)行。除此之外,還存在一些另外的處理方式,如優(yōu)先級天花板等,有興趣的讀者可以自行查閱相關(guān)資料。
二值信號量和互斥信號量非常類似,但還是有一些細(xì)微的差別。互斥信號量擁有優(yōu)先級繼承機制,而二值信號量沒有。互斥量必須是同一個任務(wù)申請,同一個任務(wù)釋放,其他任務(wù)釋放無效,且同一個任務(wù)可以遞歸申請。然而對于二值信號量,一個任務(wù)申請成功后,可以由另一個任務(wù)釋放,因此二值信號另更適合用于同步(任務(wù)與任務(wù)或任務(wù)與中斷的同步),互斥信號量適合用于簡單的互斥訪問。
4線程間通信
線程間通信主要是通過消息隊列和郵箱實現(xiàn),消息隊列一般采用先進(jìn)先出的原則(FIFO),而郵箱可以理解成隊列長度為1的特殊消息隊列,但是消息隊列中為待傳輸?shù)臄?shù)據(jù)按值拷貝的副本,所以支持各種類型的數(shù)據(jù)的傳遞,而郵箱中傳輸?shù)耐ǔ橹赶虼粨Q數(shù)據(jù)的指針。5總結(jié)
至此,一個RTOS的內(nèi)核功能基本就實現(xiàn)了,下面對一個RTOS Kernel應(yīng)具備的功能進(jìn)行分條總結(jié):
實時性:實時系統(tǒng)對任務(wù)的響應(yīng)時間要求較高。具備嚴(yán)格的按優(yōu)先級調(diào)度任務(wù)的機制,并且一般要支持搶占式調(diào)度。
多任務(wù)調(diào)度:RTOS需要能夠同時管理多個任務(wù),并合理分配CPU時間片給每個任務(wù)。設(shè)計任務(wù)調(diào)度算法以確保相同優(yōu)先級的任務(wù)能公平使用CPU,避免優(yōu)先級反轉(zhuǎn)問題,并提供優(yōu)先級繼承、優(yōu)先級天花板等機制。
同步和通信:多任務(wù)系統(tǒng)中,任務(wù)之間需要進(jìn)行同步和通信。設(shè)計合適的同步機制,如信號量、互斥鎖、消息隊列等,并確保在多個任務(wù)之間實現(xiàn)可靠的數(shù)據(jù)傳輸和共享。
但是,這些僅僅是內(nèi)核的基本功能,一個成熟的RTOS還應(yīng)該具有更多的擴展功能予以支撐。例如內(nèi)存管理功能、外設(shè)驅(qū)動的支持、硬件依賴性和可移植性、調(diào)試和測試功能等等。羅馬非一日而建,希望大家都能腳踏實地,樂于鉆研,樂于進(jìn)步,共勉!
END
更多恩智浦AI-IoT市場和產(chǎn)品信息,邀您同時關(guān)注“NXP客棧”微信公眾號

NXP客棧
恩智浦致力于打造安全的連接和基礎(chǔ)設(shè)施解決方案,為智慧生活保駕護(hù)航。
長按二維碼,關(guān)注我們
恩智浦MCU加油站
這是由恩智浦官方運營的公眾號,著重為您推薦恩智浦MCU的產(chǎn)品信息、開發(fā)技巧、教程文檔、培訓(xùn)課程等內(nèi)容。

長按二維碼,關(guān)注我們
原文標(biāo)題:構(gòu)建RTOS Kernel指南 (下)
文章出處:【微信公眾號:恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
-
mcu
+關(guān)注
關(guān)注
146文章
17978瀏覽量
366680 -
恩智浦
+關(guān)注
關(guān)注
14文章
5980瀏覽量
116589
原文標(biāo)題:構(gòu)建RTOS Kernel指南 (下)
文章出處:【微信號:NXP_SMART_HARDWARE,微信公眾號:恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
請問編譯純rtos到底是選擇Linux+rtos的sdk編譯only rtos還是直接使用rtos sdk?
請問cyw20719或cyw20721是否支持RTOS?
有沒有關(guān)于使用英飛凌產(chǎn)品構(gòu)建充電式 VPD 設(shè)備的指南?
如何獲取yocto build來構(gòu)建對設(shè)備樹的更改?
詳解RTOS中的Hook函數(shù)
2K0300 OpenHarmony源碼構(gòu)建指南
VCOP Kernel-C到C7000遷移工具用戶指南

深入解析Zephyr RTOS的技術(shù)細(xì)節(jié)

Openharmony軟件評估指南-米爾瑞芯微RK3568開發(fā)板
freertos和rtos區(qū)別是什么
RTOS與Linux有什么區(qū)別
RTOS的特性和類型
RTOS開發(fā)最佳實踐
什么是實時操作系統(tǒng)(3)-在 RTOS 中可以期待什么?

評論