wince5.0課件及實驗指導(dǎo)遠(yuǎn)見_第1頁
wince5.0課件及實驗指導(dǎo)遠(yuǎn)見_第2頁
wince5.0課件及實驗指導(dǎo)遠(yuǎn)見_第3頁
wince5.0課件及實驗指導(dǎo)遠(yuǎn)見_第4頁
wince5.0課件及實驗指導(dǎo)遠(yuǎn)見_第5頁
已閱讀5頁,還剩48頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

Thesuccess'sroad

Windows系統(tǒng)定制與驅(qū)動開發(fā)(3)第一節(jié)設(shè)備驅(qū)動概述1.1設(shè)備驅(qū)動的概念1.2驅(qū)動的分層處理1.3驅(qū)動的加載與分類1.4內(nèi)建驅(qū)動簡介1.5流接口驅(qū)動簡介1.1設(shè)備驅(qū)動的概念驅(qū)動程序是一個軟件模塊,其功能就是對這些設(shè)備,或者對協(xié)議甚至是某些服務(wù)進行管理。

設(shè)備驅(qū)動程序以動態(tài)鏈接庫形式存在。設(shè)備驅(qū)動程序是直接和設(shè)備通信的部分。該設(shè)備既可以是物理設(shè)備,也可以是邏輯設(shè)備。從驅(qū)動程序本身,并不能辨別出這個設(shè)備是一個實際的物理設(shè)備或是一個虛擬的邏輯設(shè)備。文件系統(tǒng)驅(qū)動就是這樣的一個例子。設(shè)備驅(qū)動程序是操作系統(tǒng)內(nèi)核和機器硬件之間的接口,設(shè)備驅(qū)動程序為應(yīng)用程序屏蔽了硬件的細(xì)節(jié)。在應(yīng)用程序看來,硬件設(shè)備只是一個設(shè)備文件,應(yīng)用程序可以像操作普通文件一樣對硬件設(shè)備進行操作。應(yīng)用程序,其他的驅(qū)動程序,或者是WindowsCE的設(shè)備管理器可以使用用戶接口。而驅(qū)動提供什么樣的接口,決定了用戶端使用這個驅(qū)動的方法。1.2驅(qū)動的分層處理

許多基于WindowsCE的設(shè)備驅(qū)動都使用了分層處理的方法。驅(qū)動的上層部分被稱為模板驅(qū)動,即MDD(modeldevicedriver)。而底層被稱為平臺的驅(qū)動,即PDD(platform-dependentdriver)。使用這種方法的優(yōu)點是,當(dāng)你進行驅(qū)動移植時,只需要修改該驅(qū)動的上層或者底層就可以了。MDD層包含的代碼在開發(fā)該類型的所有設(shè)備驅(qū)動時是通用的。MDD層調(diào)用特定的PDD層程序來訪問硬件或和硬件相關(guān)的信息。當(dāng)使用分層驅(qū)動時,開發(fā)驅(qū)動時可以對微軟提供的某些通用MDD層代碼進行復(fù)用,而只需重新開發(fā)針對特定硬件環(huán)境的PDD層代碼。同樣,如果想將某個驅(qū)動程序移植到新的硬件平臺上,只需對PDD層代碼進行移植,而MDD層代碼則無需改動即可直接使用。分層結(jié)構(gòu)不是必須的,某些功能簡單,復(fù)用性不強的驅(qū)動一般采用單層結(jié)構(gòu)。1.3驅(qū)動的加載與分類

不同的驅(qū)動程序,其加載的方式也不同,下表類出了WindowsCE下各種驅(qū)動的加載方式。加載方式驅(qū)動類型

