www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]前言: 最近一直都在看nucleus plus,之前看過一些linux內(nèi)核的一些東西,但都是停留在文字上,代碼看的很少,這個nucleus plus內(nèi)核的代碼量不大,看過source code確實對

前言: 最近一直都在看nucleus plus,之前看過一些linux內(nèi)核的一些東西,但都是停留在文字上,代碼看的很少,這個nucleus plus內(nèi)核的代碼量不大,看過source code確實對很多OS的知識有了更深入的認(rèn)識,收獲還是挺多的,把學(xué)到的東西記錄下來。

內(nèi)容:

?一、nucleus plus特點: 1.內(nèi)核采用微內(nèi)核的設(shè)計,方便移植,資料寫著更reliable,但是我不這么認(rèn)為,與linux相比,以ARM平臺為例,NU只用到了SVC mode,內(nèi)核與用戶任務(wù)都運(yùn)行在同一個狀態(tài)下,也就是說所有的task都擁有訪問任何資源的權(quán)限,這樣很reliable么? 2.real-time OS,NU是一個軟實時操作系統(tǒng)(VxWorks是硬實時),thread control component支持多任務(wù)以及任務(wù)的搶占,對于中斷的處理定義了兩種服務(wù)方式,LISR和HISR,這個與linux中的上、下半部機(jī)制類似,linux中的下半部是通過軟中斷來實現(xiàn)的,NU的HISR只是作為一種優(yōu)先級總是高于task的任務(wù)出現(xiàn)。 3.NU是以library的方式應(yīng)用的,通過寫自己的app task與裁剪后的NU內(nèi)核及組件鏈接起來,NU并沒有CLI

二、組件

1.IN component 初始化組件由三個部分組成,硬件在reset后首先進(jìn)入INT_initialize(),進(jìn)行板級的相關(guān)初始化,首先設(shè)置SVC mode,關(guān)中斷,然后將內(nèi)核從rom中拷貝至ram中,建立bss段,依次建立sys stack, irq stack和fiq stack,最后初始化timer,建立timer HISR的棧空間,看了一下2410平臺的代碼,一個tick大概是15.8ms,完成板級的初始化后就進(jìn)入了INC_initialize,初始化各個組件,其中包括Application initialize,create task和HISR,最后將控制權(quán)交給schedule,主要看了一下RAM中地址空間的安排 |timer HISR stack = 1024| |FIQ stack = 512| |IRQ stack = 1024| |SVC stack = 1024| |.bss| |.data| |.text| 其中SVC stack的大小與中斷源的個數(shù)相關(guān),nested irq發(fā)生時,irq_context保存在SVC stack中,IRQ的stack只是做了臨時棧的作用。

2.thread control component TC組件是NU內(nèi)核的最重要組成部分,主要涵蓋了調(diào)度、中斷、任務(wù)的相關(guān)操作、鎖、時鐘幾個方面,下面分別介紹。

調(diào)度(schedule)

NU中的線程類型(在同一個地址空間內(nèi))有兩種,HISR和task,HISR可以理解為一種優(yōu)先級較高的task,但又不是task,HISR優(yōu)先級高于task的實現(xiàn)方式就是schdule時,先去查看當(dāng)前是否有active的HISR,再去查看task。task有suspend、ready、finished和terminated四種狀態(tài),而HISR只有executing和no-active這兩種狀態(tài)。

每一個task都有一個線程控制的數(shù)據(jù)結(jié)構(gòu)(TCB thread control block),其中包括了task的優(yōu)先級、狀態(tài)、時間片、task棧、protect信息、signal操作的標(biāo)志位和signal_handler等,task在創(chuàng)建時初始化這些信息,將task掛到一個create_list上,初始設(shè)定task為pure_suspend,如果設(shè)定auto start,調(diào)用resume_task()喚醒task,這里有個細(xì)節(jié),如果在application initialize中create_task(),則task不會自動運(yùn)行,因為初始化還未完成,控制權(quán)還沒有交給schedule,無法調(diào)度task。task被喚醒后狀態(tài)改變?yōu)閞eady,并掛在一個TCD_Priority_List[256]上,數(shù)組的每個元素是一個指向TCB環(huán)形雙向鏈表的指針,根據(jù)task的tc_priority找到對應(yīng)優(yōu)先級的TCB head pointer。

