【正文】
t_Specific 首先清除指定保護(hù)結(jié)構(gòu)上掛的線程 tc_tcb_pointer,如果沒(méi)有其它線程在等待該保護(hù)結(jié)構(gòu)就直接返回。如果還有其它線程在等待該保護(hù)結(jié)構(gòu),則為當(dāng)前線程建立一個(gè) Solicited 類(lèi)型的堆棧幀,清除當(dāng)前線程 TCD_Current_Thread,將堆棧從線程堆棧切換到系統(tǒng)堆棧,然后將控制權(quán)交給 TCD_Schedule 重新進(jìn)行調(diào)度,從而引起 TASK 或 HISR 的競(jìng)爭(zhēng)(線程的搶占 )。 ③ 、保護(hù)的調(diào)度( TCT_Schedule_Protected) 保護(hù)結(jié)構(gòu)的調(diào)度也就是調(diào)度擁有保護(hù)結(jié)構(gòu)的線程,直至其釋放保護(hù)。 TCT_Schedule_Protected 首先為想得到保護(hù)結(jié)構(gòu)的當(dāng)前線程建立一個(gè) Solicited 類(lèi)型的堆棧幀,將擁有保護(hù)結(jié)構(gòu)的線程置為當(dāng)前線程 TCD_Current_Thread,將堆棧切換至系統(tǒng)堆棧,將控制權(quán)交給 TCT_Control_To_Thread,這里將恢復(fù)運(yùn)行因線程搶占而掛起的擁有保護(hù)結(jié)構(gòu)的線程,等其處理完相關(guān)數(shù)據(jù)結(jié)構(gòu) 后,就會(huì)調(diào)用 TCD_Unprotect 來(lái)釋放保護(hù)結(jié)構(gòu),釋放時(shí)就會(huì)發(fā)現(xiàn)還有另一個(gè)線程在等待該保護(hù)結(jié)構(gòu),然后控制權(quán)就會(huì)交給 TCD_Schedule 重新進(jìn)行調(diào)度,引起線程之間的競(jìng)爭(zhēng)。 注意: TCT_Schedule_Protected 并沒(méi)有修改 TCD_Execute_Task 及 TCD_ Execute_HISR,只是臨時(shí)地將擁有保護(hù)結(jié)構(gòu)的線程置為當(dāng)前線程,當(dāng)擁有保護(hù)結(jié)構(gòu)的線程釋放保護(hù)后,TCD_Schedule 又會(huì)恢復(fù)運(yùn)行想得到保護(hù)結(jié)構(gòu)的 TCD_Execute_Task 或 TCD_ Execute_HISR。 數(shù)據(jù)結(jié)構(gòu)保護(hù)的處理示意圖如下: Nucleus 分析報(bào)告 16 Nucleus 操作系統(tǒng)不具備優(yōu)先級(jí)自動(dòng)逆轉(zhuǎn)的功能,它有自己的解決方法。當(dāng)高優(yōu)先級(jí)的線程不能獲得臨界系統(tǒng)資源時(shí),高優(yōu)先級(jí)的任務(wù)并沒(méi)有掛起,所有在此優(yōu)先級(jí)之下的線程就都不能運(yùn)行, Nucleus 會(huì)把擁有臨界系統(tǒng)資源的低優(yōu)先級(jí)線程臨時(shí)地升為當(dāng)前線程 TCD_Current_Thread(相當(dāng)于臨時(shí)把優(yōu)先級(jí)升為最高),當(dāng)?shù)蛢?yōu)先級(jí)的線程釋放臨界系統(tǒng)資源后,高優(yōu)先級(jí)的任務(wù)馬上會(huì)恢復(fù)運(yùn)行。 VxWorks 是通過(guò)互斥信號(hào)燈來(lái)實(shí)現(xiàn)優(yōu)先級(jí)自動(dòng)逆轉(zhuǎn)的,操作系統(tǒng)能自動(dòng)提升獲得此信號(hào)燈的所有任務(wù)的 優(yōu)先級(jí),與獲得此信號(hào)燈的最高優(yōu)先級(jí)任務(wù)相同。如果所有任務(wù)沒(méi)有設(shè)置信號(hào)燈選項(xiàng),它們的工作方式是這樣的:優(yōu)先級(jí)低的任務(wù)獲得一個(gè)臨界資源且正在運(yùn)行,高優(yōu)先級(jí)任務(wù)因?yàn)闆](méi)有獲得這一臨界資源而掛起,這時(shí)一個(gè)中優(yōu)先級(jí)任務(wù)就緒,如果低優(yōu)先級(jí)的任務(wù)是可以搶占的,它就會(huì)搶占低優(yōu)先級(jí)的任務(wù),造成高優(yōu)先級(jí)任務(wù)沒(méi)有機(jī)會(huì)運(yùn)行。如果低優(yōu)先級(jí)和高優(yōu)先級(jí)的任務(wù)都設(shè)置了互斥信號(hào)燈,操作系統(tǒng)會(huì)自動(dòng)提高低優(yōu)先級(jí)任務(wù)的優(yōu)先級(jí)和高優(yōu)先級(jí)任務(wù)相同,這樣就不會(huì)出現(xiàn)上面的問(wèn)題。 任務(wù)間通信 Nucleus 任務(wù)間的通信機(jī)制有郵箱( mailboxes), 消息對(duì)列( queues),消息管道( pipes)。它們之間的主要不同之處在于使用的消息結(jié)構(gòu)不同。 Nucleus 的郵箱( mailboxes)提供的是單個(gè)消息的簡(jiǎn)單通信機(jī)制。每個(gè)郵箱最多只能容納一條 4 個(gè)長(zhǎng)字( 16 bytes)的消息。郵箱可以動(dòng)態(tài)地創(chuàng)建和刪除,郵箱的數(shù)目不受限制。 Nucleus 的隊(duì)列( queues)提供的是傳送多個(gè)消息的通信機(jī)制,一條消息由一個(gè)以上的長(zhǎng)字組成,支持定長(zhǎng)和變長(zhǎng)的消息類(lèi)型。隊(duì)列也可以動(dòng)態(tài)地創(chuàng)建和刪除,隊(duì)列的數(shù)目不受限制。 Nucleus 的管道( pipes)提供的也是傳送多個(gè)消息 的通信機(jī)制,一條消息由由一個(gè)以上的字節(jié)組成,支持定長(zhǎng)和變長(zhǎng)的消息類(lèi)型。管道也可以動(dòng)態(tài)地創(chuàng)建和刪除,管道的數(shù)目不受限制。 Nucleus 的隊(duì)列和管道是十分類(lèi)似的,不同之處在于:隊(duì)列的消息按長(zhǎng)字來(lái)訪問(wèn),管道的消息按字節(jié)來(lái)訪問(wèn)。下面我們只拿管道來(lái)分析 Nucleus 的任務(wù)通信機(jī)制。 T C T _ P ro te c tT C T _ P ro te c t T C T _ S c h e d u l e _ P ro t e c te dT C T _ U n p ro t e c tT C T _ S c h e d u l eT C T _ U n p ro t e c t時(shí)間優(yōu)先級(jí)低高Nucleus 分析報(bào)告 17 消息管道( Pipes) 管道支持定長(zhǎng)和變長(zhǎng)的消息類(lèi)型,消息格式的類(lèi)型在創(chuàng)建時(shí)就已經(jīng)固定。定長(zhǎng)消息的管道比較好管理,每條消息都具有固定的長(zhǎng)度;變長(zhǎng)消息的管道管理起來(lái)就相對(duì)復(fù)雜一點(diǎn),每條消息前還要加四個(gè) bytes 用來(lái)指示消息的長(zhǎng) 度,一條變長(zhǎng)的消息有時(shí)不是位于連續(xù)的內(nèi)存空間,也就是當(dāng)管道寫(xiě)指針指到管道尾時(shí),一條變長(zhǎng)消息就會(huì)分成管道的首尾兩塊。 ① 、管道的創(chuàng)建( PIC_Create_Pipe) 管道創(chuàng)建時(shí),首先要對(duì)以下比較重要的管道控制塊數(shù)據(jù)成員賦初值,用來(lái)確定管道的大小和消息類(lèi)型: pipepi_fifo_suspend: NU_FIFO 表示任務(wù)在管道上的掛起順序是按先入先出( FIFO)的順序; NU_PRIORITY 表示任務(wù)在管道上的掛起順序是按照優(yōu)先級(jí)的順序。 pipepi_fixed_size: NU_VARIABLE_SIZE 表示管道的消息類(lèi)型是變長(zhǎng)的; NU_FIXED_SIZE表示管道的消息類(lèi)型是定長(zhǎng)的。 pipepi_message_size:對(duì)于定長(zhǎng)的消息類(lèi)型,表示每條消息的大小;對(duì)于變長(zhǎng)類(lèi)型的消息,表示最長(zhǎng)消息的大小。 pipepi_pipe_size:管道總的大小。 pipepi_start, pipepi_end:管道在內(nèi)存空間的起始和終止地址指針。 pipepi_read, pipepi_write:管道的讀寫(xiě)指針。 pipepi_suspend_list:管道上的掛起任務(wù)鏈表頭指針; pipepi_urgent_list:管道上發(fā)送緊急消息的掛起任務(wù)鏈表頭指針。 pipepi_tasks_waiting:管道上等待任務(wù)的個(gè)數(shù)。 注意:只有任務(wù)才能掛起在管道上, HISR 是不能掛起的, HISR 在管道上收發(fā)消息的時(shí)候都要使用 NU_NO_SUSPEND 選項(xiàng)。 然后,將該管道插入已創(chuàng)建管道鏈表 PID_Created_Pipes_List。 ② 、管道的刪除( PIC_Delete_Pipe) 管道的刪除首先要把該管道從已創(chuàng)建 管道鏈表中刪除。 其次,將管道掛起任務(wù)鏈表 pipepi_suspend_list 上被掛起的任務(wù)(在管道上收發(fā)消息時(shí)被掛起)全部恢復(fù)( TCC_Resume_Task),給所有的任務(wù)返回狀態(tài) NU_PIPE_DELETED。 然后,將管道緊急消息掛起鏈表 pipepi_urgent_list 上被掛起的任務(wù)(做PIS_Send_To_Front_Of_Pipe 調(diào) 用 時(shí) 被 掛 起 ) 全 部 恢 復(fù) , 給 所 有 任 務(wù) 返 回 狀 態(tài)NU_PIPE_DELETED。 如果被恢復(fù)的任務(wù)優(yōu)先級(jí)比做管道刪除系統(tǒng)調(diào)用的任務(wù)優(yōu)先級(jí)高,且做該系統(tǒng)調(diào)用的任 務(wù)可以搶占,則控制權(quán)會(huì)交給 TCT_Control_To_System,發(fā)生任務(wù)的搶占。 ③ 、往管道發(fā)送消息( PIC_Send_To_Pipe) PIC_Send_To_Pipe 負(fù)責(zé)往指定的管道發(fā)送消息,消息的長(zhǎng)度由用戶(hù)指定。 如果管道上有一個(gè)或更多的任務(wù)在等待消息,則發(fā)送的消息直接拷貝至第一個(gè)等待任務(wù)的消息域,同時(shí)掛起的任務(wù)被恢復(fù),如果被恢復(fù)的任務(wù)優(yōu)先級(jí)比當(dāng)前任務(wù)的優(yōu)先級(jí)高,且當(dāng)前任Nucleus 分析報(bào)告 18 務(wù)可以搶占,則控制權(quán)會(huì)交給 TCT_Control_To_System,發(fā)生任務(wù)的搶占 。 如果管道上沒(méi)有足夠的空間來(lái)存放消息,則往管道發(fā)送消息的任務(wù)就會(huì)被掛起(可以選擇掛起或不掛起)。 如果管道上有空間存放消息,則要發(fā)送的消息就會(huì) copy 至管道中。 往管道發(fā)送消息的處理流程如下: ④ 、從管道中接收消息( PIC_Receive_From_Pipe) PIC_Receive_From_Pipe 負(fù)責(zé)從指定的管道中接收消息,接收到的消息的實(shí)際長(zhǎng)度放在actual_size 中。 P i c _ S e n d _ T o _ P i p eT C T _ S y s t e m_ P r o t e c t變長(zhǎng)消息類(lèi)型?計(jì)算 p a d ,保證每條消息位于一個(gè)長(zhǎng)字的邊界Y管道中有足夠的空間存放消息?N要將任務(wù)掛起?N建立一個(gè)掛起控制塊插入 管道掛起任務(wù)鏈表Y調(diào)用 T C C _ S u s p e n d _ T a s k掛起任務(wù)T C T _ S c h e d u l e其它的任務(wù)從管道中取走消息本次發(fā)送的消息就會(huì)填入管道中調(diào)用 T C C _ R e s u m e _ T a s k恢復(fù)任務(wù)返回N U _ S U C C E S S消息丟失返回 N U _ P I P E _ F U L LN有任務(wù)在等待從管道中接收消息?將要發(fā)送的消息填入掛起任務(wù)接收消息域Y調(diào)用 T C C _ R e s u m e _ T a s k恢復(fù)被掛起任務(wù)當(dāng)前任務(wù)可以搶占且被掛起的任務(wù)比當(dāng)前任務(wù)優(yōu)先級(jí)高?T C T _ C o n t r o l _ T o _ S y s t e m發(fā)生任務(wù)的搶占Y返回N U _ S U C C E S SNY將要發(fā)送的消息c o p y 至管道中N調(diào)整管道的寫(xiě)指針調(diào)整管道的可用空間管道消息計(jì)數(shù)器 加 1p i _ m e s s a g e s + +Nucleus 分析報(bào)告 19 如果管道中沒(méi)有消息,任務(wù)可以選擇掛起與否。 如果有任務(wù)做 PIS_Send_To_Front_Of_Pipe 系統(tǒng)調(diào)用發(fā)送緊急消息到管道中,由于管道中沒(méi)有空間而被掛起,則緊急消息會(huì) copy 至接收任務(wù)的接收消息域,被掛起的任務(wù)馬上會(huì)恢復(fù),如果當(dāng)前任務(wù)可以搶占且被掛起的任務(wù)比當(dāng)前任務(wù)優(yōu)先級(jí)高,則控制權(quán)會(huì)交給TCT_Control_To_System,發(fā)生任務(wù)搶占。 如果管道中有消息,則管道中讀指針指向的消息會(huì) copy 至接收任務(wù)的接收消息域 .。如果有發(fā)送消息的任務(wù)掛起在管道上,且管道中又有空間存放其要發(fā)送的消息,則被掛起的任務(wù)會(huì)恢復(fù),其要發(fā)送的消息會(huì) copy至管道中。如果當(dāng)前任務(wù)可以搶占且被 掛起的任務(wù)比當(dāng)前任務(wù)優(yōu)先級(jí)高,則控制權(quán)會(huì)交給 TCT_Control_To_System,發(fā)生任務(wù)搶占。 從管道接收消息的處理流程如下: 拿兩個(gè)任務(wù)舉列來(lái)說(shuō)明消息管道的收發(fā)過(guò)程(假設(shè)沒(méi)有其它任務(wù)在運(yùn)行): P I C _ R e c e i v e _ F r o m_ P i p eT C T _ S y s t e m _ P r o t e c tp i p e p i _ u r g e n t _ l i s t ?將掛起的緊急消息c o p y 至 消息接收域調(diào)用 T C T _ R e s u m e _ T a s k恢復(fù) 被 掛起的 任務(wù)搶占條件成立?T C T _ C o n t r o l _ T o _ S y s t e m發(fā)生任務(wù) 搶占本任務(wù)重新得到控制權(quán)返回 N U _ S U C C E S SYN管道中有消息?YN將消息 c o p y 至消息接收域Y調(diào)整管道讀指針及管道可用空間大小有發(fā)送消息任務(wù)掛起在管道上,且管道中有空間存放要發(fā)送的消息將消息填入管道中調(diào)整管道寫(xiě)指針及管道可用空間大小YN建立一個(gè)掛起塊插入 管道掛起任務(wù)鏈表調(diào)用 T C T _ S u s p e n d _ T a s k掛起任務(wù)將控制 交給T C T _ S c h e d u l e其它任務(wù)往管道中發(fā)消息本任務(wù)恢復(fù)運(yùn)行將消息 c o p y 至消息接收域調(diào)整管道讀指針及管道可用空間大小返回 N U _ S U C C E S SNNucleus 分析報(bào)告 20 ① 、兩個(gè)任務(wù)具有不同的優(yōu)先級(jí),高優(yōu)先級(jí)任務(wù)不停地發(fā)送,低優(yōu)先級(jí)任務(wù)不停地接收。 ② 、兩個(gè)任務(wù)具有不同的優(yōu)先級(jí),低優(yōu)先級(jí)任務(wù)不停地發(fā)送,高優(yōu)先級(jí)任務(wù)不停地接收。 ③ 、兩個(gè)任務(wù)具有相同的優(yōu) 先級(jí),分時(shí)間片運(yùn)行。 發(fā)送了 n 條消息 管道擁塞,高優(yōu)先級(jí)任務(wù)掛起11 1 11 1 1接收發(fā)送低高優(yōu)先級(jí)發(fā)送了 1 條消息接收發(fā)送低高優(yōu)先級(jí)11 1 11 1 1管道空 , 高優(yōu)先級(jí)任務(wù)掛起11時(shí)間接收發(fā)送任務(wù)n 條消息n 條消息n 條消息n 條消息任務(wù) 1 時(shí)間片到任務(wù) 2 時(shí)間片到任務(wù) 1任務(wù) 2時(shí)間Nucleus 分析報(bào)告 21 任務(wù)的同步 Nucleus 提供:信號(hào)量( semaphores)、事件組( event groups)和信號(hào)( signals