文件系統(tǒng)(FileSys.exe)文件系統(tǒng)驅(qū)動程序設(shè)備管理器(Device.exe)網(wǎng)絡(luò)驅(qū)動,,USB驅(qū)動,以及其他流接口的設(shè)備驅(qū)動圖形窗口消息系統(tǒng)(GWES)顯示、鍵盤、鼠標(biāo)驅(qū)動驅(qū)動的分類從接口形式上對驅(qū)動進行分類,可以分為內(nèi)建設(shè)備驅(qū)動程序和流接口驅(qū)動程序。內(nèi)建設(shè)備驅(qū)動程序用于低級、內(nèi)置設(shè)備,提供一組定制的接口可通過移植、定制微軟提供的驅(qū)動樣例來實現(xiàn)。內(nèi)建驅(qū)動部分典型樣例:觸摸屏驅(qū)動顯示驅(qū)動鼠標(biāo)及鍵盤驅(qū)動打印機驅(qū)動而流接口的驅(qū)動是基本的設(shè)備驅(qū)動類型,它實現(xiàn)一組固定的流接口函數(shù),大部分CE設(shè)備都可使用此模型實現(xiàn)。流接口驅(qū)動部分典型樣例:音頻驅(qū)動、串口驅(qū)動并口驅(qū)動某些USB設(shè)備驅(qū)動為了方便開發(fā),微軟提供了一些示范的驅(qū)動程序源代碼以供參考。這些代碼被分成三部分:依賴于平臺的設(shè)備的驅(qū)動代碼,跟芯片相關(guān)部分的驅(qū)動代碼,通用設(shè)備的驅(qū)動代碼。應(yīng)用這些樣例代碼,開發(fā)者可以根據(jù)自己的需要進行相關(guān)的移植和優(yōu)化,來生成自己的驅(qū)動程序。具體代碼在

%_WINCEROOT%\Public\Common\OAK\Drivers路徑下可以找到。第2節(jié)流接口驅(qū)動分析2.1流接口驅(qū)動介紹2.2流接口驅(qū)動的架構(gòu)2.3流接口驅(qū)動的加載2.1流接口驅(qū)動介紹

流接口驅(qū)動程序的主要任務(wù)是把外設(shè)的使用傳遞給應(yīng)用程序,這是通過把設(shè)備表示為文件系統(tǒng)的一個特殊文件實現(xiàn)。流接口驅(qū)動可以由設(shè)備管理程序(Device.exe)自動加載、管理和卸載,也可以通過API函數(shù)手動加載、管理和卸載。所有流接口驅(qū)動程序使用同一組接口函數(shù)集——流接口函數(shù)。流接口驅(qū)動接口函數(shù):

XXX_Init XXX_Deinit XXX_Open XXX_Close XXX_Read XXX_Write XXX_Seek XXX_IoControl XXX_PowerDown XXX_PowerUp2.2流接口驅(qū)動的架構(gòu)前綴名XXX的意義在流驅(qū)動的DEF文件中輸出流驅(qū)動接口時定義。由用戶寫入注冊表中,用于標(biāo)識設(shè)備名。作為參數(shù)組成傳遞給CreateFile函數(shù)。

應(yīng)用程序API和流接口函數(shù)的對應(yīng)ActivateDeviceEx-XXX_InitDeActivateDeviceEX-XX_DeinitCreateFile-XXX_OpenCloseHandle-XXX_CloseReadFile-XXX_ReadWriteFile-XXX_Write

SetFilePointer-XXX_SeekDeviceIoControl-XXX_IoControlXXX_PowerDown,XXX_PowerUp為電源管理接口,當(dāng)系統(tǒng)電源狀態(tài)發(fā)生改變時自動調(diào)用。2.3流接口驅(qū)動的加載

當(dāng)系統(tǒng)啟動時時,設(shè)備管理(Device.exe)會自動調(diào)用ActivateDevice,然后讀出相應(yīng)的注冊表項,根據(jù)相應(yīng)的值來加載驅(qū)動程序。用戶也可以自行調(diào)用ActivateDevice來加載驅(qū)動程序。當(dāng)驅(qū)動被卸載時,應(yīng)調(diào)用DeActivateDevice,來卸載驅(qū)動程序。第3節(jié)串口驅(qū)動分析3.1串口設(shè)備簡述3.2流控制的引入3.3串口驅(qū)動架構(gòu)3.4驅(qū)動代碼分析3.1串口設(shè)備簡述串行接口是目前十分流行的通訊接口之一。在這里提到的串行接口主要是指UART(通用串行)和IRDA(紅外串口)兩種。通用串行連接通常分為3線和9線兩種。3線串口:

只使用TXD(發(fā)送),RXD(接收),GND(地線)三根連接線。9線串口:

在原3線的基礎(chǔ)上增加DCD,DTR,DSR,RTS,CTS,DELL六根控制線。其中RTS/CTS用于流控制,另外的DCD和DELL則留作連接modem使用。九線串口管腳定義