每一個HISR都有一個HISR控制的數(shù)據(jù)結(jié)構(gòu)(HCB HISR control block),其中只有優(yōu)先級,HISR棧和HISR entry信息,因此HISR是不可以suspend,同時也沒有time slice以及signal的相關(guān)操作,一般情況下當(dāng)發(fā)生了中斷后,HISR被activate,schedule就會調(diào)度HISR運(yùn)行,期間如果不發(fā)生中斷,HISR的執(zhí)行是不會被打斷的,HISR的優(yōu)先級只有0、1、2,timer的HISR優(yōu)先級為2,也就是說由外部中斷激活的HISR很難被搶占的,只有更高優(yōu)先級的中斷HISR才可以。與task不同,被激活的HISR使用head_list和tail_list將HCB掛在一個單項的鏈表上,因為相同優(yōu)先級的HISR不會搶占對方,因此不需要雙向鏈表,使用兩個指針目的是加快HISR執(zhí)行的速度。


一個實時操作系統(tǒng)的核心就是對于任務(wù)的調(diào)度,NU的調(diào)度策略是time slice和round robin的算法, 調(diào)度的部分主要有三個函數(shù)control_to_system()用于保存上下文,建立solicited stack,關(guān)中斷,關(guān)system time slice,并重置task的time slice為預(yù)設(shè)值,將sp更新為system_stack_pointer,調(diào)用schedule(),調(diào)度的過程是非常簡單的查詢,就是查看兩個全局的變量,TCD_Execute_HISR和TCD_Execute_Task,schedule部分的關(guān)鍵是打開了中斷,不然如果當(dāng)前沒有ready的task或是被激活的HISR,則shedule死循環(huán)下去,查詢到下一個應(yīng)該執(zhí)行的線程后跳轉(zhuǎn)至control_to_thread(),在這里重新開啟system time slice,然后將線程的tc_stack_ptr加入到sp中,切換至線程的棧中,依次pop出來,即完成了任務(wù)調(diào)度。

任務(wù)的切換主要是上下文的切換,也就是task棧的切換,函數(shù)的調(diào)用會保存部分regs和返回地址,這些動作都是編譯器來完成的,而OS中的任務(wù)切換是運(yùn)行時(runtime)的一種狀態(tài)變化,因此編譯器也無能為力,所以對于上下文的保存需要代碼來實現(xiàn)。

任務(wù)的搶占是異步的因此必須要通過中斷來實現(xiàn),一般每次timer的中斷決定當(dāng)前的task的slice time是否expired,然后設(shè)置TCT_Set_Execute_Task為相同優(yōu)先級的其他task或更高優(yōu)先級的task;高優(yōu)先級的task搶占低優(yōu)先級的task,一般是外部中斷觸發(fā),在HISR中resume_task()喚醒高優(yōu)先級的task,然后schedule到高優(yōu)先級的task中,因為timer的HISR是在系統(tǒng)初始化就已經(jīng)注冊的,只是執(zhí)行timeout和time slice超時后的操作,并沒有執(zhí)行resume_task的動作。

NU中的stack有兩種solicited stack和interrupt stack,solicited stack是一種minmum stack,而interrupt stack是對當(dāng)前所有寄存器全部保存,TCB中的minimum stack size = 申請得到stack size - solicited stack(在arm mode下占44字節(jié),thumb mode下占48字節(jié)),thumb標(biāo)志用來記錄上下文保存時的ARM的工作模式,c代碼編譯為thumb模式,這樣可以減小code size,提高代碼密度,assembly代碼編譯為arm模式提升代碼的效率,NU中內(nèi)核的代碼不多,主要是assembly代碼。stack的類型與其中PC指向的shell無關(guān),interrupt stack保存的是task或是HISR在執(zhí)行的過程中被中斷時的現(xiàn)場,solicited stack建立的地方包括 control_to_system()、schedule_protect()和send_signals()發(fā)送給占有protect資源的task的情況,HISR_Shell()執(zhí)行完后會建立solicited stack,再跳轉(zhuǎn)至schedule。

