下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
頁(yè)次頁(yè)次iiQNX簡(jiǎn) 架構(gòu)概 架構(gòu)對(duì) 首要移植問(wèn) 移植策 建議移植路 詳細(xì)對(duì) 內(nèi)核可 QNX 可移植操作系統(tǒng)接口(POSIX)支 內(nèi)存可 QNX 任務(wù)間/進(jìn)程間通 VxWorks信息隊(duì)列實(shí) QNXNeutrino版本(信息隊(duì)列 使用單獨(dú)進(jìn)程的QNXNeutrino版 VxWorks共享內(nèi)存實(shí) QNXNeutrino版本(共享內(nèi)存 使用單獨(dú)進(jìn)程的QNXNeutrino版 VxWorks監(jiān)視程序計(jì)時(shí)器的實(shí) QNXNeutrino版本(監(jiān)視程序計(jì)時(shí)器 異常處 QNX 結(jié) 移植元 啟動(dòng)代 VxWorks啟 結(jié) 硬件輸入/輸出設(shè) 中斷服務(wù)例程 輸入/輸 設(shè)備驅(qū)動(dòng)程 網(wǎng) VxWorks網(wǎng)絡(luò)架 QNXNeutrino網(wǎng)絡(luò)架 結(jié) 網(wǎng)絡(luò)應(yīng)用程序編 應(yīng)用程序的移 vx2qnx.lib概 構(gòu)建環(huán) 生成文 應(yīng)用程序內(nèi)存的使 附 移植參 運(yùn)行區(qū) 參考文 圖 圖2:QNXNEUTRINO架構(gòu)提供全內(nèi)存保護(hù) 圖3:QNXNEUTRINO中單獨(dú)的多線程進(jìn)程 圖4:QNXNEUTRINO中的多個(gè)多線程進(jìn)程 圖7:QNXNEUTRINO中的內(nèi)存管理 圖8:QNXNeutrino中的函數(shù)mmap() 圖10:QNXNEUTRINO的啟動(dòng)順序 圖11:VXWORKS的輸入/輸出系統(tǒng) QNX軟件系統(tǒng)公 頁(yè)次iii頁(yè)次頁(yè)次ivQNX圖12:QNXNEUTRINO中的設(shè)備輸入/輸出 圖13:QNXNEUTRINO中的文件系統(tǒng)分層 圖14:VXWORKS的網(wǎng)絡(luò)架構(gòu) 圖15:QNXNEUTRINO的網(wǎng)絡(luò)架構(gòu) 圖15:IO-PKT架構(gòu) 圖16:VXWORKS遺留程序 簡(jiǎn)WindRiverVxWorks系統(tǒng)是過(guò)去十年來(lái)非常成功的一款實(shí)時(shí)操作系統(tǒng)。與桌面/服務(wù)器操作系統(tǒng)的復(fù)雜性相比,VxWorks操作系統(tǒng)結(jié)構(gòu)的相QNX?Nti?開(kāi)發(fā)未來(lái)平臺(tái)軟件的途徑。嵌入式系統(tǒng)的開(kāi)發(fā)人員現(xiàn)在能使其產(chǎn)品具有與高級(jí)操作系統(tǒng)一樣的復(fù)雜功能,同時(shí)又能精確響應(yīng)嵌入式系統(tǒng)環(huán)境的獨(dú)特NXNuoMSS-4與x6傳統(tǒng)意義上,從實(shí)時(shí)操作系統(tǒng)(VxWorks)向高級(jí)操作系統(tǒng)(QNX的各種選擇可能對(duì)移植過(guò)程產(chǎn)生深遠(yuǎn)的影響。認(rèn)識(shí)到這種情況后,QNX開(kāi)發(fā)了功能全面的遷移工具(包括本文件)Library庫(kù),幫助客戶以更VxWorksQNXNeutrino實(shí)時(shí)操作VxWorks向QNXNeutrino移植是僅使用所有重要,但無(wú)法對(duì)這一復(fù)雜的專題進(jìn)行詳盡論述。必要時(shí),您可參考其它QNX文件以深入了解該專題。本文涉及到應(yīng)用程序開(kāi)發(fā)/移植的各個(gè)階段,并對(duì)兩種操作系統(tǒng)進(jìn)行了對(duì)比。它闡述了移植策略并了兩種操作系統(tǒng)之間的主要異同點(diǎn)。概括介紹移植要求之外,本文還對(duì)QNXNeutrino與VxWorks的應(yīng)用程序接最后,本文還介紹vx2qnx移植庫(kù)QNXNeutrino移植VxWorks應(yīng)移植到QNXNeutrino系統(tǒng)中,但該移植庫(kù)實(shí)現(xiàn)了VxWorks的關(guān)鍵功能,因注意:本文中的“VxWorks”在所有情況下均指WindRiver公司5.x版產(chǎn)品組合,而不是指其AE產(chǎn)品。架構(gòu)概架構(gòu)圖1:VxWorks系統(tǒng)的架構(gòu)DeviceVxWorksDeviceI/OInterruptIntertaskMemory1顯示的是系統(tǒng)架構(gòu)示意圖。VxWorks內(nèi)核很小,除含有調(diào)度程序外,操作系統(tǒng)通過(guò)使用和同步技術(shù)監(jiān)視任務(wù)的執(zhí)行情況??蓳屨际絻?nèi)(MMU),但在執(zhí)行指令和數(shù)據(jù)高速緩存(如需要)時(shí)可能需要使用它()。內(nèi)存管理單元是以任務(wù)內(nèi)存時(shí)使用物理內(nèi)存地址的方式建立的。也就是說(shuō),無(wú)需內(nèi)存地址轉(zhuǎn)換以從任務(wù)內(nèi)使用的內(nèi)存地址中獲取物理地址。需要重視的是,盡管VxWorks可啟用內(nèi)存管理單元,但它不提供任何內(nèi)存保護(hù)功能。任務(wù)與操作系統(tǒng)內(nèi)核之間的通信是通過(guò)一個(gè)簡(jiǎn)單的函數(shù)調(diào)用接口完成的,(也可能不會(huì)中斷服務(wù)例程(ISR)與設(shè)備驅(qū)動(dòng)器(由WindRiver或用戶提供)是通過(guò)調(diào)用口可確保使用標(biāo)準(zhǔn)的輸入/輸出調(diào)用(打開(kāi)、、寫入等)設(shè)備。設(shè)QNXNeutrinoQNXNeutrino是一種基于微內(nèi)核且具有微內(nèi)核結(jié)構(gòu)的操作系統(tǒng),它能提供如可通過(guò)QNXNeutrino微內(nèi)核管理的基元與同步基元互相通信,這種架構(gòu)與傳統(tǒng)的實(shí)時(shí)執(zhí)行程序和單核nx式系統(tǒng)有本質(zhì)的區(qū)別。NXNuro(IC)服務(wù),并通過(guò)附加的服務(wù)進(jìn)程擴(kuò)展內(nèi)核功能方面有顯著區(qū)別。由于操作系統(tǒng)是以微內(nèi)核管理的一組協(xié)作進(jìn)程的形式實(shí)現(xiàn)的,因此用戶編寫的進(jìn)程可同時(shí)用作(針對(duì)與用戶有關(guān)的程序因此,操作系統(tǒng)本身就變?yōu)椤伴_(kāi)放”式的,而且易于擴(kuò)展。QNXNeutrino充分利用處理器的內(nèi)存管理單元在受保護(hù)的運(yùn)行環(huán)境中提供完整的可移植操作系統(tǒng)接口(POSIX)進(jìn)程模型。微內(nèi)核可為用戶應(yīng)用程序?yàn)榍度胧綉?yīng)用程序,特別是任務(wù)關(guān)鍵型系統(tǒng)增加內(nèi)存保護(hù)功能能實(shí)現(xiàn)的主要優(yōu)勢(shì)是提高系統(tǒng)的穩(wěn)定性。如果在多任務(wù)處理環(huán)境中運(yùn)行的某個(gè)進(jìn)程試圖未明確或分配用于其類型的內(nèi)存資源,內(nèi)存管理單元硬件就能利用內(nèi)存保護(hù)功能通知操作系統(tǒng),由其(通過(guò)失敗/指令中止線程。這樣可以在進(jìn)程地址空間之間提供“保護(hù)”,防止一個(gè)進(jìn)程中出現(xiàn)的線程編碼錯(cuò)誤“損壞”其他進(jìn)程(或操作系統(tǒng))中的線程使用的內(nèi)存。這蓋的內(nèi)存,那么調(diào)試會(huì)十分。啟用內(nèi)存管理單元后,操作系統(tǒng)就能在出現(xiàn)內(nèi)存時(shí)立即中止進(jìn)程,為程序員提供即時(shí)反饋,而不是一段時(shí)間之后莫名其妙地導(dǎo)致系統(tǒng)。操作系統(tǒng)還能提供失敗進(jìn)程中錯(cuò)誤指圖2:QNXNeutrino架構(gòu)提供全內(nèi)存保護(hù)。UserUserDevice在宏內(nèi)核架有許乎相當(dāng)于整個(gè)操作系統(tǒng),而QNX基本的系統(tǒng)服務(wù),包括處理線程、信號(hào)、、同步、調(diào)度、計(jì)時(shí)器和進(jìn)程。與線程不同,QNXNeutrino本身不會(huì)被安排執(zhí)行任務(wù)。只有個(gè)操作系統(tǒng)都是在這些調(diào)用的基礎(chǔ)上構(gòu)建的。QNXNeutrino是一種完全可QNXNeutrino微內(nèi)核的最小復(fù)雜性可為通過(guò)內(nèi)核的不可搶占的最長(zhǎng)代碼路徑設(shè)置上限,其緊湊的代碼大小允許對(duì)復(fù)雜的多處理器問(wèn)題進(jìn)行。加系統(tǒng)進(jìn)程與用戶編寫的程序在本質(zhì)上很難區(qū)分——因?yàn)樗鼈兌际褂孟嗤墓灿眯蚪雍秃危ㄓ羞m當(dāng)?shù)膽暨M(jìn)使用內(nèi)服QNXNtrno操作系統(tǒng)本身很簡(jiǎn)單:只需編寫新程序提供新的操作系統(tǒng)服務(wù)即可。VxWorks中的基本運(yùn)行單元是任務(wù)。QNXNeutrino中的基本運(yùn)行單元是線程。QNXNeutrino中的線程會(huì)集中進(jìn)入名為“進(jìn)程”的容器內(nèi),并通過(guò)操作系統(tǒng)進(jìn)行控制和調(diào)度。VxWorksQNXNeutrino的線程是一樣的。VxWorks中的任務(wù)控制taskLib函數(shù)實(shí)現(xiàn)的,而QNXNeutrino中的線程控制是通過(guò)pthread_函數(shù)族實(shí)現(xiàn)的。VxWorks中只有一個(gè)“任務(wù)容器”,即操作系統(tǒng)本身。在QNXNeutrino中, 共享內(nèi)存區(qū),但進(jìn)程必須使用函數(shù)shm_*明確指明其想要共享的內(nèi)存區(qū)。QNXNeutrino中的操作系統(tǒng)和應(yīng)用程序之間有非常清楚的界限。進(jìn)入操作系統(tǒng)的調(diào)用是通過(guò)能完全用戶應(yīng)用程序和操作系統(tǒng)的系統(tǒng)調(diào)用接口實(shí)VxWorks提供的基于函數(shù)的操作系統(tǒng)接口形成了鮮明對(duì)比,因?yàn)槠渲械膮?shù)錯(cuò)誤或內(nèi)存指針會(huì)導(dǎo)致操作系統(tǒng)內(nèi)部結(jié)構(gòu)的損壞。是顯而易見(jiàn)的。在VxWorks中,操作系統(tǒng)組件必須到應(yīng)用程序中,以的方式建立的,并單獨(dú)在文件系統(tǒng)中以便隨后執(zhí)行。用戶無(wú)法修改QNXNeutrino內(nèi)核,由于其具有可擴(kuò)展的架構(gòu),因此也無(wú)需修QNXNeutrino中,用戶可通過(guò)向其他協(xié)作進(jìn)程發(fā)送信息來(lái)擴(kuò)展內(nèi)核的功能。Vrs中的內(nèi)存幾乎總是按照“一對(duì)一”映射的方式進(jìn)行的,其中的物理內(nèi)存地址與應(yīng)用程序的地址完全相同。QNXNtrno啟用了虛擬內(nèi)存;內(nèi)存管理單元會(huì)將應(yīng)用程序地址轉(zhuǎn)換成對(duì)應(yīng)的物理內(nèi)存地址,同時(shí)將適當(dāng)?shù)膬?nèi)存保護(hù)標(biāo)準(zhǔn)用于被的內(nèi)存。如果需要一個(gè)特殊的物理內(nèi)用_*將內(nèi)存空“映射”到進(jìn)存空間。如果需要知道應(yīng)用程序的物理地址(如要將緩沖庫(kù)位輸入硬件設(shè)備),就(e_offse()_ece_eoy()_ee_())轉(zhuǎn)換地址。QNXNeutrino程中加入了“”和“權(quán)”概念。這在本質(zhì)上提供了一種可限制線程使用的功能的機(jī)制。例如,在x86架構(gòu)中,線程必須具有輸入/輸出(通過(guò)使用函數(shù)ThreadCtl()取得)和根權(quán)(通過(guò)在應(yīng)用他處理器族中也提供了類似的級(jí)別。首要移植VxWorksQNXNeutrino的程序庫(kù)應(yīng)用程序接口有很大差異。雖然兩QNXNeutrino例程中。必須將應(yīng)用程序地址轉(zhuǎn)換成物理內(nèi)存地址QNXNeutrino中,不同進(jìn)程中的線程之間不會(huì)自動(dòng)共享內(nèi)存。必須移植策QNXNeutrinoVxWorksvx2qnx移植庫(kù),以最少量的修改將大部分應(yīng)用程序代碼從VxWorks遷移到QNX使用適QNXNeutrino調(diào)用VxWorks私有函數(shù)。這種替換可通過(guò)手動(dòng)方式完成,或通過(guò)使用代碼分析工具自動(dòng)完成。由于某些因此需要對(duì)一部分應(yīng)用程序代碼進(jìn)行重新架構(gòu)和修改,以適應(yīng)QNXNeutrino提供的架構(gòu)與服務(wù)。rsQNXNtrno。最理想的是,能使這種遷移像“重建并運(yùn)行”一樣簡(jiǎn)單。但在實(shí)際中,多數(shù)應(yīng)用程序都很復(fù)雜,而且操作系統(tǒng)架構(gòu)存在很大差異,因此無(wú)法在實(shí)際操作中實(shí)現(xiàn)完全模擬。同時(shí),常見(jiàn)的操作系統(tǒng)中還有數(shù)百種應(yīng)用程序接口功能。因此,正確地模擬所有應(yīng)用程序接口功能不僅而且容易出錯(cuò)。第二種方案要求從VxWorks向QNXNeutrino移植應(yīng)用程序,這涉及到修改一部分代碼以體QNXNeutrino提供的新架構(gòu)與服務(wù)。這樣您就不必再通過(guò)VxWorks進(jìn)行編碼就能不斷取得進(jìn)展,以開(kāi)發(fā)能使用QNXNeutrino中和冗長(zhǎng)的轉(zhuǎn)換過(guò)程是明顯的不利因?yàn)槌浞掷鸔NXNeutrino的功能兩種方案都需要VxWorks私有函數(shù)到QNXNeutrino私有函數(shù)調(diào)用的適當(dāng)映函數(shù)語(yǔ)法更改(一對(duì)一映射能以模擬VxWorks功能)vx2qnxVxWorks功能(如任務(wù)庫(kù)功能、信號(hào)量、信息隊(duì)列等)。由于開(kāi)源移植庫(kù)已經(jīng)指明并且其他第提供的資源也已確認(rèn),因POSIX操作系統(tǒng)(QNXNeutrino)上開(kāi)VxWorks應(yīng)用能無(wú)法處理需要直接硬件的代碼(因?yàn)檫@種代碼依賴于相同的物理和代碼進(jìn)行手動(dòng)移植,以確保將其正確集成到QNXNeutrino架構(gòu)中。VxWorksVxSim產(chǎn)品可識(shí)別能以這種方式移植的應(yīng)用程序部分和需要的應(yīng)用程序在兩種目標(biāo)硬件和VxSim上運(yùn)行,因此您應(yīng)該使vx2qnx移植層在QNXNeutrino上“重建并運(yùn)行”應(yīng)用程序。vx2qnx移植庫(kù)完成大應(yīng)引入一種規(guī)劃策略,以盡快使用本QNXNeutrino代碼,這樣就能實(shí)現(xiàn)QNXNeutrino的全部功能集并在必要時(shí)進(jìn)行優(yōu)化。圖3:QNXNeutrino中單獨(dú)的多線程進(jìn)程。ProtectedmemoryDeviceQNXNeutrino4所示。可QNXNeutrino進(jìn)程間通信(IPC)調(diào)用或共享內(nèi)存區(qū),以便進(jìn)程圖4:QNXNeutrino中的多個(gè)多線程進(jìn)程。ProtectedProtectedmemoryDeviceProtectedmemoryProtectedmemoryProtectedmemoryProtectedmemoryVxWorks運(yùn)行模式的方方案二更令人滿意,但其需完成的工作量更大。它能實(shí)QNXNeutrino提供的完全保護(hù)和功能。但除了重新編寫之外,很可能還需要對(duì)代碼進(jìn)行逐步完成移植。可使用QNXNeutrino或針對(duì)進(jìn)程間通信的vx2qnx移VxWorks任務(wù),并將其放入單獨(dú)的進(jìn)程中。清晰的進(jìn)程間通口就是為松散耦合的任務(wù)設(shè)分離機(jī)制提供的附加模塊化和功能,能在針對(duì)某些問(wèn)題進(jìn)行故障排解時(shí)大顯身手,例如解決“內(nèi)存”(一個(gè)任務(wù)覆寫另一個(gè)任務(wù)擁有的內(nèi)機(jī)QNXNeutrino函數(shù)調(diào)用。程序并完全實(shí)現(xiàn)QNXNeutrino的增強(qiáng)功能。建議移植VxWorks線程的單獨(dú)進(jìn)程。這樣就能在最短時(shí)識(shí)別任何有性能問(wèn)題的區(qū)域,并使用本機(jī)QNXNeutrino調(diào)用對(duì)這部分析代碼庫(kù)并引入使用本機(jī)QNXNeutrino進(jìn)程間通信機(jī)制(針對(duì)松QNXNeutrino函數(shù)啟用這些功能,內(nèi)核可圖5:在VxWorks中,所有內(nèi)容都是在“內(nèi)核空間”內(nèi)運(yùn)行的KernelKernelFunctionFunctionDeviceVxWorks中的內(nèi)核在許多層上都是可完全的,包括任務(wù)對(duì)它的無(wú)意任務(wù)通過(guò)VxWorks程序庫(kù)提供的直接函數(shù)調(diào)用獲得對(duì)內(nèi)核的權(quán)限。操作系統(tǒng)內(nèi)所有可執(zhí)行組件都能所有數(shù)據(jù)區(qū)任務(wù)管理是通過(guò)VxWorks調(diào)度程序進(jìn)taskHook例程(位于taskLib內(nèi))修改任務(wù)執(zhí)行的一些特征。這些包括taskSwitchHookAdd()、控制塊(TCB)結(jié)構(gòu)與任務(wù)有關(guān)的操作系統(tǒng)信息。雖然可以進(jìn)行這種訪問(wèn),但由于用于信息的C結(jié)構(gòu)在不同的釋放之間會(huì)發(fā)生變化,因此建議您不要采用這種。這些結(jié)構(gòu)的損壞(可在顯示所有任務(wù)信息時(shí)檢測(cè)VxWorks中的任務(wù)調(diào)度是基于優(yōu)先級(jí)的,而且可通過(guò)兩種調(diào)度模式實(shí)現(xiàn)完全搶占:即先入先出(FIFO)調(diào)度和循環(huán)調(diào)度。任務(wù)控制是通過(guò)taskLib庫(kù)完成的??赏ㄟ^(guò)調(diào)用延遲任務(wù)的調(diào)度期(taskDelay)、防止任務(wù)被搶占(taskLock/intLock)、更改任務(wù)的優(yōu)先級(jí)(taskPrioritySet)等。QNXQNXNeutrino微內(nèi)核與進(jìn)程管理器在單獨(dú)的模(to)內(nèi)配對(duì)。所有運(yùn)能包含多個(gè)POSIX線程)。用戶進(jìn)程可直接通過(guò)內(nèi)核調(diào)用微內(nèi)核功能,并通過(guò)向to發(fā)送信息()需要重視的是,在to內(nèi)執(zhí)行的線程調(diào)用微內(nèi)核的方式與其他進(jìn)的味著有“特殊”或“”接口。系統(tǒng)內(nèi)的所有線程均共享相同一致的內(nèi)核接口,而且所有線會(huì)在調(diào)用微內(nèi)核時(shí)進(jìn)行轉(zhuǎn)換??梢浦膊僮飨到y(tǒng)接口(POSIX)支持VxWorks為多種工具(包括調(diào)度、信號(hào)量、信息隊(duì)列、信號(hào)和計(jì)時(shí)器)提POSIX接口。QNXNeutrino包含所有這些接口,而且還提供了完全符POSIX標(biāo)準(zhǔn)。POSIX與QNXNeutrino都采用相反的方式:數(shù)值越大的優(yōu)先級(jí)越重要。QNXNeutrino256種不同的優(yōu)先級(jí)(VxWorks類似)用于線程(FIFO的策略之允許有偶發(fā)CPU利用需求的應(yīng)用程序線程分配其所需的執(zhí)行預(yù)算。VxWorksQNXNeutrinoPOSIX的功能進(jìn)行了并列對(duì)比。請(qǐng)注意,在VxWorks中,大部分不同的功能都是由獨(dú)立庫(kù)提QNXNeutrino中,大部分POSIX功能都是通過(guò)libc程序庫(kù)內(nèi)的函數(shù)實(shí)現(xiàn)的。VxWorks程序QNXNeutrino程RR,互斥體(POSIX1003.1線程256,High=Low256,High=HighPOSIX1003.1(系統(tǒng)接口POSIX1003.1(系統(tǒng)接口擴(kuò)展POSIX1003.1b(實(shí)時(shí)擴(kuò)展POSIX1003.1c(線程POSIX1003.1b(附加實(shí)時(shí)擴(kuò)展POSIXPOSIXPOSIX1003.1f(透明文件POSIX1003.1j(高級(jí)實(shí)時(shí)擴(kuò)展POSIX1003.1-200x(草稿POSIX1003.4-200x(草稿QNXNeutrinoPOSIX1003.1-2001規(guī)范(1003.1-1996規(guī)范修改P1003.1a、1003.1d-、.1g-、.1j-2000)的要求,以及現(xiàn)行POSIX1003.13文件(PSE51、5253)定義的功能要求。QNXNeutrino已獲得PSE52實(shí)時(shí)控制器1003.13-2003系統(tǒng)的符合性認(rèn)證。內(nèi)存可如前所述,VxWorks中的內(nèi)存空間對(duì)所有任務(wù)都是開(kāi)放的,內(nèi)存時(shí)可它只會(huì)在提供指令和數(shù)據(jù)緩存功能時(shí)啟動(dòng)。可使用標(biāo)準(zhǔn)的庫(kù)分配例程(malloc()、calloc等),或使用滿足指定內(nèi)存池(在啟動(dòng)順序的內(nèi)存初始化內(nèi)存的設(shè)備提供緩存保護(hù)內(nèi)存。盡管有時(shí)需要將“虛擬”內(nèi)存轉(zhuǎn)換成“物理內(nèi)存”(cacheDrvVirtToPhys()/cacheDrvPhysToVirt函數(shù)),但根據(jù)圖6:VxWorks中的內(nèi)存分配。MemoryMemoryMemPartAlloc(SystemWasblockof sufficientsizefound(firstSplittheblockFreeListtotaskReturnunusedportiontotheglobalfreelistQNXQNXNeutrino(MMU)實(shí)現(xiàn)的功能全面的虛擬內(nèi)存來(lái)運(yùn)行。處理器內(nèi)的硬件會(huì)利用在系統(tǒng)內(nèi)存中定義虛擬地址(如在應(yīng)用程序內(nèi)使用的內(nèi)存地址)CPU發(fā)出地址的映射的一組頁(yè)表,以物理內(nèi)存。程執(zhí)行時(shí),操作系統(tǒng)管理的頁(yè)表會(huì)控制線程使用的內(nèi)存地QNXNeutrino提供了全面的內(nèi)存保護(hù)模式,它能將系統(tǒng)映像內(nèi)的所有代碼表。在該模式下,會(huì)為每個(gè)進(jìn)程分配由CPU的內(nèi)存管理單元控制的虛任務(wù)進(jìn)行的內(nèi)存分配是使用POSIX標(biāo)準(zhǔn)mmap()函數(shù)調(diào)用實(shí)現(xiàn)的,QNX內(nèi)存碎片并對(duì)性能進(jìn)行優(yōu)化。由于進(jìn)程管理器是以4KB為單位管理內(nèi)存QNXNeutrino(first-fit分配策略的。每個(gè)進(jìn)同進(jìn)的線程堆。分配器的運(yùn)行原理如下。內(nèi)存(使malloc()、calloc()realloc()調(diào)用)時(shí),系統(tǒng)會(huì)搜索空閑列表,尋找注意:QNXNeutrino中的空閑列表是使向鏈表的。因此,可同圖7:QNXNeutrino中的內(nèi)存管理。 QNXNeutrino系統(tǒng)架構(gòu)指南提供了有關(guān)操作系統(tǒng)如何管理內(nèi)存的詳細(xì)任務(wù)間/進(jìn)程間通信VxWorks提供了幾種不同的任務(wù)間通信機(jī)制??墒褂玫牟煌椒òǎ盒盘?hào)量是VxWorks中的任務(wù)間進(jìn)行同步的主要。它提供了三種不同當(dāng)建立信號(hào)量時(shí),程序還能為等待信號(hào)量(即將可用)s對(duì)X。信息隊(duì)列與管道Vrs了間。留量可變的信息,每種信息都有不同的長(zhǎng)度。應(yīng)用程序信息會(huì)使用sgend函(信息在發(fā)送時(shí)會(huì)被存放在隊(duì)列開(kāi)頭)VxWorks還提供了具有32種優(yōu)先級(jí)的POSIX信息隊(duì)列(mq_*)。任務(wù)等待來(lái)自任何一組文件描述符(輸入/輸出設(shè)備)的數(shù)據(jù)。QNXNeutrino提供了符合POSIX1003.1接口規(guī)范要求的管道接口實(shí)現(xiàn)。VxWorks信息隊(duì)列VxWorks中的任務(wù)之間實(shí)現(xiàn)同步和進(jìn)行#include<stdio.h>#include<sysLib.h>#include<string.h>#defineMAX_NUM_MSG#defineMAX_MSG_LEN100#defineNUM_MSGS2*MAX_NUM_MSG void{staticcharbuf[MAX_MSG_LEN];inti;for(i=0;i<NUM_MSGS;i++)/*Yieldtoallowothertaskstorun.OtherwiseFIFOmeansthatthistaskwillrununtilblocked.*//*Writeandsendamessage.*/sprintf(buf,"Send1%d",i);ifMSG_PRI_NORMAL)==ERROR)printf("Send1msgQSendfailed!\n");}if(i==3)/*Sendanurgentmessage.*/sprintf(buf,"Send1URG%d",i);if(msgQSend(msgQId,MSG_PRI_URGENT)==ERROR)printf("Send1msgQSendfailed!\n");}}}}void{staticcharbuf[MAX_MSG_LEN];inti;for(i=0;i<NUM_MSGS;i++)sprintf(buf,"Send2%d",i);if(msgQSend(msgQId,MSG_PRI_NORMAL)==ERROR)printf("Send2msgQSendfailed!\n");}if(i==5)sprintf(buf,"Send2URG%d",i);if(msgQSend(msgQId,MSG_PRI_URGENT)==ERROR)printf("Send2msgQSendfailed!\n");}}}}void{charbuf[MAX_MSG_LEN];inti;for(i=0;i<NUM_MSGS;i++)ifWAIT_FOREVER)==ERROR)printf("Rxtask1msgQReceive}elseprintf("Task1received%s\n",}}}void{charbuf[MAX_MSG_LEN];inti;for(i=0;i<10;{ifWAIT_FOREVER)==ERROR)printf("Rxtask2msgQReceive}elseprintf("Task2received%s\n",}}}void{int /*Priorityislessthaninit’spriority,soinitcanruntocompletion.*/if((msgQId=MSG_Q_FIFO))==NULL){}if(0,0,0,0,0,0,0,0,0,0)==ERROR){printf("taskSpawnTx1}if0,0,0,0,0,0,0,0,0,0)==ERROR){printf("taskSpawnTx2}if0,0,0,0,0,0,0,0,0,0)==ERROR){printf("taskSpawnRx1}if0,0,0,0,0,0,0,0,0,0)==ERROR){printf("taskSpawnRx2}}QNXNeutrino版本(信息隊(duì)列QNXNeutrino中實(shí)現(xiàn)同樣的功能,我們有兩種不同的選擇方案。我們可以將VxWorks中的原始任務(wù)映射成相同進(jìn)的線程,或使其成為不同的#include<stdio.h>#include<stdlib.h>#include#include<sys/QNXNeutrino.h>#include<sys/types.h>#include<pthread.h>#include<mqueue.h>#include#defineMAX_NUM_MSG#defineMAX_MSG_LEN100#defineNUM_MSGS2*MAX_NUM_MSG#defineMSG_PRI_NORMAL#defineMSG_PRI_URGENT20#defineMQ_NAME"simple_queue"mqd_tmsgQId;void*sendTask1(void{staticcharbuf[MAX_MSG_LEN];inti;for(i=0;i<NUM_MSGS;i++)/*Yieldtoallowothertaskstorun.OtherwiseFIFOmeansthatthistaskwillrununtilblocked.*//*Writeandsendamessage.*/sprintf(buf,"Send1%d",i);if(mq_send(msgQId,buf,strlen(buf)+1,MSG_PRI_NORMAL)<{printf("Send1msgQSendfailed!\n");}if(i==3)/*Sendanurgentmessage.*/sprintf(buf,"Send1URG%d",i);if(mq_send(msgQId,buf,strlen(buf)+1,MSG_PRI_URGENT)<{printf("Send1msgQSendfailed!\n");}}}}void*sendTask2(void{staticcharbuf[MAX_MSG_LEN];inti;for(i=0;i<NUM_MSGS;i++)sprintf(buf,"Send2%d",i);if(mq_send(msgQId,buf,strlen(buf)+1,MSG_PRI_NORMAL)<{printf("Send2msgQSendfailed!\n");}if(i==5)sprintf(buf,"Send2URG%d",if(mq_send(msgQId,buf,strlen(buf)+1,MSG_PRI_URGENT)<{printf("Send2msgQSendfailed!\n");}}}}void*receiveTask1(void{charbuf[MAX_MSG_LEN];inti;unsignedfor(i=0;i<NUM_MSGS;i++)if(mq_receive(msgQId,buf,MAX_MSG_LEN,&prio)<{printf("Rxtask1msgQReceive}elseprintf("Task1received%s\n",}}}void*receiveTask2(void{charbuf[MAX_MSG_LEN];inti;unsignedfor(i=0;i<10;i++)if(mq_receive(msgQId,buf,MAX_MSG_LEN,&prio)<0{printf("Rxtask2msgQReceive}elseprintf("Task2received%s\n",}}}void{intpri;pthread_attr_tattrib;structsched_paramparam;structsched_paramour_param;inti;structmq_attrpthread_attr_setinheritsched(&attrib,PTHREAD_EXPLICIT_SCHED);pthread_attr_setschedpolicy(&attrib,SCHED_FIFO);sched_getparam(0,&our_param);param.sched_priority=our_param.sched_priority-1;pthread_attr_setschedparam(&attrib,¶m);memset(&mqattr,0,sizeof(mqattr));mqattr.mq_maxmsg=MAX_NUM_MSG;mqattr.mq_msgsize=MAX_MSG_LEN;if((msgQId=mq_open(MQ_NAME,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR,&mqattr))<0){}if(pthread_create(&tid[0],&attrib,sendTask1,NULL)<{printf("taskSpawnTx1}if(pthread_create(&tid[1],&attrib,sendTask2,NULL)<{printf("taskSpawnTx2}if(pthread_create(&tid[2],&attrib,receiveTask1,NULL)<{printf("taskSpawnRx1}if(pthread_create(&tid[3],&attrib,receiveTask2,NULL)<{printf("taskSpawnRx2}for(i=0;i<3;i++)}intmain(intargc,char{}使用單獨(dú)進(jìn)程的QNXNeutrino版#include<stdio.h>#include<stdlib.h>#include#include<sys/QNXNeutrino.h>#include<sys/types.h>#include<pthread.h>#include<mqueue.h>#include<sched.h>#include<unistd.h>#include<spawn.h>#include<fcntl.h>#include#defineMAX_NUM_MSG#defineMAX_MSG_LEN100#defineNUM_MSGS2*MAX_NUM_MSG#defineMSG_PRI_NORMAL#defineMSG_PRI_URGENT20#defineMQ_NAME"simple_queue"mqd_tmsgQId;void{staticcharbuf[MAX_MSG_LEN];inti;for(i=0;i<NUM_MSGS;i++)/*Yieldtoallowothertaskstorun.OtherwiseFIFOmeansthatthistaskwillrununtilblocked.*//*Writeandsendamessage.*/sprintf(buf,"Send1%d",i);if(mq_send(msgQId,buf,strlen(buf)+1,MSG_PRI_NORMAL)<{printf("Send1msgQSendfailed!\n");}if(i==3)/*Sendanurgentmessage.*/sprintf(buf,"Send1URG%d",i);if(mq_send(msgQId,buf,strlen(buf)+1,MSG_PRI_URGENT)<0)printf("Send1msgQSendfailed!\n");}}}}void{staticcharbuf[MAX_MSG_LEN];inti;for(i=0;i<NUM_MSGS;i++)sprintf(buf,"Send2%d",i);if(mq_send(msgQId,buf,strlen(buf)+1,MSG_PRI_NORMAL)<{printf("Send2msgQSendfailed!\n");}if(i==5)sprintf(buf,"Send2URG%d",if(mq_send(msgQId,buf,strlen(buf)+1,MSG_PRI_URGENT)<{printf("Send2msgQSendfailed!\n");}}}}void{charbuf[MAX_MSG_LEN];inti;unsignedfor(i=0;i<NUM_MSGS;i++)if(mq_receive(msgQId,buf,MAX_MSG_LEN,&prio)<{printf("Rxtask1msgQReceive}elseprintf("Task1received%s\n",}}}void{charbuf[MAX_MSG_LEN];inti;unsignedfor(i=0;i<10;i++)if(mq_receive(msgQId,buf,MAX_MSG_LEN,&prio)<0)printf("Rxtask2msgQReceive}elseprintf("Task2received%s\n",}}}voidmsgQ_init(int{intif(first)structmq_attrmemset(&mqattr,0,sizeof(mqattr));mqattr.mq_maxmsg=MAX_NUM_MSG;mqattr.mq_msgsize=MAX_MSG_LEN;if((msgQId=mq_open(MQ_NAME,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR,&mqattr))<0){}}elseif((msgQId=mq_open(MQ_NAME,O_RDWR))<{printf("msgQOpenfailed!\n");}}}intmain(intargc,char{if(argc=={pid_tpid[3];charbuf[10];inti;for(i=0;i<3;{sprintf(buf,"%d",i+2);argv[1]=buf;argv[2]=pid[i]=spawnv(P_NOWAIT,argv[0],}for(i=0;i<3;i++)waitpid(pid[i],NULL,WEXITED);}elseintnum=atoi(argv[1]);switch(num){case2:case3:case4:}}}共享內(nèi)存QNXNetro準(zhǔn)IXhm_*調(diào)用提供對(duì)共享內(nèi)存的,樣能使不同進(jìn)程(不共享同一地址空間)中的線程互相通信。與在xor中(可使用在不同上下文中運(yùn)行的直接代碼指針?lè)〒?jù)的同。shm_openopen相同的參數(shù),然后它會(huì)將文件描述符退回對(duì)象。與ftruncateshm_ctl()函數(shù)。請(qǐng)注意,ftruncate()與設(shè)置文件大小的函mmap()將對(duì)象(或其一部分)映射到進(jìn)程的地址空間內(nèi)。函數(shù)mmap()是QNXNeutrino中內(nèi)mmap()是按下列方式定void*mmap(void*where_i_want_it,size_tintmemory_protections,intmap_flags,intfd,off_toffset_within_shared_memory);長(zhǎng)度(位于共享內(nèi)存對(duì)象中oft_wthshe_eoy)fd有關(guān)。”圖8:QNXNeutrino中的函數(shù)mmap()len,prot,flags,len,prot,flags,fd,offset
mmapMAP_ANON標(biāo)志連用時(shí),用戶能輕松實(shí)現(xiàn)專用的頁(yè)級(jí)分配器/mprotect更改對(duì)內(nèi)存映射區(qū)的保護(hù)。VxWorks共享內(nèi)存 #include<stdio.h>#include<sysLib.h>#include<string.h>struct{char}void{intfor(i=0;i<10;i++)/*Sharedareaismutex-protected.*/semTake(mSem,WAIT_FOREVER);/*Delayfor2seconds*//*Printandthenchangethesharedmemory.*/sprintf(shareThis.writeArea,"Thisisshared1/*Releasethemutex.*/}}void{int/*Delayforonesecondtolettheshared1taskgrabthemutex.*/for(i=0;i<10;i++)/*Sharedareaismutex-protected.*/semTake(mSem,WAIT_FOREVER);printf("Shared2reads%s",shareThis.writeArea);}}void{int/*Prioritylessthaninit’spriority,sotasksstartandwaitforinittocomplete.*/mSem=semMCreate(SEM_Q_PRIORITY);if(mSem==NULL){}if(0,0,0,0,0,0,0,0,0,0)==ERROR){printf("taskSpawn1}if0,0,0,0,0,0,0,0,0,0)==ERROR){printf("taskSpawn2}}QNXNeutrino版本(共享內(nèi)存程實(shí)例中,同一進(jìn)的線程會(huì)自動(dòng)共享內(nèi)存。為防止對(duì)共享區(qū)的同時(shí)訪#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/QNX#include<unistd.h>struct{char}void*shared1(void{intfor(i=0;i<10;i++)/*Sharedareaismutex-protected.*//*Printandthenchangethesharedmemory.*/sprintf(shareThis.writeArea,"Thread1Writes:Thisisshared1/*Releasemutex.*//*Delayfor2seconds*/}}void*shared2(void{int/*Delayforonesecondtolettheshared1taskgrabthemutex.*/for(i=0;i<10;i++)/*Sharedareaismutex-protected.*/printf("Thread2reads:%s",shareThis.writeArea);/*Delayfor1seconds*/}}void{intpri;pthread_attr_tattrib;structsched_paramparam;structsched_paramour_param;inti;pthread_attr_setinheritsched(&attrib,PTHREAD_EXPLICIT_SCHED);pthread_attr_setschedpolicy(&attrib,SCHED_RR);sched_getparam(0,&our_param);param.sched_priority=our_param.sched_priority-1;pthread_attr_setschedparam(&attrib,¶m);mmutex=malloc(sizeof(pthread_mutex_t));pthread_mutex_init(mmutex,NULL);if(pthread_create(&tid[0],&attrib,shared1,NULL)<{printf("taskSpawn1}if(pthread_create(&tid[1],&attrib,shared2,NULL)<{printf("taskSpawn2}for(i=0;i<2;{pthread_join(tid[i],}}intmain(intargc,char{}使用單獨(dú)進(jìn)程的QNXNeutrino版適當(dāng)?shù)墓蚕韮?nèi)存區(qū),因此兩個(gè)進(jìn)能該內(nèi)存區(qū)。定義一個(gè)互斥體并#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/QNXNeutrino.h>#include<pthread.h>#include<unistd.h>#include<spawn.h>#include<fcntl.h>#include<sys/wait.h>#include#defineroundup(x,y)((((x)+((y)-1))/(y))*(y))#defineSHAREDNAME"/shared_test"struct{pthread_mutex_tmmutex;charwriteArea[128];structsharedarea*sharedThis;voidshared1(void){intfor(i=0;i<10;i++)/*Sharedareaismutex-protected.*//*Printthesharedmemorybeforechangingit.*/printf("%s",sharedThis->writeArea);"Proc1Writes:Thisisshared1/*Releasethemutex.*//*Delayfor2seconds*/}}void{int/*Delayforonesecondtolettheshared1taskgrabthemutex.*/for(i=0;i<10;i++)/*Sharedareaismutex-protected.*/printf("Proc2reads:%s",sharedThis->writeArea);/*Delayfor1seconds*/}}voidshare_init(int{intsize;intfd;if(first){fd=shm_open(SHAREDNAME,O_CREAT|O_RDWR,}elsefd=shm_open(SHAREDNAME,O_RDWR,}size=size=roundup(size,4096);//roundtopageaddr=(void*)mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,sharedThis=(structsharedarea*)addr;}intmain(intargc,char{pid_tpid;if(argc=={shm_unlink(SHAREDNAME);pthread_mutex_init(&(sharedThis->mmutex),&attr);strcpy(sharedThis->writeArea,"Initialstartingstring\n");argv[1]="1";argv[2]=pid=spawnv(P_NOWAIT,argv[0],argv);waitpid(pid,NULL,WEXITED);}else}}套接字與過(guò)程調(diào)用進(jìn)行的。在建立套接字時(shí),您還要指定協(xié)議(UDPTCP)。TCP套接字為套接字的兩端之間提供了可靠的雙向通信。VxWorksBSD套接字接口實(shí)現(xiàn)代碼兼容。QNXNeutrino提供的套接字接口也是基于BSD模式的。兩種操作系統(tǒng)都提供了過(guò)程調(diào)用(RPC)工具。信適當(dāng)?shù)男盘?hào),就會(huì)調(diào)用這些處理程序。VxWorksPOSIX1003.1信號(hào)BSD信號(hào)接口。QNXNeutrinoPOSIX信號(hào)工具和基于語(yǔ)義的BSD信號(hào)工具。監(jiān)視程序計(jì)時(shí)器監(jiān)視程序計(jì)時(shí)器的函數(shù)是在系統(tǒng)時(shí)鐘的中斷服務(wù)例程(ISR)的上下文中執(zhí)行的。這就限制了在回調(diào)例程中可實(shí)現(xiàn)的功能。用戶還能使用POSIX1003.1b時(shí)鐘和計(jì)時(shí)器接口。QNXNeutrinoPOSIX1003.1b時(shí)鐘和計(jì)時(shí)器接口,從而允許線程將來(lái)在特定時(shí)間內(nèi)自行發(fā)送信號(hào)。QNXNeutrino提供了功能全面的事件發(fā) 監(jiān)視程序計(jì)時(shí)器的#include<stdio.h>#include<sysLib.h>#include<string.h>#include#include<wdLib.h>WDOG_IDwDog;SEM_IDbSem;void{}void{intfor(i=0;i<10;i++)/*Waitforsignalfromwdogtogoahead.*/semTake(bSem,WAIT_FOREVER);printf("Taskreceivedwatchdog/*Fireoffthewatchdogagaininonesecond.*/if(wdStart(wDog,sysClkRateGet(),(FUNCPTR)wDogRoutine,0)=={printf("wdStartfailedin}}}void{bSem=semBCreate(SEM_Q_PRIORITY,SEM_EMPTY);if(bSem==NULL){}wDog=wdCreate();if(wDog==NULL)printf("wdCreatefailed\n");}/*Fireoffthewatchdoginonesecond.*/if(taskSpawn("watchDog",0,0,0,0,0,0,0,0,0,0)==ERROR){printf("watchDogtaskspawn}if(wdStart(wDog,(FUNCPTR)wDogRoutine,0)=={printf("wdStart}}QNXNeutrino版本(監(jiān)視程序計(jì)時(shí)器#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/QNXNeutrino.h>#include<pthread.h>pthread_mutex_twd_mutex=PTHREAD_MUTEX_INITIALIZER;pthread_cond_twd_cond=PTHREAD_COND_INITIALIZER;structsigeventevent;inttimer_chid;structitimerspec#define void*wDogRoutine(void{intstruct_pulsemsg;while(1){rcvid=MsgReceive(timer_chid,&msg,sizeof(msg),NULL);if(rcvid==0){/*wegotapulse*/if(msg.code=={printf("\nwDogfired!\n");}}}}void*watchDogTask(void{intfor(i=0;i<10;i++)/*Waitforasignalfromwdogtogoahead.*/pthread_cond_wait(&wd_cond,&wd_mutex);printf("Taskreceivedwatchdogsem:%d.\n",i);itime.it_value.tv_sec=1;itime.it_value.tv_nsec=0;timer_settime(timer_id,0,&itime,NULL);}}void{pthread_ttid[2];pthread_attr_tattrib;structsched_paramparam;structsched_paramour_param;inti;setbuf(stdout,NULL);timer_chid=ChannelCreate(0);event.sigev_notify=SIGEV_PULSE;event.sigev_coid=ConnectAttach(0,0,timer_chid,event.sigev_priority=getprio(0);event.sigev_code=TIMER_PULSE_CODE;timer_create(CLOCK_REALTIME,&event,&timer_id);itime.it_value.tv_sec=itime.it_value.tv_nsec=0;timer_settime(timer_id,0,&itime,NULL);pthread_attr_setinheritsched(&attrib,PTHREAD_EXPLICIT_SCHED);pthread_attr_setschedpolicy(&attrib,SCHED_RR);sched_getparam(0,&our_param);param.sched_priority=our_param.sched_priority;pthread_attr_setschedparam(&attrib,¶m);if(pthread_create(&tid[0],&attrib,wDogRoutine,NULL)<{printf("watchDogroutinespawn}if(pthread_create(&tid[1],&attrib,watchDogTask,NULL)<{printf("watchDogtaskspawn}}intmain(intargc,char{}異常處CPU架構(gòu)有關(guān)的庫(kù)調(diào)用對(duì)異常中斷向量表進(jìn)行初始化。內(nèi)核啟動(dòng)后,excInitexk()、可使用函數(shù)excHookAdd()增加用戶異常代碼,以增加默認(rèn)動(dòng)作。該代碼是在正還可使用信號(hào)庫(kù)sigLib(一種與Unix兼容的接口)處理硬件異常,在這種情況下,使用了sigvec()對(duì)單獨(dú)的異常向量進(jìn)行初始化。這種信號(hào)庫(kù)同時(shí)提供了BSD4.3POSIX接口,但是這兩種應(yīng)用程序接口(API)不能混插。信號(hào)確QNX針對(duì)異常處理和異?;謴?fù),QNXNeutrino提供了多種不同的機(jī)制。例如,然后在現(xiàn)場(chǎng)的所有其他設(shè)備遇到同樣的前,為它們準(zhǔn)備可的修復(fù)(SPOF)。此時(shí)真正需要的是一系統(tǒng)進(jìn)程間完全支持內(nèi)存管理單元(MMU)的內(nèi)存保護(hù)功能可輕松并保護(hù)單獨(dú)進(jìn)程。QNXNeutrino的進(jìn)程模型還具備動(dòng)態(tài)創(chuàng)建和析構(gòu)功能,這對(duì)結(jié)植工作的難度取決于VxWorks應(yīng)用程序中使用了何種異常庫(kù)。在QNXNeutrino中,可通過(guò)重啟進(jìn)程為顯示應(yīng)用程序出現(xiàn)嚴(yán)重故障VxWorks應(yīng)用程序(常常需要進(jìn)行系統(tǒng)完全重設(shè))通常無(wú)1節(jié)中所述,代碼移植的簡(jiǎn)易性與要移植的代碼和硬件的關(guān)聯(lián)程度密通常,進(jìn)行移植時(shí)首先要在硬件平臺(tái)上建立操作系統(tǒng)(本質(zhì)上即板級(jí)支持啟動(dòng)代VxWorks啟VxWorks針對(duì)嵌入式應(yīng)用的基本啟動(dòng)順序是先執(zhí)行重設(shè)的匯編代碼,這可通過(guò)_romInit代碼或BIOS完成,具體取決于使用的硬件。該代碼可執(zhí)行建立CPU和內(nèi)存所需的最基本功能,以便將VxWorks應(yīng)用程序加載到隨(RAM圖9:VxWorks的啟動(dòng)順序。 ImageismovedintoRAM
機(jī)器(RAM)中,而且通常還要進(jìn)行解壓縮和。必要時(shí),可在此時(shí)當(dāng)映像進(jìn)入隨機(jī)器(RAM)后,會(huì)從只讀器(ROM)跳轉(zhuǎn)執(zhí)行隨機(jī)存(RAM)內(nèi)建立處理器和堆棧幀的少量程序集(_sysInit),以便啟動(dòng)服務(wù)等級(jí)(COS)初始化例程usrInit()。usrInit(會(huì)處理其余必要的設(shè)置,以對(duì)內(nèi)核進(jìn)行初始化(包括初始化異常向量、緩存庫(kù)、中斷和任何附加的硬件初始化)kernelInit()呼叫建立內(nèi)核。內(nèi)核初始化會(huì)導(dǎo)致執(zhí)行usrRoot()。文件系統(tǒng)和其他支持的硬件,最后它會(huì)啟動(dòng)userAppInit(),其中包含用戶提#define進(jìn)行配置的,以在建立階段確定應(yīng)包含的prjConfig.c內(nèi)QNXNeutrino啟QNXNeutrino(to)to程序(IPL)完成的。IPL的初始任務(wù)是對(duì)硬件進(jìn)行最低限度的配置以建立一種運(yùn)行環(huán)境,便于啟動(dòng)程序以及隨后的QNXNeutrino微內(nèi)核運(yùn)行。具體說(shuō)來(lái),(包括配置選擇與/或PCI控制器)、配置時(shí)鐘,以及建立能使IPL庫(kù) 圖10:QNXNeutrino的啟動(dòng)順序。ROM OSboot
Boot軟件執(zhí)行的第二步是配置處理器和硬件、檢測(cè)系統(tǒng)資源并啟動(dòng)操作系統(tǒng)。啟動(dòng)IL在進(jìn)行必要的最低限度的配置,以使系統(tǒng)進(jìn)入啟動(dòng)程序可以運(yùn)行的狀態(tài)時(shí),啟動(dòng)程序L檢測(cè)到各種資源,它會(huì)就該信息與啟動(dòng)程序進(jìn)行通信(這樣它就不必重新檢測(cè)相同的資源)。為盡量確保QNXNuro些代碼段必須能清除中斷源。注意,啟動(dòng)程序不會(huì)配置串行端口的波特率。查看的一段內(nèi)存)后,啟動(dòng)代碼會(huì)負(fù)責(zé)將控制權(quán)轉(zhuǎn)至QNXNeutrino內(nèi)核與進(jìn)程管理器(to),由其完成最后的載入步驟。要建立操作系統(tǒng),需使用一個(gè)單獨(dú)的映像文件。該映像至少應(yīng)包含操作系但它們通常在單獨(dú)的文件系統(tǒng)中(如閃存或磁盤),并由映像文件中包含的啟動(dòng)。有參考駐留文件(應(yīng)用程序映像、程序庫(kù)、操作系統(tǒng)映像、啟動(dòng)等)所需的mkifs(建立映像文件系統(tǒng))的程序會(huì)使用命令結(jié)QNXNeutrinoVxWorksromStart/usrInit代碼QNXNeutrinoVxWorksusrRoot類似的無(wú)需配置QNXNeutrino的內(nèi)核。內(nèi)核是作為生成文件可容納的獨(dú)立QNXNeutrino中的操作系統(tǒng)與應(yīng)用程序能以不同格式在不同區(qū)VxWorks不同,VxWorks中的應(yīng)用程序和操作系統(tǒng)必須硬件輸入/輸出設(shè)備系統(tǒng)中,這樣就能使用一致的應(yīng)用程序接口(API)硬件。在低層級(jí),可使用標(biāo)準(zhǔn)輸入/輸出命令(開(kāi)啟、、寫入、關(guān)閉等)設(shè)備。中斷服務(wù)例程進(jìn)行處理的。該例程庫(kù)提供的例程可用于鎖定/、啟用/中斷、為CPU產(chǎn)品系列。中斷服務(wù)功說(shuō)DRV_CTRL_SdrvCtrl;SEM_IDpacketSem;LOCALvoidmotFccISR(DRV_CTRL_S{structfcc_regs*fcc_regs;unsignedint *pQ=(PQ2IMM*)vxImmrGet();fcc_regs=&pQ->fcc_regs[pDrvCtrl-> um-1];/*Savetheeventregister.*/events=fcc_regs->fcc_fcce;/*Cleartheeventthat’scausingtheinterrupt.*/fcc_regs->fcc_fcce=0xffff0000;/*Otherprocessing/*Signaltotask.*/}DRV_CTRL_SdrvCtrl;...packetSem=semBCreate(SEM_Q_PRIORITY,SEM_EMPTY);um=1;(VOIDFUNCPTR)motFccISR,...}{while(1)/*Processpacket...}}在處理程序內(nèi)部,可(QIMM結(jié)構(gòu)與傳遞數(shù)據(jù)結(jié)構(gòu)內(nèi)包含的信息直接內(nèi)內(nèi)存射,確要的當(dāng)存器清中。還可進(jìn)行其他處理以應(yīng)對(duì)中斷問(wèn)題。當(dāng)完成中斷處理后,會(huì)指定一個(gè)信號(hào)量以向任務(wù)通知出現(xiàn)的中斷。semTake、malloc、printf、QNX望中斷服務(wù)例程與特定的中斷源產(chǎn)生關(guān)聯(lián)。線程會(huì)使用InterruptAttach()或InterruptAttachEvent()函數(shù)調(diào)用指定它希望哪個(gè)中斷源與哪個(gè)中斷服務(wù)例程產(chǎn)生關(guān)聯(lián)。當(dāng)軟件希望解除中斷服務(wù)例程與中斷源的關(guān)聯(lián)時(shí),它可以調(diào)用//ExampletoshowattachinganISR#defineIRQ33externconstsigevent*handle_int3(void*,//ObtainI/OPrivilegesThreadCtl(_NTO_TCTL_IO,0);//AssociateaninterrupthandlerwithIRQid=InterruptAttach(IRQ3,handle_int3,NULL,0,//Performsome//Done;detachtheinterruptsource.試圖依附中斷的線程必須具有輸入/輸出——即有關(guān)控制輸入/輸出端口和影響處理器允許中斷標(biāo)志的。只有根賬戶能獲得輸入/輸出,handle_int3()是中斷服務(wù)例程。中斷服務(wù)例程通常負(fù)責(zé)特性產(chǎn)生影響。str*mem*()(strcpymemcpy())在中斷服務(wù)例程中非常有用,所strdup()分配內(nèi)存并使用互斥體。QNXNeutrino庫(kù)參考可識(shí)別您能從中斷服務(wù)例程調(diào)用的功能。InterruptDisableInterruptEnable()呼叫。由于這些呼叫能有效關(guān)閉中斷,因此線程應(yīng)該能使數(shù)據(jù)操作運(yùn)行保持(如非全部)真正的線程級(jí)“維修”操作。您可以決定一些需要在中斷服務(wù)例程中實(shí)現(xiàn)的時(shí)序要求嚴(yán)格的功能,然后稍后調(diào)度線程去做“實(shí)際”的工作,或者,您也可以決定無(wú)需在中斷服務(wù)例程中實(shí)現(xiàn)任何功能;僅需調(diào)tA()Itettchet()(structsigevent)之間的明顯區(qū)別。中斷服務(wù)例程從硬件中一些寄存器后,或者完成進(jìn)行維修所需的任何conststructsigevent結(jié)構(gòu)即可;內(nèi)線程,它僅需返回一個(gè)空(NULL)值即可。和迅速的方法是專門安排一個(gè)線程進(jìn)行中斷處理。線程(通過(guò)保持阻塞,直到中斷服務(wù)例程返回SIGEV_INTR事件。#include<errno.h>#include<fcntl.h>#include<stdarg.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<sys/iofunc.h>#include<sys/resmgr.h>#include<sys/stat.h>#include<sys/syspage.h>#define void*interrupt_thread(void*data);structsigeventintr_event; #defineNUM_DATA_BYTES1unsignedintinterrupt_num=intmain(intargc,char{intwhile((i=getopt(argc,argv,"i:"))!=-{switch{caseinterrupt_num=atoi(optarg);printf("Unknownarg\n");return(EXIT_FAILURE);}}fprintf(stderr,"UsingInterrupt%u\n",interrupt_num);pthread_create(0,NULL,interrupt_thread,//Nowourmain()threadjustwaitstillwegetkilledreturn}conststructsigevent*interrupt_handler(void*event,int{structsigevent*return_event=(structsigevent*) mentthefollowinglinestopulse//NUM_DATA_BYTES'thinterrupt.Wearepretendingwe//onebyteofdataperinterruptandonlywakeup//threadafterNUM_DATA_BYTES//Whydotheworkofgettingthebytesofdatafrom//thethread?Becausewearepretendingthatifwe//doitathandlertime,thenwe'llmissthedata(e.g.//bufferingonthe//staticunsignedinterrupt_counter=////if(interrupt_counter==NUM_DATA_BYTES) interrupt_counter=0;returnreturn_event;//}else return//}void*interrupt_thread(void{unsignedcounter=0;structsched_paramparam;param.sched_priority=if(sched_setscheduler(0,SCHED_FIFO,¶m)==-1{fprintf(stderr,"Unabletochangepriority:%s\n",exit(EXIT_FAILURE}//WeneedI/OprivilegessowecancallInterruptAttach()if(ThreadCtl(_NTO_TCTL_IO,0)==-1){fprintf(stderr,"UnabletogetI/Oprivileges:%s\n",exit(EXIT_FAILURE}//SetupasigeventthatwillwakeupInterruptWait()SIGEV_INTR_INIT(&intr_event);if(interrupt_num==0)//Setinterrupt_numtothetimerinterrupt.On//thisis0.Wedothisjusttoshowhowtopull//fromtheinterrupt_num=SYSPAGE_ENTRY(qtime)-}intr_id=InterruptAttach(interrupt_num,interrupt_handler,&intr_event,sizeof(intr_event),_NTO_INTR_FLAGS_TRK_MSK);if(intr_id==-1)fprintf(stderr,"Unabletoattachtoirq%u:%s\n",interrupt_num,strerror(errno));exit(EXIT_FAILURE}for(;;)if(InterruptWait(NULL,NULL)==-1{fprintf(stderr,"\nInterruptWaitinterrupted:%s\n",}else//Theinterruptwentoff,andtheinterrupt//wascalled,andtheinterrupthandlerthen//usupfromInterruptWait()byreturningwith//SIGEV_INTRfprintf(stderr,"%u",counter);}}}正確設(shè)置QNXNeutrino中斷服務(wù)例程中的硬件,然后才能使用程中能進(jìn)行的函數(shù)調(diào)用的類型。QNXNeutrino進(jìn)一步限制了在中斷相對(duì)而言,將可清除硬件中斷根源并執(zhí)行semGive(啟動(dòng)一個(gè)執(zhí)行剩Neutrino中并不。輸入/接口(API),這就為硬件提供了一致的接口(如圖11所示)。圖11:VxWorks的輸入/輸出系統(tǒng)。EnhancedI/O(e.g.buffered,BasicI/OOSinfrastructure(e.g.filesystems,Device輸入/輸出函數(shù)說(shuō)操作系統(tǒng)庫(kù)中還包括更高級(jí)的標(biāo)準(zhǔn)功能(如套接字調(diào)用、printf、scanf等)。合”中分配/VxWorks5.4255個(gè)文件描述文件描述符可在open()或creat()調(diào)用過(guò)程中分配,并通過(guò)close()解除分配,而0分配給標(biāo)準(zhǔn)輸入、1分配給標(biāo)準(zhǔn)輸出、2塊設(shè)備(如磁盤驅(qū)動(dòng)器VxWorks中的文件系統(tǒng)位于塊設(shè)備驅(qū)動(dòng)程序的頂部。塊設(shè)備驅(qū)動(dòng)程序可充文件系統(tǒng)說(shuō)ISO9660CD-ROM可通過(guò)您熟悉的stdio庫(kù)調(diào)用(建立、打
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 生態(tài)環(huán)境部衛(wèi)星環(huán)境應(yīng)用中心招聘筆試真題2024
- 2024年中國(guó)儲(chǔ)備糧管理集團(tuán)有限公司廣西分公司招聘考試真題
- 黑龍江公安警官職業(yè)學(xué)院《結(jié)構(gòu)力學(xué)》2025 學(xué)年第二學(xué)期期末試卷
- 2025寧夏中衛(wèi)市選聘行政執(zhí)法監(jiān)督員20人參考考試試題及答案解析
- 2025年甘肅省臨夏州康樂(lè)縣融媒體中心招聘編輯記者、播音員筆試重點(diǎn)題庫(kù)及答案解析
- 2025年數(shù)字政府建設(shè)報(bào)告
- 2025年上海市復(fù)旦大學(xué)智能醫(yī)學(xué)研究院招聘周欣課題組行政助理崗位備考題庫(kù)及完整答案詳解一套
- c 課程設(shè)計(jì)的報(bào)告
- 2025江蘇蘇州大學(xué)科研助理崗位招聘10人考試核心試題及答案解析
- 2025年公安部第一研究所公開(kāi)招聘預(yù)報(bào)名公安部第一研究所備考題庫(kù)及答案詳解1套
- 《城市防疫專項(xiàng)規(guī)劃編制導(dǎo)則》
- 數(shù)字與圖像處理-終結(jié)性考核-國(guó)開(kāi)(SC)-參考資料
- 肝硬化并糖尿病護(hù)理查房
- 初中七年級(jí)主題班會(huì):成為自己的主人(課件)
- 鄭伯克段于鄢-2
- TCSUS-智能水表技術(shù)標(biāo)準(zhǔn)
- 利用EXCEL畫風(fēng)機(jī)特性曲線-模版
- 人體工效評(píng)估程序
- 西南大學(xué)PPT 04 實(shí)用版答辯模板
- 管理百年智慧樹(shù)知到答案章節(jié)測(cè)試2023年
- 國(guó)家開(kāi)放大學(xué)《刑法學(xué)(1)》形成性考核作業(yè)1-4參考答案
評(píng)論
0/150
提交評(píng)論