針號123456789縮寫DCDRXDTXDDTRGNDDSRRTSCTSDELL功能說明數(shù)據(jù)載波檢測接收數(shù)據(jù)發(fā)送數(shù)據(jù)數(shù)據(jù)終端就緒信號地數(shù)據(jù)設(shè)備就緒請求發(fā)送清除發(fā)送振鈴指示2410中串口原理圖

串口工作原理在串行接口控制器上會有兩FIFO用作接收和發(fā)送的緩沖。當(dāng)接收到數(shù)據(jù)后會直接將接收到的數(shù)據(jù)置入該緩沖器,并同時通知本地總線。而發(fā)送發(fā)送的過程剛剛相反,本地總線可一直向發(fā)送緩沖寫入數(shù)據(jù)直到器填滿為止,而無需對每個數(shù)據(jù)的發(fā)送進行等待。這一點在3線和9線中都是相同的。3.2流控制的引入

考慮這種情況

如果接收程序由于某種原因的干擾(如處理器被其他中斷服務(wù)占用)的時候,ReceiveFIFO就可能被填滿了。

解決方法需要數(shù)據(jù)的可靠傳輸就需要對數(shù)據(jù)流的收發(fā)進行控制??梢圆扇∮布骺刂苹蜍浖骺刂频姆椒?。硬件流控制用RTS/CTS(請求發(fā)送/清除發(fā)送)進行流控制時,應(yīng)將通訊兩端的RTS、CTS線對應(yīng)相連)。在發(fā)送端準(zhǔn)備發(fā)送數(shù)據(jù)之前設(shè)置RTS(Requesttosend),若接收端以作好接收準(zhǔn)備,就啟動響應(yīng)的CTS(Cleartosend)。此過程中如若接收端處理數(shù)據(jù)的速度低于發(fā)送端的發(fā)送速度,接收一端還可以將CTS引線恢復(fù)原來的阻塞狀態(tài),以暫時中斷數(shù)據(jù)傳輸。之后若需要恢復(fù)數(shù)據(jù)傳輸,只需將CTS恢復(fù)為有效狀態(tài)即可。軟件流控制3線傳輸時,若接收端接收數(shù)據(jù)過程中緩沖器的負(fù)載到達某一限制,接收端向發(fā)送端發(fā)送一個特殊的停止標(biāo)示。當(dāng)發(fā)送端收到該停止標(biāo)示的時候就停止發(fā)送。直到接收端緩沖器低于另一限制后發(fā)送接收標(biāo)示,繼續(xù)啟動發(fā)送。3.3串口驅(qū)動架構(gòu)

在wince中串口的驅(qū)動實現(xiàn)是有固定模型的,基于流驅(qū)動模型,采用分層架構(gòu)。串口驅(qū)動流接口口函數(shù)COM_CloseCOM_PowerDownCOM_DeinitCOM_PowerUpCOM_INIT COM_ReadCOM_IOControlCOM_WriteCOM_Open

驅(qū)動結(jié)構(gòu)3.4驅(qū)動代碼分析