(Lower Address) Stack Top -> 1 (Interrupt stack type) CPSR Saved CPSR r0 Saved r0 r1 Saved r1 r2 Saved r2 r3 Saved r3 r4 Saved r4 r5 Saved r5 r6 Saved r6 r7 Saved r7 r8 Saved r8 r9 Saved r9 r10 Saved r10 r11 Saved r11 r12 Saved r12 sp Saved sp lr Saved lr (Higher Address) Stack Bottom-> pc Saved pc

(Lower Address) Stack Top -> 0 (Solicited stack type) !!FOR THUMB ONLY!! 0/0x20 Saved state mask r4 Saved r4 r5 Saved r5 r6 Saved r6 r7 Saved r7 r8 Saved r8 r9 Saved r9 r10 Saved r10 r11 Saved r11 r12 Saved r12 (Higher Address) Stack Bottom-> pc Saved pc 一個簡單的例子說明stack的情況,首先是一個task在ready(executing)的狀態(tài)下,而且time slice超時了,timer中斷發(fā)生后,保存task上下文interrupt_contex_save(),在task的tc_stack_ptr指向的地方建立中斷棧 taskA |interrupt stack|___tc_stack_ptr 棧頂端是pc=lr-4 ARM對于中斷的判定發(fā)生在當(dāng)前指令完成execute時,同時pipeline的原因pc=pc+8,入棧時就把lr-4首先放在stack的最高端(high)。

timer的LISR完成后激活了HISR,執(zhí)行TCC_Time_slice()將當(dāng)前task移到相同優(yōu)先級的尾端,并且設(shè)置下一個要執(zhí)行的task,HISR在棧頂端保存的是這個HISR_shell的入口地址,因為task的執(zhí)行完就finished,HISR是可重入的 HISR |solicited stack| 棧頂端是HISR_shell_entry

中斷(interrupt)

前面已經(jīng)提及了中斷的基本操作,這里就寫一些代碼路徑的細(xì)節(jié),中斷的執(zhí)行主要是兩個部分LISR和HISR,分成兩個部分的目的就是將關(guān)中斷的時間最小化,并且在LISR中開中斷允許中斷的嵌套,以及建立中斷優(yōu)先級,都可以減少中斷的延遲,保證OS的實時性。 NU的中斷模式是可重入的中斷處理方式,也就是基于中斷優(yōu)先級和嵌套的模式,中斷的嵌套在處理的過程中應(yīng)對lr_irq_mode寄存器進(jìn)行保存,因為高優(yōu)先級的中斷發(fā)生時會覆蓋掉低優(yōu)先級中斷的r14和spsr,因此要利用系統(tǒng)的棧來保存中斷棧。

NU對于中斷上下文的保存具體操作如下: (1)在中斷發(fā)生后執(zhí)行的入口函數(shù)INT_IRQ()中,將r0-r4保存至irq的棧中 (2)查找到對應(yīng)的interrupt_shell(),clear中斷源,更新全局的中斷計數(shù)器,然后進(jìn)行interrupt_contex_save (3)首先利用r1,r2,r3保存irq模式下的sp,lr,spsr,這里sp是用來切換至系統(tǒng)棧后拷貝lr和spsr的,這里保存lr和spsr是目的是task被搶占后,當(dāng)再次schedule時可以返回task之前的狀態(tài)。 (4)切換至SVC模式,如果是非嵌套的中斷則保存上下文至task stack中,將irq模式下的lr作為頂端PC的返回值入棧,將SVC模式下的r6-r14入棧,將irq模式下的sp保存至r4中入棧,最后將保存在irq_stack中的r0-r4入棧 (5)如果是嵌套中斷,中斷的嵌套發(fā)生在LISR中,在執(zhí)行LISR時已經(jīng)切換至system stack,因此嵌套中斷要將中斷的上下文保存至system stack中,與task stack中interrupt stack相比只是少了棧頂用來標(biāo)記嵌套的標(biāo)志(1 not nested) (6)有一個分支判斷,就是如果當(dāng)前線程是空,即TCD_Current_Thread == NULL,表明當(dāng)前是schedule中,因為初始化線程是關(guān)中斷的,這樣就不為schedule線程建立棧幀,因為schedule不需要保存上下文,在restore中斷上下文時直接跳轉(zhuǎn)至schedule。

