【正文】
息c o p y 至管道中N調(diào)整管道的寫指針調(diào)整管道的可用空間管道消息計數(shù)器 加 1p i _ m e s s a g e s + +Nucleus 分析報告 19 如果管道中沒有消息,任務(wù)可以選擇掛起與否。如果當前任務(wù)可以搶占且被 掛起的任務(wù)比當前任務(wù)優(yōu)先級高,則控制權(quán)會交給 TCT_Control_To_System,發(fā)生任務(wù)搶占。 發(fā)送了 n 條消息 管道擁塞,高優(yōu)先級任務(wù)掛起11 1 11 1 1接收發(fā)送低高優(yōu)先級發(fā)送了 1 條消息接收發(fā)送低高優(yōu)先級11 1 11 1 1管道空 , 高優(yōu)先級任務(wù)掛起11時間接收發(fā)送任務(wù)n 條消息n 條消息n 條消息n 條消息任務(wù) 1 時間片到任務(wù) 2 時間片到任務(wù) 1任務(wù) 2時間Nucleus 分析報告 21 任務(wù)的同步 Nucleus 提供:信號量( semaphores)、事件組( event groups)和信號( signals)來實。 ② 、兩個任務(wù)具有不同的優(yōu)先級,低優(yōu)先級任務(wù)不停地發(fā)送,高優(yōu)先級任務(wù)不停地接收。 如果管道中有消息,則管道中讀指針指向的消息會 copy 至接收任務(wù)的接收消息域 .。 如果管道上有空間存放消息,則要發(fā)送的消息就會 copy 至管道中。 如果被恢復(fù)的任務(wù)優(yōu)先級比做管道刪除系統(tǒng)調(diào)用的任務(wù)優(yōu)先級高,且做該系統(tǒng)調(diào)用的任 務(wù)可以搶占,則控制權(quán)會交給 TCT_Control_To_System,發(fā)生任務(wù)的搶占。 然后,將該管道插入已創(chuàng)建管道鏈表 PID_Created_Pipes_List。 pipepi_read, pipepi_write:管道的讀寫指針。 pipepi_fixed_size: NU_VARIABLE_SIZE 表示管道的消息類型是變長的; NU_FIXED_SIZE表示管道的消息類型是定長的。下面我們只拿管道來分析 Nucleus 的任務(wù)通信機制。隊列也可以動態(tài)地創(chuàng)建和刪除,隊列的數(shù)目不受限制。 Nucleus 的郵箱( mailboxes)提供的是單個消息的簡單通信機制。如果所有任務(wù)沒有設(shè)置信號燈選項,它們的工作方式是這樣的:優(yōu)先級低的任務(wù)獲得一個臨界資源且正在運行,高優(yōu)先級任務(wù)因為沒有獲得這一臨界資源而掛起,這時一個中優(yōu)先級任務(wù)就緒,如果低優(yōu)先級的任務(wù)是可以搶占的,它就會搶占低優(yōu)先級的任務(wù),造成高優(yōu)先級任務(wù)沒有機會運行。 注意: TCT_Schedule_Protected 并沒有修改 TCD_Execute_Task 及 TCD_ Execute_HISR,只是臨時地將擁有保護結(jié)構(gòu)的線程置為當前線程,當擁有保護結(jié)構(gòu)的線程釋放保護后,TCD_Schedule 又會恢復(fù)運行想得到保護結(jié)構(gòu)的 TCD_Execute_Task 或 TCD_ Execute_HISR。 TCD_Unprotect_Specific 首先清除指定保護結(jié)構(gòu)上掛的線程 tc_tcb_pointer,如果沒有其它線程在等待該保護結(jié)構(gòu)就直接返回。保護結(jié)構(gòu)的釋放有兩個系統(tǒng)調(diào)用: TCD_Unprotect 釋放的是線程當前的保護結(jié)構(gòu) tc_current_protect ;TCD_Unprotect_Specific 釋放的是用戶或操作系統(tǒng)指定的保護結(jié)構(gòu)。TCD_System_Protect),比如:任務(wù)的恢復(fù)、任務(wù)的掛起、消息管道的收發(fā)等,這些操作都要申請系統(tǒng)保護結(jié)構(gòu),當系統(tǒng)調(diào)用結(jié)束后,就要調(diào)用 TCT_Unprotect( )釋放當前線程擁有的保護結(jié)構(gòu)。 /* 有線程在等待該保護結(jié)構(gòu)的標志 */ }TC_PROTECT。任務(wù)運行時如果要修改操 作系統(tǒng)的數(shù)據(jù)結(jié)構(gòu),就要通過系統(tǒng)調(diào)用 TCT_Protect (TC_PROTECT *protect) 把該數(shù)據(jù)結(jié)構(gòu)的保護結(jié)構(gòu)保護起來,當任務(wù)對該數(shù)據(jù)結(jié)構(gòu)的操作結(jié)束就會通過系統(tǒng)調(diào)用 TCT_Unprotect (void) 或TCT_Unprotect_Specific (TC_PROTECT *protect) 來釋放保護結(jié)構(gòu)。然后將控制權(quán)交給 TCT_Shedule 重新調(diào)度,如果還有其它的 HISR 被激活,則重復(fù)上面的過程;否則進入任務(wù)的調(diào)度,或在 TCT_Shedule 死循環(huán),等待 HISR 被激活或任務(wù) ready。如果 TCD_Execute_HISR 只被激活了一次,則HISR 的入口函數(shù)只會執(zhí)行一次。 ⑧ 、 HISR 的調(diào)度 中斷恢復(fù)后,如果當前的 TCD_Execute_HISR是被中斷停下來的 HISR,則經(jīng) TCT_Shedule調(diào)度后,被中斷的 HISR 恢復(fù)運行。 激活 HISR 首先根據(jù)激活次數(shù) hisrtc_activation_count 來判斷該 HISR 是否已被激活。 iii)、中斷產(chǎn)生時,有一個高級中斷服務(wù)程序 HISR 在運行。 ii)、中斷產(chǎn)生時,有一個任務(wù)在運行。 要注意的是,如果某個中斷向量沒有注冊,則會產(chǎn)生系統(tǒng)錯誤,進入系統(tǒng)錯誤線程Nucleus 分析報告 11 ERC_System_Error 處理,這種錯誤是致命的錯誤,導(dǎo)致整個系統(tǒng)進入一個死循環(huán)。其次判斷中斷計數(shù)器TCD_Interrupt_Count,如果本次中斷是中斷嵌套,則將 TCD_Interrupt_Count 加 1,然后返回。一般來說, HISR 的刪除沒有什么意義,除非把跟 HISR 相關(guān)的中斷也關(guān)掉。另外,還要判斷 INT_Loaded_Flag標志,如果該標志為 0,則要替換掉當前的中斷向量表,否則不修改當前的中斷向量表。該系統(tǒng)Nucleus 分析報告 10 調(diào)用的第 2 個參數(shù)是 LISR 的入口函數(shù)指針,也就是中斷產(chǎn)生后要執(zhí)行的 LISR。 每個 HISR 具有一個 0~2 的優(yōu)先級, 0 表示最高優(yōu)先級, 2 表示最低優(yōu)先級,相同優(yōu)先級的HISR 按照先入先出的順序處理,優(yōu)先級不同的 HISR按照優(yōu)先級的高低進行調(diào)度。 TCD_Created_HISRs_List:已創(chuàng)建的 HISR 鏈表的頭指針。 0:沒有中斷;1:只有一個中斷; 1:中斷嵌套。 中斷的調(diào)度需要用到以下比較重要的數(shù)據(jù)結(jié)構(gòu): TCD_Registered_LISRs[256]:對應(yīng) 68360 的 256 個中斷向量。 非管理的中斷,則不需要通過操作系統(tǒng)進行管理,直接將中斷服務(wù)程序掛到中斷向量表上,上下文的保存與恢復(fù)都要用戶自己來做,該中斷自己不能嵌套,最好不要被管理的中斷再次中斷否則會引起堆棧出錯,而且非管理的中斷不能使用絕大多數(shù)的 Nucleus 系統(tǒng)調(diào)用,因為它可能會破壞操作系統(tǒng)某些保 護的數(shù)據(jù)結(jié)構(gòu)(當有線程在運行時)。 任務(wù)掛起流程如下: Nucleus 分析報告 8 T C C _ S u s p e n d _ T a s k要掛起的是當前任務(wù) ?N釋放任務(wù)的保護結(jié)構(gòu)任務(wù)狀態(tài)為 N U _ R E A D Y ?Y該任務(wù)優(yōu)先級中只有這一個任務(wù)就緒?YY清除優(yōu)先級組及子優(yōu)先級組中相應(yīng)位要掛起的任務(wù)具有最高優(yōu)先級 ?調(diào)整 T C D _ H i g h e s t _ P r i o r i t yY要掛起的任務(wù)是T C D _ E x e c u t e _ T a s k ?根據(jù)最高優(yōu)先級調(diào)整T C D _ E x e c u t e _ T a s kY要掛起的任務(wù)是 當前線程T C D _ C u r r e n t _ T h r e a d ?NN將控制權(quán) 交給系統(tǒng)重新調(diào)度Y將該任務(wù)從優(yōu)先級就緒任務(wù)鏈表中刪除N設(shè)置 t c _ d e l a y e d _ s u s p e n d標志為 N U _ T R U E返回N返回N清空該任務(wù)優(yōu)先級的就緒任務(wù)鏈表任務(wù)恢復(fù)( r e s u me )Nucleus 分析報告 9 中斷的調(diào)度 Nucleus 的中斷分為管理的和非管理的中斷。然后根據(jù)最高優(yōu)先級,重新調(diào)整 TCD_Execute_Task ,如果最高優(yōu)先級為 255 ,則TCD_Execute_Task=NU_NULL。 ⑥ 、掛起任務(wù)( TCC_Suspend_Task) 如果任務(wù)不能獲得執(zhí)行所需要的系統(tǒng)資源,比如:對于做 NU_Send_To_Pipe 系統(tǒng)調(diào)用的任務(wù)如果消息管道已滿,或者做 NU_Reveive_From_Pipe 系統(tǒng)調(diào)用的任務(wù)如果管道已空,那么任務(wù)就會被掛起。如果任務(wù) 處于 suspended 狀態(tài),則必須釋放和該任務(wù)相關(guān)的所有保護結(jié)A p p lic a t io n _ I n it ia liz eN U _ C r e a t e _ T a s kT C C _ C r e a t e _ T a s k初始化任務(wù)控制塊T C B 的各數(shù)據(jù)成員創(chuàng)建任務(wù)初始堆棧幀將該任務(wù)插入已創(chuàng)建任務(wù)鏈表T C D _ C r e a t e d _ T a s k s _ L is tc a ll T C C _ R e s u m e _ T a s k置任務(wù)狀態(tài)為 N U _ R E A D Y修改 T C D _ P r io r it y _ G r o u p s及 T C D _ S u b _ P r io r it y _ G r o u p s指示本任務(wù)對應(yīng)的優(yōu)先級有任務(wù) r e a d y根據(jù)任務(wù)優(yōu)先級調(diào)整T C D _ E x e c u t e _ T a s k將控制交給 T C T _ S c h e d u le進行 線程調(diào)度Nucleus 分析報告 7 構(gòu)后才能將任務(wù)終止。 ④ 、終止任務(wù)( TCC_Terminate_Task) 如果要終止的是當前任務(wù)( TCD_Current_Thread),則直接將任務(wù)掛起,將任務(wù)狀態(tài)置為NU_TERMINATED。任務(wù)創(chuàng)建的流程如下: Nucleus 分析報告 6 ② 、刪除任務(wù)( TCC_Delete_Task) 對任務(wù)刪除時,默認任務(wù)是處于 finished 或 terminated 狀態(tài)。一旦任務(wù)處于這種狀態(tài)就不能再執(zhí)行了,除非任務(wù)被復(fù)位。 Suspended:任務(wù)在等待請求服務(wù)完成的過程中被掛起,一旦請求服務(wù)完成,任務(wù)就會遷移至 ready 狀態(tài)。 TCD_Current_Thread:當前正在執(zhí)行的線程指針( TASK or HISR)。 TCD_Sub_Priority_Groups[32]:子優(yōu)先級組的位映像圖,每一元素對應(yīng)一組優(yōu)先級。 HISR_Shell 對 HISR 調(diào)度就是執(zhí)行 HISR 的入口程序,然后根據(jù)激活計數(shù)器循環(huán)調(diào)度, HISR 是不能被掛起的。 Nucleus 的線程有兩種類型的堆棧幀: 任務(wù)創(chuàng)建時,要建立一個初始堆棧幀,線程入口是 TCC_Task_Shell,該 Shell執(zhí)行任務(wù)的入口程序,通常任務(wù)的執(zhí)行是一個死循環(huán),不停地在等待消息或事件,如果沒有消息或事件任務(wù)就會掛起,否則往下執(zhí)行。 線程調(diào)度 TCT_Schedule 是線程調(diào)度的入口,負責(zé)將控制權(quán)交給具有最 高優(yōu)先級的高級中斷服務(wù)程序HISR( TCD_Execute_HISR)或處于就緒狀態(tài)的最高優(yōu)先級任務(wù)( TCD_Execute_Task)。 然后, 控制交給 INC_Initialize。 初始化線程 初始化線程是系統(tǒng)開始執(zhí)行的第一個線程,線程的入口是 INT_Initialize,同時 也是系統(tǒng)的主函數(shù),具有另外的標號名 main。 系統(tǒng)啟動 對于 68K系列的 CPU,如果采用 CrossCode C 編譯器的話, Nucleus 使用的是 CrossCode C的啟動函數(shù),標號 START 是系統(tǒng)的入口點。 Nucleus PLUS提供其他實時內(nèi)核都具有的系統(tǒng)服務(wù),比如:任務(wù)控制、任務(wù)通信、任務(wù)同步、內(nèi)存管理、可編程的定時器 、標準的輸入 /輸出設(shè)備接口等。 特性: ① 、快速響應(yīng)時間:對臨界資源 的檢測時間不依賴于占有該臨界資源的線程執(zhí)行時間的長短,一旦低優(yōu)先級線程釋放掉臨界資源(不管其是否執(zhí)行完),高優(yōu)先級線程就會搶占運行。因此,用戶可以利用多個 Nucleus PLUS 對象之間的結(jié)合形成混合系統(tǒng)調(diào)用。比如,你可以通過 Nu_Create_Task 系統(tǒng)調(diào)用來創(chuàng)建一個任務(wù)。 Nucleus 分析報告 3 一、 Nucleus 的內(nèi)核( Kernel) Nucleus 的核心是一個實時的多任務(wù)內(nèi)核 —— Nucleus PLUS,具有以下特性( Accelerater Technology 公司宣稱的): 可移植性: Nucleus PLUS 可用于大多數(shù)流行的處理器。如果使用另外的 CPU,則只用修改 6個匯編程序就可以進行移植,但是對于不同系列的處理器,它們的 Compiler、 Linker、 Debugger 是不同的(要另外購買),而且編譯預(yù)處理的過程也是不一樣的,這就要投入一部分力量去進行操作系統(tǒng)的移植。對于程序員來說,寫 BSP 是一項比較繁瑣的任務(wù),有了 OS 的源碼這項工作就簡單多了,同時調(diào)試時也可以跟蹤到中斷、寄存器那一