




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
Windows2023設備驅動程序
引言:
由于工作關系,我常常涉及PC機與外圍設備接口的工作,從PC機這方面要做的工作看來,主要是通過接口處理外圍設備的中斷,通過I/O端口或內存地址與外設相互傳遞數據。從計算機原理的角度看,所要到達的目的很簡潔,那么如何編寫程序完成上述功能呢?
目前國內流行的PC操作系統有三種:DOS,Win95/98系列,WindowsNT。DOS是單用戶、單任務操作系統,由于PC機硬件處理速度不斷提高,基于單用戶、單任務的操作系統越來越不能充分發揮硬件的功能,現在只應用于一些老式PC及其它個別場合,有漸漸被淘汰的趨勢;Win95/98系列和WindowsNT屬于多任務操作系統,不管從其原理還是界面上看,這兩種操作系統都比DOS有著無可比較的優越性,這兩種操作系統雖然在界面和操作上及其相像,但其內部實現的諸多方面有很多區分,有些區分是本質上的。Win95/98設計目標是針對一般家庭用戶,安全性及牢靠性存在很多薄弱環節,就牢靠性而言,Win95/98系列不能很好的防止多任務環境中某個進程的非法操作導致系統中其它程序甚至整個系統的崩潰,而WindowsNT在這方面及其它諸多方面設計的相當嚴謹。這兩種操作系統是Microsoft公司同一時期的產品,但針對不同的使用群,所以在一些重要場合及生產實踐中應當選擇WindowsNT作為計算機的操作系統,此外,從進展趨勢來看,WindowsNT已經成為定型產品,具有相對穩定性。
在不同操作系統下編寫驅動程序是有很大區分的,在DOS平臺上,應用程序和設備驅動程序之間沒有標準的接口,它們在外部表現為一個擴展名為EXE的文件,驅動程序的作用被嚴厲在應用程序中,這樣,應用程序為了使用不同廠商的同一類設備,必需了解這些設備在接口上詳細的硬件實現,同時,對于一個特定型號的硬件產品,全部支持它的應用軟件中對于掌握整個設備動作的這局部代碼,可能被屢次重寫。這種狀況不適應硬件及應用軟件的飛速進展。Windows系統在這方面,進展了根本性改良,把掌握設備動作的這局部代碼獨立出來,提出了設備驅動程序的概念,驅動程序是應用程序和硬件設備之間的一個橋梁,應用程序與驅動程序之間有明確的接口,應用程序通過與驅動程序交換信息,到達掌握外設的目的。接口定義的操作是面對設備的,這就是說,在應用程序的設計中,并不用關懷對外設操作的詳細硬件實現,只是對驅動程序發出一系列指令既可;驅動程序承受來自上層應用程序的指示,詳細操縱實際硬件,完成用戶功能。詳細實現上,Win95/98系列與WindowsNT又有所區分,WindowsNT是嚴格根據上述思路設計的;而Win95/98系列不那么嚴格,其支持上述思路,但同時應用程序也可以繞過驅動程序直接訪問實際物理I/O,這樣做,增加程序設計的敏捷性,但同時,對系統牢靠性造成肯定隱患。這也正是Win95/98系列牢靠性低于WinNT的緣由之一。
WindowsNT設備驅動程序的組成原理
WindowsNT操作系統構造分為用戶模式和內核模式,用戶模式下的編程為應用程序的設計,而開發設備驅動程序,則屬于內核模式下的編程,內核模式組件包括NTExecutive(ExXxx),內核(KeXxx),硬件抽象層(HalXxx)。其層次如圖2-1所示,其中NTExecutive包括幾個獨立的軟件組件,它們是系統效勞接口(ZwXxx),對象治理器(ObXxx),配置治理器,進程治理器(PsXxx),安全監視器(SeXxx),虛擬空間治理器(MemXxx),本地進程調用,I/O治理器(IoXxx)。內核模式的系統效勞并不是全部公開的,而是供應了一系列開發設備驅動程序需要的函數(上文括號內為函數形式,函數手冊參見[2]Kernel-ModeDrivers-Reference章節),換言之,這些函數功能是全部內核模式的系統效勞功能的子集。
驅動程序由一系列相對獨立的函數組成,由I/O治理器依據需要調用這些函數,對于一個需要處理中斷的最簡潔的驅動程序也需要由以下幾個函數構成:
1.DriverEntry()運行于PASSIVE_LEVEL
驅動程序入口點,當驅動程序被手動或自動裝入系統后,驅動程序從這點開頭執行,主要用于定位硬件資源,建立指向其它驅動程序函數的指針等其它初始化工作。
2.XxUnload()運行于PASSIVE_LEVEL
用于驅動程序從系統卸出之前,釋放由驅動程序占用的全部系統資源。
3.XxIsr()運行于DIRQL
中斷效勞程序。
4.XxDpcForIsr()運行于DISPATCH_LEVEL
中斷效勞程序后處理程序,以排隊方執行不太關鍵代碼的執行,由于排隊機制及優先級,不會造成代碼擁塞從而提高中斷效勞程序的響應并且提高系統總體I/O吞吐率。
5.XxOpen()運行于PASSIVE_LEVEL
處理應用程序Win32函數CreateFile()懇求。
6.XxClose()運行于PASSIVE_LEVEL
處理應用程序Win32函數CloseHandle()懇求。
7.XxDispatch()運行于PASSIVE_LEVEL
處理應用程序Win32函數DeviceIoControl()懇求,通過一系列自定義命令,驅動程序與應用程序交換特定的信息。
WindowsNT使用一個抽象化的CPU優先級方案,IRQL代表中斷懇求級,任一時刻CPU總處在某一級上,這個數越大,表示當前的任務重要性越大,如表2-1所示,從上至下IRQL越來越小。全部上述驅動程序的函數及內核模式函數都必需運行于各自的IRQL級上,假如違反這一調用規定,會造成系統崩潰。例如,中斷效勞程序(XxIsr)運行于DIRQL及上,那幺在編寫中斷效勞程序時,只能調用允許在這一級運行的內核模式函數(并不是全部內核模式函數都能運行于DIRQL級)。至于每個內核模式函數運行級別的說明,詳見[2]Kernel-ModeDrivers-Reference章節。
WindowsNT是一多任務系統,很多設備的驅動程序同時存在系統中,這樣各個設備所占用的資源(中斷,I/O及RAM地址空間)很有可能沖突,假如設備驅動程序在運行之前不進展‘探測’而使用自己硬件設備的資源,有可能和系統內其它設備占用的資源沖突,后果不堪設想。WindowsNT通過注冊表治理硬件資源的占用信息,作為內核模式信任的組件,驅動程序使用硬件資源之前必需遵循‘查詢-申請-使用-釋放’的原則
WindowsNT設備驅動程序的編寫步驟與實例
現以一實際例子簡要說明設備驅動程序的開發步驟,本例以CINRAD天氣雷達測試卡實際應用為原型,加以簡化、抽象。
第一步,了解被控設備的接口狀況。
本例為一ISA卡,占用PC機9號中斷,I/O地址360H及RAM地址D0228H分別一個字空間。
其次步,確定驅動程序的功能。
驅動程序每當9號中斷到達時,檢查運行標志變量RunFlag(為一BOOL變量),假如等于TRUE,中斷累積計數器counter(為一unsignedshort變量)增一,把這個值寫入RAM地址D0228H,再從這個地址讀出,假如讀出值等于寫入值,把這個值寫入I/O地址360H,這個地址的內容會驅動板卡上的LED顯示,把寫入值顯示出來;假如讀出值不等于寫入值,設置運行標志變量FALSE。假如運行標志變量等于FALSE,什幺也不做,返回。
第三步,定義驅動程序與應用程序的軟件接口。
本例定義兩個接口命令:
IOCTL_IOCardA_START:應用程序設置驅動程序內部的運行標志變量等于TRUE。
IOCTL_IOCardA_READ:應用程序查詢驅動程序內部的中斷累積計數器的值。
第四步,畫流程圖。這里列舉本例實現的幾個主要流程圖,(圖略)。
系統傳給驅動程序入口函數系統定義的‘設備驅動對象’DrObj,通過初始化這個對象的一些成員變量,把驅動程序其它函數與這個對象聯系起來。
ISA卡為非即插即用設備,事先把資源占用信息手工添加注冊表如下:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IOCardA\parameters]
“IRQ“=dword:00000009
“IOSPAN“=dword:00000004
“IOAdd“=dword:00000360
“RAMAdd“=dword:000d0228
“RAMSPAN“=dword:00000002
其中IOCardA以下各子鍵及其值為自定義,設備驅動程序利用相應函數檢索出這些值。
(3)每個設備驅動程序可以創立若干系統定義的‘設備對象’,本例依據需要只創立了一個‘設備對象’Dev。‘設備對象’其中一個成員變量為指向一非分頁的物理內存塊DeviceExtension,這塊內存大小及內容為用戶自定義,由于Dev或DeviceExtension對象會被系統傳給驅動程序的其它函數,這樣驅動程序各函數通過訪問這塊內存區,實際上到達相互傳遞信息的功能。本例在這里存儲設備硬件資源信息及RunFlag和中斷計數器counter,這些數值在DriverEntry()初始化后,供驅動程序的其它函數使用。
圖3-2為中斷效勞程序IOCardAIsr()流程圖。操作系統承受中斷,連同DeviceExtension等參數傳給中斷效勞程序,中斷效勞程序利用這些參數,實現要求功能。
圖3-3為IOCardADispatch()流程圖,這個函數用于處理來自上層應用程序的命令。上層應用程序通過以下程序段設置驅動程序中RunFlag值為TRUE,從而啟動中斷效勞程序開頭計數。
BOOLcmd=TRUE;
hTest=CreateFile(...);//翻開設備
DeviceIoControl(hTest,//設備句柄
IOCTL_IOCardA_START,//命令
cmd,sizeof(BOOL),//輸入緩沖區地址及大小
NULL,0,c,NULL);
CloseHandle(hTest);//關閉設備
上層應用程序通過以下程序段查詢當前的中斷計數器的值并存于變量w中。
unsignedshortw;
hTest=CreateFile(...);
DeviceIoControl(hTest,
IOCTL_IOCardA_READ,//命令
NULL,0,
w,sizeof(unsignedshort),//輸出緩沖區地址及大小
c,NULL);
CloseHandle(hTest);
其中DeviceIoControl()執行后,操作系統調用IOCardADispatch()函數,如流程圖所示,這個函數內部通過一個開關語句,依據命令執行相應的分支。驅動程序與應用程序通過此函數接換數據時,操作系統供應4種可選數據緩沖方式,本例由于數據I/O量比擬小,應選用‘緩沖I/O’(METHOD_BUFFERED)。過程是,I/O治理器首先安排一個非分頁池,它的大小為調用者輸入緩沖區和輸出緩沖區的較大者,第一段程序為sizeof(BOOL),其次段程序為sizeof(unsignedshort),它的地址存到IRP(I/O懇求包)的AssociatedIrp.SystemBuffer域中,然后把輸入數據拷貝到這個池中,在第一段程序中cmd的值TRUE被拷貝到池中,這樣驅動程序通過RtlCopyBytes()函數再把池中的值拷貝到驅動程序的RunFlag中。IOCardADispatch()函數執行完,I/O治理器把池中的內容拷貝到調用者的輸出緩沖區,在其次段程序中,驅動程序通過RtlCopyBytes()函數把counter的值拷貝到池中,從而最終傳遞到應用程序變量w中。
第五步,編程。在編寫設備驅動程序的同時,要編寫一個簡潔的應用程序用于測試設備驅動程序的一些功能。
第六步,驅動程序的載入。
驅動程序C語言源程序經過編譯、連接生成擴展名為SYS的文件,本例為IOCardA.sys,把這個文件拷貝到\WINNT\system32\drivers\系統名目下,同時手工添加如下信息到注冊表:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IOCardA]
“ErrorControl“=dword:00000001
“Start“=dword:00000003
“Type“=dword:00000001
要保證IOCardA子鍵名與驅動程序文件名全都,其中Type=1表示此驅動程序為內核模式驅動程序,Start=3表示此驅動程序手動載入,E
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025【國際服務貿易合同】國際服務貿易合同的標準
- 2025簡易技術委托開發合同范本
- 2025茶葉委托加工合同范本
- 2025租賃合同解除協議模板
- 幼兒園蔬菜化妝舞會
- 二零二五房屋居間合同書范例
- 庫房出租簡單合同書范例二零二五年
- 房屋出租合同書水電費規定
- 二零二五養殖勞動聘用合同
- 授權經銷合同書協議書范例二零二五年
- 銷售部長助理崗位職責
- ISOTS 22163專題培訓考試
- 六年級下冊數學課件-第4單元 比例 整理和復習 人教版(共21張PPT)
- JJF(魯) 142-2022 稱重式雨量計校準規范
- Adobe-Illustrator-(Ai)基礎教程
- 程序的運行結果PPT學習教案
- 圓柱鋼模計算書
- 合成寶石特征x
- 查擺問題及整改措施
- 年度研發費用專項審計報告模板(共22頁)
- 隧道工程隧道支護結構設計實用教案
評論
0/150
提交評論