日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

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

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

內(nèi)容:

?一、nucleus plus特點(diǎn): 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是一個軟實(shí)時操作系統(tǒng)(VxWorks是硬實(shí)時),thread control component支持多任務(wù)以及任務(wù)的搶占,對于中斷的處理定義了兩種服務(wù)方式,LISR和HISR,這個與linux中的上、下半部機(jī)制類似,linux中的下半部是通過軟中斷來實(shí)現(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的實(shí)現(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)行,因?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掛在一個單項(xiàng)的鏈表上,因?yàn)橄嗤瑑?yōu)先級的HISR不會搶占對方,因此不需要雙向鏈表,使用兩個指針目的是加快HISR執(zhí)行的速度。


一個實(shí)時操作系統(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)變化,因此編譯器也無能為力,所以對于上下文的保存需要代碼來實(shí)現(xiàn)。

任務(wù)的搶占是異步的因此必須要通過中斷來實(shí)現(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中,因?yàn)閠imer的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的入口地址,因?yàn)閠ask的執(zhí)行完就finished,HISR是可重入的 HISR |solicited stack| 棧頂端是HISR_shell_entry

中斷(interrupt)

前面已經(jīng)提及了中斷的基本操作,這里就寫一些代碼路徑的細(xì)節(jié),中斷的執(zhí)行主要是兩個部分LISR和HISR,分成兩個部分的目的就是將關(guān)中斷的時間最小化,并且在LISR中開中斷允許中斷的嵌套,以及建立中斷優(yōu)先級,都可以減少中斷的延遲,保證OS的實(shí)時性。 NU的中斷模式是可重入的中斷處理方式,也就是基于中斷優(yōu)先級和嵌套的模式,中斷的嵌套在處理的過程中應(yīng)對lr_irq_mode寄存器進(jìn)行保存,因?yà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中,因?yàn)槌跏蓟€程是關(guān)中斷的,這樣就不為schedule線程建立棧幀,因?yàn)閟chedule不需要保存上下文,在restore中斷上下文時直接跳轉(zhuǎn)至schedule。

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

timer timer與中斷緊密相關(guān),其實(shí)timer也是中斷的一種,只是發(fā)生中斷的頻率較高,且作用重大,一個實(shí)時操作系統(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)的實(shí)現(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)中斷來實(shí)現(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資源,因?yàn)長ISR是中斷task后執(zhí)行,如果task占有protect資源,這時LISR又去請求protect資源,會發(fā)生死鎖,因?yàn)長ISR讓出處理器后,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ā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