中斷上下文的恢復(fù) 全局的中斷計數(shù)器INT_Count是否為0來判定當(dāng)前出棧的信息,如果是嵌套則返回LISR中,否則切換至system stack執(zhí)行schedule

timer timer與中斷緊密相關(guān),其實timer也是中斷的一種,只是發(fā)生中斷的頻率較高,且作用重大,一個實時操作系統(tǒng),時間是非常重要的一部分,NU中的timer主要有四個作用: (1)維護(hù)系統(tǒng)時鐘 TMD_system_clock (2)task的time slice (3)task的suspend timeout timer (4)application timer 其中(3)(4)共用一種機(jī)制,一個全局的時間軸TMD_timer,timeout timer和app timer都建立在一個TM_TCB的數(shù)據(jù)結(jié)構(gòu)上,通過tm_remaining_time來表征當(dāng)前timer的剩余時間,例如當(dāng)前有timer_list上有三個TM_TCB,依次是Ta = 5,Tb = 7, Tc = 20,那么建立的鏈表上剩余時間依次是5,2,8,如果現(xiàn)在要加入一個新的timer根據(jù)timer值插入至合適的位置,如果插入的timer為13,則安排在Tb后面,剩余時間為1,后面的8改為7,當(dāng)發(fā)生了timer expired,則觸發(fā)timer_HISR,如果是app timer則執(zhí)行timer callback,如果是task timeout timer,則執(zhí)行TCC_Task_Timeout喚醒task。

(2)的實現(xiàn)也是依賴于全局的time slice時間軸,每一個task在執(zhí)行時都會將自己的時間片信息更新至全局的時間軸上,當(dāng)一個task的time slice執(zhí)行完在timer HISR中調(diào)用TCC_task_Timeout將當(dāng)前的task放在相同優(yōu)先級list的最尾端,并設(shè)置下一個最高優(yōu)先級的任務(wù)。task在執(zhí)行的過程中只有被中斷后time slice會保存下來,其他讓出處理器的情況都會將time slice更新為預(yù)設(shè)值。

protect protect與linux的鎖機(jī)制類似,互斥訪問,利用開關(guān)中斷來實現(xiàn),并且擁有protect的task是不可以suspend的,必須要將protect釋放后才可以掛起,當(dāng)一個優(yōu)先級較低的task占有protect資源,如果被搶占,一個高優(yōu)先級的task或HISR在請求protect資源時會執(zhí)行TCC_schedule_protect()讓出處理器給低優(yōu)先級的task執(zhí)行,直到低優(yōu)先級的task執(zhí)行unprotect()為止,此時task或HISR建立的是solicited stack,同時在control_to_thread前開關(guān)中斷一次,這樣可以減少一次上下文的切換。NU中常用到的是system_protect,它就是一把大鎖,保護(hù)內(nèi)核中所有全局?jǐn)?shù)據(jù)結(jié)構(gòu)的順序訪問,粒度很大。

LISR中不可以請求protect資源,因為LISR是中斷task后執(zhí)行,如果task占有protect資源,這時LISR又去請求protect資源,會發(fā)生死鎖,因為LISR讓出處理器后,schedule沒辦法再次調(diào)度到LISR執(zhí)行,則發(fā)生死鎖錯誤,因此在LISR中除了activate_HISR()以外不可以使用system call,例如resume_task等等,這寫系統(tǒng)調(diào)用都會請求protect資源。

對于protect的請求按照一定的順序可以防止死鎖,NU的源碼中一般將system_protect資源的請求放在后面,其他如DM_protect先請求。


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