結(jié)構(gòu)體HWOBJ定義了相應(yīng)的硬件設(shè)備操作的抽象集合。typedefstruct__HWOBJ{ULONG BindFlags;//FlagscontrollingMDDbehaviour.Seabove.DWORDdwIntID;//InterruptIdentifierusedifTHREAD_AT_INITorTHREAD_AT_OPENPHW_VTBL pFuncTbl;}HWOBJ,*PHWOBJ;BandFlags指定IST的啟動時間,可選為在初始化過程啟動或是在打開設(shè)備的時候起動ISR.dwIntID指定攔截的具體的系統(tǒng)中斷號。pFuncTbl被定義為一個結(jié)構(gòu)指針。該結(jié)構(gòu),即HW_VTBL,是代表具體硬件操作函數(shù)指針的集合。該結(jié)構(gòu)中的函數(shù)包括了初始化、打開、關(guān)閉、接收、發(fā)送、設(shè)置Baudrate等一系列操作。驅(qū)動MDD層中通過調(diào)用這些函數(shù)來訪問驅(qū)動的PDD層。該結(jié)構(gòu)存在就像紐帶一樣聯(lián)系著PDD中的具體實現(xiàn)和MDD中的抽象操作。PDD的實現(xiàn)必須遵循HW_VTBL中所描述的函數(shù)形式,并構(gòu)造出相應(yīng)的HW_VTBL實例。驅(qū)動的編寫就是針對這些函數(shù)來一一進行實現(xiàn)。驅(qū)動初始化--COM_InitCOM_Init是串口驅(qū)動的初始化函數(shù),在設(shè)備管理器加載該驅(qū)動后首先調(diào)用,用于初始化所需的變量,硬件設(shè)備等資源。在函數(shù)中定義了兩個重要的變量-pSerialHead和pHWHead。前者用于描述相應(yīng)的串口的狀態(tài),后者則是對應(yīng)硬件的數(shù)據(jù)抽象。首先為pSerialHead分配空間和初始化鏈表和臨界區(qū)等數(shù)據(jù)并同時為接收和發(fā)送中斷創(chuàng)建事件。然后再從注冊表中獲得當(dāng)前的注冊項值。得到DeviceArrayIndex、Priority256鍵下的具體值后就可以調(diào)用GetSerialObject(在PDD中實現(xiàn))來獲得具體的HWObj對象,并通過該對象來調(diào)用硬件初始化函數(shù)了。驅(qū)動釋放--COM_Deinit

當(dāng)驅(qū)動程序被卸載的時候該函數(shù)被調(diào)用,用作與COM_Init相反的操作。這個過程會釋放驅(qū)動中所使用的資源,停止期間創(chuàng)建的線程等操作。打開驅(qū)動實例--COM_OpenCOM_Open在CreateFile后被調(diào)用,用于以讀/寫模式打開設(shè)備。初始化所需要的空間/資源等,創(chuàng)建相應(yīng)的實例,為后面的操作做好準(zhǔn)備。首先檢查通過COM_Init返回的pHead結(jié)構(gòu)是否有效。之后是檢查文件系統(tǒng)傳遞過來的Open句柄中的Open模式是否有效。之后開始初始化的操作,在這里將會建立相應(yīng)的HW_OPEN_INFO實體。結(jié)構(gòu)體定義typedefstruct__HW_OPEN_INFO{PHW_INDEP_INFOpSerialHead;//@fieldPointerbacktoourHW_INDEP_INFODWORD AccessCode;//@fieldWhatpermissionswasthisopenedwithDWORD ShareMode;//@fieldWhatShareModewasthisopenedwithDWORDStructUsers;//@fieldCountofthreadscurrentlyusingstruct. COMM_EVENTS CommEvents; //@fieldContainsallin….handlingLIST_ENTRYllist;//@fieldLinkedlistofOPEN_INFOs }HW_OPEN_INFO,*PH結(jié)構(gòu)體說明結(jié)構(gòu)中的第一個參數(shù)指向HW_INDEP_INFO結(jié)構(gòu)。第二個參數(shù)為操作權(quán)限碼,也就是READ/WRITE這類的權(quán)限。第三個參數(shù)為共享模式,以確定是否支持獨占。這兩個參數(shù)都是與文件系統(tǒng)的內(nèi)容對應(yīng)的。而CommEvent則對應(yīng)于本實例的事件。由于驅(qū)動架構(gòu)支持多個OPEN操作實例的存在,所以這里維護了一個鏈表來聯(lián)系這些結(jié)構(gòu)。準(zhǔn)備好HW_OPEN_INFO結(jié)構(gòu)后就可以調(diào)用HWOpen(PDD)來進行PDD所需的Open操作了。Open操作完成后調(diào)用m(PDD)來處理(取消或等待)當(dāng)前仍在通訊狀態(tài)的任務(wù)。然后重置軟件FIFO就基本完成了COM_Open的動作。事實上這里主要是對所需的數(shù)據(jù)結(jié)構(gòu)進行處理,對于硬件的具體操作都留給PDD去做了,MDD所維護的僅僅是一個架構(gòu)性的代碼。Open操作完成后,驅(qū)動就進入了工作狀態(tài)。關(guān)閉驅(qū)動實例--COM_CloseCOM_Close為與COM_Open相對應(yīng)的逆操作。調(diào)用它的目的是釋放COM_Open所使用的系統(tǒng)資源。除此以外如果在COM_Open期間創(chuàng)建了相應(yīng)的IST還需要停止該線程最后將該HW_OPEN_INFO脫鏈。這樣一來驅(qū)動狀態(tài)就得以恢復(fù)。期間還做了一寫避免線程競爭的處理。StartDispatchThread/StopDispatchThread這兩個函數(shù)都不是流驅(qū)動的標(biāo)準(zhǔn)接口函數(shù),但卻是中斷服務(wù)程序所需的IST啟動和關(guān)閉的手段。StartDispatchThread函數(shù)用于啟動IST,主要的工作為調(diào)用InterruptInitialize將系統(tǒng)中斷與相應(yīng)的事件聯(lián)系起來。接下來啟動SerialDispatchThread作為IST,其中調(diào)用了InterruptDone的函數(shù),該函數(shù)會調(diào)用OAL中的OEMInterruptDone來完成中斷的響應(yīng)。StopDispatchThread用于與StartDispatchThread相反的操作。停止的過程相對要復(fù)雜一些,該函數(shù)首先設(shè)定當(dāng)前線程的優(yōu)先級與分發(fā)線程相同,以便于在停止該線程的動作不會比釋放內(nèi)存的動作快以避免出錯。停止的動作是讓線程主動完成的,具體的方法是提交表示位KillRxThread然后通過Sleep請求調(diào)度,待到IST自己停止。這個時候由于IST已經(jīng)停止,所以在程序的最后調(diào)用InterruptDisable來屏蔽中斷。SerialDispatchThread/SerialEventHandlerSerialDispatchThread/SerialEventHandler就是串口驅(qū)動的中斷分發(fā)程序(也就是IST的所在)。整個IST被分開寫成兩個部分---循環(huán)主體和事件處理程序。循環(huán)主體SerialDispatchThread內(nèi)容相對比較簡單,反復(fù)等待串口事件并調(diào)用SerialEventHandler對具體的中斷進行處理,直到pSerialHead->KillRxThread被設(shè)置后退出。SerialEventHandler為中斷處理的具體實現(xiàn),程序在獲得串口事件后運行,目的在于對中斷進行進一步的判斷并執(zhí)行相應(yīng)的處理。

讀取驅(qū)動數(shù)據(jù)--COM_ReadCOM_Read是獲取串所接收到數(shù)據(jù)的操作。該函數(shù)有三個參數(shù)。第一個參數(shù)是從上面的COM_OPEN通過設(shè)備管理器交換來的。后兩個參數(shù)與文件系統(tǒng)的使用方法完全一樣,一個是接受緩沖區(qū)的指針,另一個是緩沖區(qū)的長度。首先對參數(shù)進行檢查,包括對存取權(quán)限,OpenCnt等。之后計算超時時間,如果設(shè)定了超時讀取動作會在超時后返回,不管是否讀到了足夠長度的數(shù)據(jù)。隨后就是簡單對軟件緩沖進行讀取的操作了,讀取的操作是在RX_CS中完成的。下面要處理的主要就是幾種異常的情形,讀取過程中設(shè)備被關(guān)閉/取消讀取和超時.最后在讀取的過程中需要處理的就只是流控制的成本了。寫數(shù)據(jù)函數(shù)--COM_Write

COM_Write是與COM_Read相對應(yīng)的操作。所傳遞的參數(shù)的形式也是很相似的,僅僅是數(shù)據(jù)流向的不同。在程序的開始,同樣也是參數(shù)檢查,內(nèi)容與COM_Read一致。在數(shù)據(jù)檢查完成之后進入臨界區(qū)(保障多線程下的獨占)將送入的目標(biāo)地址和長度設(shè)置為TXbuffer,待到數(shù)據(jù)發(fā)送完成事件后調(diào)用DoTxData來啟動發(fā)送。這里啟動發(fā)送的目的在于獲得硬件中斷維持發(fā)送流程。DoTxData是作為兩種狀態(tài)來執(zhí)行的,在通過COM_Write的執(zhí)行的過程中是在device.exe所創(chuàng)建的線程空間內(nèi)執(zhí)行的,但由系統(tǒng)中斷事件主動啟動的過程中屬于IST本身的的進程空間。因此在COM_Write中調(diào)用DoTxData之前設(shè)置的權(quán)限代碼。(由GetCurrentPermissions獲得)就可以由TxBufferInfo傳遞到

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論