版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)2022/12/17第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)2022/12/1Windows是一個(gè)多任務(wù)操作系統(tǒng),在保護(hù)模式下工作。Windows操作系統(tǒng)不支持用戶(hù)程序?qū)τ?jì)算機(jī)底層硬件進(jìn)行直接控制。用戶(hù)程序需要輸入/輸出時(shí),可以通過(guò)通過(guò)API(ApplicationProgramInterface,應(yīng)用程序接口)來(lái)調(diào)用設(shè)備驅(qū)動(dòng)程序,對(duì)設(shè)備實(shí)現(xiàn)間接控制,進(jìn)行輸入/輸出。Windows9x使用VxDs(VirtualDeviceDriver’s,虛擬設(shè)備驅(qū)動(dòng))設(shè)備驅(qū)動(dòng)程序。Windows2000/XP使用WDM(WindowsDriverModel,Windows驅(qū)動(dòng)程序模型)設(shè)備驅(qū)動(dòng)程序。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)Windows是一個(gè)多任務(wù)操作系統(tǒng),在保護(hù)模式下工作。第11211.1Windows設(shè)備驅(qū)動(dòng)程序
11.1.1虛擬設(shè)備 在多任務(wù)運(yùn)行環(huán)境下,計(jì)算機(jī)內(nèi)的硬件、軟件資源為多個(gè)任務(wù)共享。任何一個(gè)用戶(hù)程序都不能獨(dú)占系統(tǒng)的硬件、軟件資源。虛擬設(shè)備實(shí)質(zhì)上是真實(shí)物理設(shè)備的部分資源和相關(guān)軟件的組合,用來(lái)完成用戶(hù)程序需要的功能。虛擬設(shè)備不但可以代表實(shí)際存在的硬件設(shè)備,還可以模擬實(shí)際上不存在的“設(shè)備”,供用戶(hù)使用。計(jì)算機(jī)上的“虛擬光驅(qū)”就是一個(gè)典型的虛擬設(shè)備。與這個(gè)設(shè)備同名的物理設(shè)備是不存在的,用戶(hù)使用的是硬盤(pán)的部分存儲(chǔ)空間以及相應(yīng)的服務(wù)程序。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.1Windows設(shè)備驅(qū)動(dòng)程序11.1.13使用虛擬設(shè)備好處:實(shí)現(xiàn)多任務(wù)對(duì)系統(tǒng)資源的共享,方便用戶(hù)的使用;實(shí)現(xiàn)任務(wù)與任務(wù)、任務(wù)與系統(tǒng)之間的隔離和保護(hù);規(guī)范外部設(shè)備輸入、輸出方法,使不同工作方式的設(shè)備用相同的方式進(jìn)行輸入輸出。對(duì)Windows應(yīng)用程序來(lái)講,虛擬設(shè)備就是真實(shí)設(shè)備,應(yīng)用程序分不清那個(gè)設(shè)備是由真實(shí)硬件支持的真實(shí)設(shè)備,那個(gè)設(shè)備是由虛擬設(shè)備驅(qū)動(dòng)程序模擬的虛擬設(shè)備。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)使用虛擬設(shè)備好處:第11章Windows環(huán)境下輸入輸出程序設(shè)411.1.2
Windows9X設(shè)備驅(qū)動(dòng)程序Windows9x是一個(gè)分層結(jié)構(gòu)的操作系統(tǒng),由工作在兩個(gè)不同層面的組件構(gòu)成:頂層組件,工作在Ring3層;底層組件,工作在Ring0層。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.1.2Windows9X設(shè)備驅(qū)動(dòng)程序5頂層:Windows9x操作系統(tǒng)的頂層組件工作在特權(quán)級(jí)3,稱(chēng)為ring3層。它給應(yīng)用程序的運(yùn)行提供Win32API服務(wù)。Windows9x應(yīng)用程序和Win32API服務(wù)一起構(gòu)成操作系統(tǒng)的頂層,稱(chēng)為系統(tǒng)虛擬機(jī)(VM,VirtualMachine)。對(duì)于一個(gè)任務(wù)來(lái)說(shuō),這些服務(wù)程序以及他們所掌控的硬件資源就是一臺(tái)“實(shí)實(shí)在在”的計(jì)算機(jī)。但是,對(duì)于整個(gè)系統(tǒng)來(lái)說(shuō),他們只是由操作系統(tǒng)向用戶(hù)提供的一個(gè)運(yùn)行用戶(hù)程序的平臺(tái),包括為這個(gè)應(yīng)用程序服務(wù)的操作系統(tǒng)組件和部分的硬件資源。每一個(gè)DOS應(yīng)用程序都在一個(gè)獨(dú)立的虛擬機(jī)中運(yùn)行,操作系統(tǒng)允許多個(gè)虛擬機(jī)同時(shí)處于運(yùn)行狀態(tài)。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)頂層:第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)6底層:Windows9x操作系統(tǒng)的底層組件工作在0特權(quán)級(jí),稱(chēng)為ring0層,它就是虛擬機(jī)管理器(VMM,VirtualMachineManager)。Windows9x虛擬機(jī)管理器由一個(gè)內(nèi)核服務(wù)集和許多虛擬設(shè)備驅(qū)動(dòng)程序(VxDs,VirtualDeviceDriver’s)組成。許多VxDs是由Microsoft公司隨操作系統(tǒng)提供的,如鍵盤(pán)和顯示器等的VxDs,有的VxD則由設(shè)備制造商提供,或者由用戶(hù)自行編寫(xiě)。VxD用來(lái)支持特定的硬件或軟件,完成需要的功能。VxDs中的程序運(yùn)行在ring0層,可以執(zhí)行所有的指令,完成所需的任何軟硬件的操作。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)底層:第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)7 對(duì)于應(yīng)用程序而言,虛擬機(jī)管理器是透明的,應(yīng)用程序感覺(jué)不到管理器的存在。 微軟已經(jīng)宣布,從2006年6月起不再提供對(duì)Windows9x的技術(shù)支持。因此,Windows9x和VxDs的使用將逐漸減少。隨著Windows2000/XP的廣泛使用,WDM驅(qū)動(dòng)程序的開(kāi)發(fā)和使用已成為主流。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 對(duì)于應(yīng)用程序而言,虛擬機(jī)管理器是透明的,應(yīng)用程序感覺(jué)不到811.1.3
Windows2000/XP設(shè)備驅(qū)動(dòng)程序Windows2000操作系統(tǒng)組件的層次結(jié)構(gòu) Windows2000操作系統(tǒng)的功能模塊劃分為用戶(hù)模式和內(nèi)核模式兩大類(lèi)。用戶(hù)模式的操作系統(tǒng)功能模塊工作在ring3層,他們不能使用CPU中的特權(quán)指令,連同IN、OUT這樣的非特權(quán)指令也被禁止。所有的用戶(hù)程序都在這一層上運(yùn)行。內(nèi)核模式的操作系統(tǒng)模塊工作在ring0層,可以使用CPU的任何指令。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.1.3Windows2000/XP設(shè)備驅(qū)動(dòng)程序Wi9Windows2000操作系統(tǒng)的層次結(jié)構(gòu)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)Windows2000操作系統(tǒng)的層次結(jié)構(gòu)第11章Windo102.Windows2000的設(shè)備驅(qū)動(dòng)程序Windows2000的驅(qū)動(dòng)程序也有兩種不同的類(lèi)型。
用戶(hù)模式驅(qū)動(dòng)程序工作在用戶(hù)模式,通過(guò)調(diào)用內(nèi)核模式驅(qū)動(dòng)程序?qū)崿F(xiàn)指定的功能。用戶(hù)模式驅(qū)動(dòng)程序不能直接對(duì)硬件設(shè)備進(jìn)行訪問(wèn),僅僅用于構(gòu)建一個(gè)硬件或軟件的運(yùn)行環(huán)境。
Windows內(nèi)核驅(qū)動(dòng)程序工作在內(nèi)核模式,可以直接訪問(wèn)硬件設(shè)備。每個(gè)設(shè)備驅(qū)動(dòng)程序都有一組完成各種功能的函數(shù),通過(guò)調(diào)用這些函數(shù)可以對(duì)某一設(shè)備完成特定的操作。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)2.Windows2000的設(shè)備驅(qū)動(dòng)程序第11章Wi11內(nèi)核模式驅(qū)動(dòng)程序的類(lèi)型文件系統(tǒng)驅(qū)動(dòng)程序可以在本地硬盤(pán)、網(wǎng)絡(luò)、移動(dòng)存儲(chǔ)設(shè)備或各種有存儲(chǔ)能力的硬件設(shè)備實(shí)現(xiàn)標(biāo)準(zhǔn)的文件系統(tǒng),如FAT32、NTFS系統(tǒng)等。PnP驅(qū)動(dòng)程序是一種遵循Windows2000即插即用協(xié)議的內(nèi)核模式驅(qū)動(dòng)程序。WDM驅(qū)動(dòng)程序是一種PnP驅(qū)動(dòng)程序。它同時(shí)還遵守電源管理協(xié)議。顯示驅(qū)動(dòng)程序是一種特殊的內(nèi)核驅(qū)動(dòng)程序。此類(lèi)的驅(qū)動(dòng)程序還有打印驅(qū)動(dòng)程序、多媒體驅(qū)動(dòng)程序、網(wǎng)絡(luò)驅(qū)動(dòng)程序等。遺留設(shè)備驅(qū)動(dòng)程序主要用在WindowsNT系統(tǒng)中,它也可以運(yùn)行在Windows2000系統(tǒng)中。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)內(nèi)核模式驅(qū)動(dòng)程序的類(lèi)型第11章Windows環(huán)境下輸入輸出程12Windows2000內(nèi)核模式驅(qū)動(dòng)程序的類(lèi)型第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)Windows2000內(nèi)核模式驅(qū)動(dòng)程序的類(lèi)型第11章Win1311.2WDM驅(qū)動(dòng)程序
WDM是Microsoft力推的新型驅(qū)動(dòng)程序模型,首先出現(xiàn)在WindowsNT中,現(xiàn)在的Windows98/Me/2000/XP都支持WDM。微軟宣稱(chēng),在后續(xù)的操作系統(tǒng)中將繼續(xù)支持WDM。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.2WDM驅(qū)動(dòng)程序WDM是Mi14WDM是一個(gè)分層的驅(qū)動(dòng)程序。它至少有功能驅(qū)動(dòng)程序(Functiondriver)和總線驅(qū)動(dòng)程序(Busdriver)兩個(gè)層面。功能驅(qū)動(dòng)程序提供一個(gè)設(shè)備的使用功能,或者可以認(rèn)為它就是一個(gè)設(shè)備的驅(qū)動(dòng)程序。用戶(hù)程序需要使用該設(shè)備時(shí),需要調(diào)用功能驅(qū)動(dòng)程序中的功能函數(shù)??偩€驅(qū)動(dòng)程序負(fù)責(zé)系統(tǒng)啟動(dòng)時(shí)設(shè)備的安裝、檢測(cè),并確定設(shè)備的資源使用情況。設(shè)備的啟動(dòng)、停止,設(shè)備的初始化,設(shè)備的電源管理等功能也都由總線驅(qū)動(dòng)程序提供。11.2.1WDM驅(qū)動(dòng)程序模型和層次結(jié)構(gòu)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)WDM是一個(gè)分層的驅(qū)動(dòng)程序。它15 WDM引入了
功能設(shè)備對(duì)象FDO(FunctionalDeviceObject)
物理設(shè)備對(duì)象PDO(PhysicalDeviceObject)
兩個(gè)新概念來(lái)描述硬件。一個(gè)PDO對(duì)應(yīng)一個(gè)真實(shí)硬件。一個(gè)硬件只允許有一個(gè)PDO,卻可以擁有多個(gè)FDO,在驅(qū)動(dòng)程序中直接操作的不是硬件而是相應(yīng)的PDO與FDO。根據(jù)具體的需要還可以選擇過(guò)濾驅(qū)動(dòng)程序(filterdriver)。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) WDM引入了
功能設(shè)備對(duì)象FDO(FunctionalDe16Windows20000的輸入輸出是包驅(qū)動(dòng)的應(yīng)用程序調(diào)用WDM驅(qū)動(dòng)程序時(shí),系統(tǒng)為每一個(gè)用戶(hù)的請(qǐng)求打包,形成一個(gè)I/O請(qǐng)求包(I/ORequestPackage,IRP),然后將其發(fā)送至驅(qū)動(dòng)程序。IRP中的PDO字段用來(lái)區(qū)別是發(fā)送給哪一個(gè)設(shè)備的。某個(gè)層次的驅(qū)動(dòng)程序得到IRP后,分析其中的請(qǐng)求,完成本層應(yīng)該完成的任務(wù)。如果IRP要求的任務(wù)已經(jīng)完成,該層次的驅(qū)動(dòng)程序就向上一層傳送結(jié)果并逐層返回。如果IRP中的請(qǐng)求尚未完成,那么就繼續(xù)向下層驅(qū)動(dòng)程序傳遞這個(gè)IRP。內(nèi)核組件就是這樣通過(guò)發(fā)送IRP來(lái)運(yùn)行驅(qū)動(dòng)程序中的代碼第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)Windows20000的輸入輸出是包驅(qū)動(dòng)的第11章Wind17WDM驅(qū)動(dòng)程序?qū)哟闻cI/O請(qǐng)求過(guò)程第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)WDM驅(qū)動(dòng)程序?qū)哟闻cI/O請(qǐng)求過(guò)程第11章Windows環(huán)1811.2.2
WDM驅(qū)動(dòng)程序開(kāi)發(fā)工具 目前有兩個(gè)主要的工具來(lái)開(kāi)發(fā)設(shè)備驅(qū)動(dòng)程序,一個(gè)是Microsoft公司提供的WindowsDDK。它有Windows98DDK、Windows2000DDK、WindowsXPDDK和Windows2003DDK四個(gè)版本,分別用來(lái)支持相應(yīng)的四個(gè)操作系統(tǒng)中VxD和WDM驅(qū)動(dòng)程序的開(kāi)發(fā)。 用WindowsDDK開(kāi)發(fā)驅(qū)動(dòng)程序難度較大。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.2.2WDM驅(qū)動(dòng)程序開(kāi)發(fā)工具 19另一個(gè)驅(qū)動(dòng)程序開(kāi)發(fā)工具是NuMega公司提供的DriverStudio,其中包含VtoolsD、DriversWorks、DriversNetWorks和SoftICE。VtoolsD用來(lái)開(kāi)發(fā)Windows98的VxD驅(qū)動(dòng)程序。DriversWorks和DriversNetWorks分別用來(lái)開(kāi)發(fā)一般設(shè)備和網(wǎng)絡(luò)設(shè)備的WDM驅(qū)動(dòng)程序。SoftICE是一個(gè)功能強(qiáng)大的調(diào)試工具。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)另一個(gè)驅(qū)動(dòng)程序開(kāi)發(fā)工具是NuMega公司提供的Dr20DriverStudio的開(kāi)發(fā)是建立在WindowsDDK的基礎(chǔ)上的,安裝DriverStudio時(shí),先要安裝WindowsDDK。DriverStudio將WindowsDDK的內(nèi)容封裝在一些基本的類(lèi)中,使用VC++編程。使用DriverStudio來(lái)開(kāi)發(fā)Windows的驅(qū)動(dòng)程序,相對(duì)WindowsDDK來(lái)講要容易得多。DriverStudio使用開(kāi)發(fā)向?qū)?,幫助你建立編?xiě)驅(qū)動(dòng)程序所需要的工程文件和程序框架文件,這些文件已經(jīng)組成了一個(gè)完整的設(shè)備驅(qū)動(dòng)程序。接下來(lái)的工作就是將這些文件導(dǎo)入到VC++的開(kāi)發(fā)環(huán)境中,添加具體的操作代碼,進(jìn)行進(jìn)一步的開(kāi)發(fā)。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)DriverStudio的開(kāi)發(fā)是建立在WindowsDDK2111.2.3
DriverStudio中的WDM驅(qū)動(dòng)程序結(jié)構(gòu)
從基本W(wǎng)DM啟動(dòng)程序的兩個(gè)頭文件中可以大致看清WDM驅(qū)動(dòng)程序的基本框架結(jié)構(gòu)。KDriver是WDM驅(qū)動(dòng)程序的基類(lèi),任何驅(qū)動(dòng)程序都要從繼承該類(lèi)開(kāi)始。SimpleWdmDriver驅(qū)動(dòng)程序從派生KDriver類(lèi)開(kāi)始。SimpleWdmDevice是KPnpDevice類(lèi)的派生類(lèi)。重載其某些成員函數(shù)便可處理相應(yīng)事件的發(fā)生。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.2.3DriverStudio中的WDM驅(qū)動(dòng)程序結(jié)22最重要的方法是virtualNTSTATUSDeviceControl(KIrpI),應(yīng)用程序中原本需要對(duì)硬件設(shè)備的I/O訪問(wèn)指令被移到了DeviceControl中。應(yīng)用程序需要訪問(wèn)硬件設(shè)備時(shí),可以使用DeviceIoControl函數(shù),最后DeviceIoControl會(huì)調(diào)用DeviceControl,從而完成對(duì)設(shè)備的I/O訪問(wèn)。可以說(shuō)DeviceControl就是功能驅(qū)動(dòng)程序。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)最重要的方法是virtualNTSTATUSDevice23//HelloWdm.h-includefileforbasicWDMdriverclassSimpleWdmDriver:publicKDriver{public:
//DriverEntry負(fù)責(zé)驅(qū)動(dòng)程序的初始化,必須重載 virtualNTSTATUS
DriverEntry(PUNICODE_STRINGRegistryPath);
//AddDevice初始化驅(qū)動(dòng)程序所控制的設(shè)備,必須重載virtualNTSTATUSAddDevice(PDEVICE_OBJECTPdo);
//Unload刪除由DriverEntry所分配的資源 virtualVOIDUnload(void);};第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)//HelloWdm.h-includefilef24//hellodev.h-includefilefordeviceclassofbasicdriverclassSimpleWdmDevice:publicKPnpDevice{public: SimpleWdmDevice(PDEVICE_OBJECTPdo,ULONGUnit);
//PlugandPlayhandlers NTSTATUSOnStartDevice(KIrpI); //設(shè)備啟動(dòng)時(shí)調(diào)用。 NTSTATUSOnStopDevice(KIrpI); //設(shè)備停止時(shí)調(diào)用。 NTSTATUSOnRemoveDevice(KIrpI);
//設(shè)備刪除時(shí)調(diào)用。
//UserControlhandlers
//設(shè)備打開(kāi)時(shí)調(diào)用,應(yīng)用程序使用Create函數(shù)時(shí)調(diào)用。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)//hellodev.h-includefilef25virtualNTSTATUSCreate(KIrpI); //設(shè)備關(guān)閉時(shí)調(diào)用,即應(yīng)用程序使用Create函數(shù)時(shí)調(diào)用。virtualNTSTATUSClose(KIrpI); //設(shè)備功能調(diào)用,應(yīng)用程序使用DeviceIoControl函數(shù)時(shí)被調(diào)用 virtualNTSTATUSDeviceControl(KIrpI); //PowerManagementhandlers NTSTATUSOnDevicePowerUp(KIrpI); // NTSTATUSOnDeviceSleep(KIrpI); //設(shè)備睡眠時(shí)調(diào)用 NTSTATUSOnSetPower(KIrpI); // NTSTATUSDefaultPnp(KIrpI); // NTSTATUSDefaultPower(KIrpI); };第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)virtualNTSTATUSCreate(KIrp2611.3Windows2000/XP下輸入
輸出的實(shí)現(xiàn)Windows是一個(gè)基于“消息傳遞”機(jī)制的多任務(wù)操作系統(tǒng)。用戶(hù)程序需要訪問(wèn)硬件設(shè)備時(shí),通過(guò)調(diào)用API函數(shù)調(diào)用該設(shè)備的驅(qū)動(dòng)程序。WIN32將用戶(hù)的請(qǐng)求組合成為一個(gè)IRP包,向內(nèi)核發(fā)送“消息”。 內(nèi)核組件根據(jù)IRP中的PDO字段,將該“消息”傳送給對(duì)應(yīng)的WDM驅(qū)動(dòng)程序。 驅(qū)動(dòng)程序完成硬件設(shè)備的訪問(wèn)后,向用戶(hù)程序返回結(jié)果。 調(diào)用驅(qū)動(dòng)程序的過(guò)程,就是用戶(hù)程序和驅(qū)動(dòng)程序之間傳遞消息,交換數(shù)據(jù),進(jìn)行通信的過(guò)程。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.3Windows2000/XP下輸入
27 用戶(hù)程序完成對(duì)設(shè)備的訪問(wèn)有兩種方式等待方式下,用戶(hù)程序調(diào)用驅(qū)動(dòng)程序,等待驅(qū)動(dòng)程序完成對(duì)硬件設(shè)備的訪問(wèn)。這種方式編程簡(jiǎn)單。異步方式下,應(yīng)用程序調(diào)用驅(qū)動(dòng)程序,啟動(dòng)了硬件設(shè)備后,直接返回進(jìn)行其它處理,并不等待輸入/輸出完成。硬件設(shè)備完成了數(shù)據(jù)輸入輸出后,由驅(qū)動(dòng)程序通知應(yīng)用程序進(jìn)行進(jìn)一步的處理。這時(shí),需要由驅(qū)動(dòng)程序發(fā)起和應(yīng)用程序的通信。這種方式下,要用到反調(diào)函數(shù)、Win32事件通知等方法。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 用戶(hù)程序完成對(duì)設(shè)備的訪問(wèn)有兩種方式第11章Windows環(huán)28CreateFile()函數(shù)用來(lái)打開(kāi)設(shè)備,獲取設(shè)備句柄;設(shè)備輸入輸出控制函數(shù)DeviceIoControl(),用來(lái)調(diào)用WDM驅(qū)動(dòng)程序執(zhí)行相應(yīng)的操作(包括設(shè)備的控制和數(shù)據(jù)的輸入,輸出);CloseHandle()函數(shù)用來(lái)關(guān)閉設(shè)備。也可以使用ReadFile()和WriteFile()函數(shù)進(jìn)行“標(biāo)準(zhǔn)”的輸入/輸出。11.3.1用于輸入/輸出的WIN32API函數(shù)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)CreateFile()函數(shù)用來(lái)打開(kāi)設(shè)備,獲取設(shè)備句柄;1291.打開(kāi)設(shè)備
CreateFile()函數(shù)用來(lái)打開(kāi)設(shè)備,獲取設(shè)備句柄,格式如下:HANDLECreateFile(“\\\\.\\SimpleWDMDevice”, //設(shè)備的符號(hào)鏈接名GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, //同步打開(kāi)設(shè)備N(xiāo)ULL );使用上述函數(shù)時(shí),除了設(shè)備名之外,不需要改變其它參數(shù)。這里假設(shè)設(shè)備的名字為SimpleWDMDevice。進(jìn)行打開(kāi)操作時(shí)首先搜索當(dāng)前目錄,然后搜索Windows系統(tǒng)目錄。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)1.打開(kāi)設(shè)備第11章Windows環(huán)境下輸入輸出程302.DeviceIoControl函數(shù)調(diào)用DeviceIoControl( HANDLE hDevice, //設(shè)備句柄 DWORD dwIoControlCode, //控制代碼 LPVOID lpInBuffer, //輸入數(shù)據(jù)塊指針 DWORD nInBufferSize,//輸入數(shù)據(jù)塊大小 LPVOID lpOutBuffer, //輸出數(shù)據(jù)塊指針 DWORD nOutBufferSize,//輸出數(shù)據(jù)塊大小 LPDWORD lpBytesReturned, //返回字節(jié)長(zhǎng)度指針 NULL //同步時(shí)為NULL )第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)2.DeviceIoControl函數(shù)調(diào)用第11章Wind31DeviceIoControl函數(shù)調(diào)用參數(shù)hDevice是由CreateFile函數(shù)獲取的設(shè)備句柄。dwIOControlCode是應(yīng)用程序向WDM驅(qū)動(dòng)程序發(fā)出的控制代碼。lpInBuffer和nInBufferSize是應(yīng)用程序向WDM驅(qū)動(dòng)程序傳送的I/O數(shù)據(jù)塊的地址及大小。lpOutBuffer、nOutBufferSize和lpBytesReturned是WDM驅(qū)動(dòng)程序返回給應(yīng)用程序的數(shù)據(jù)塊的地址、大小以及實(shí)際返回的字節(jié)數(shù)。輸入/輸出緩沖區(qū)的格式由驅(qū)動(dòng)程序自行規(guī)定。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)DeviceIoControl函數(shù)調(diào)用參數(shù)第11章W323.關(guān)閉設(shè)備 完成對(duì)設(shè)備的輸入、輸出控制后, 應(yīng)用程序調(diào)用CloseHandle(hDevice)關(guān)閉設(shè)備。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)3.關(guān)閉設(shè)備第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)334.ReadFile和WriteFile函數(shù)ReadFile( HANDLE hFile, //設(shè)備句柄 LPVOID lpBuffer, //輸入數(shù)據(jù)塊指針 DWORDnNumberOfBytesToRead,//輸入數(shù)據(jù)塊大小 LPDWORD lpNumberOfBytesRead, //返回的字節(jié)數(shù)長(zhǎng)度指針 NULL ) //同步時(shí)為NULLWriteFile( HANDLE hFile, //設(shè)備句柄 LPVOID lpBuffer, //輸出數(shù)據(jù)塊指針 DWORDnNumberOfBytesToWrite,//輸出數(shù)據(jù)塊大小 LPDWORD lpNumberOfBytesWritten,
//實(shí)際輸出的字節(jié)數(shù)長(zhǎng)度指針 NULL ) //同步時(shí)為NULL第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)4.ReadFile和WriteFile函數(shù)第11章Wi34 本節(jié)以Aedk-LabPCI計(jì)算機(jī)接口實(shí)驗(yàn)儀為例,介紹WDM驅(qū)動(dòng)程序的使用。 該實(shí)驗(yàn)設(shè)備由一塊PCI接口卡和一臺(tái)接口實(shí)驗(yàn)儀組成,將PCI接口卡插入PC機(jī)的PCI總線插槽,用連接線把PCI卡和實(shí)驗(yàn)機(jī)相連接,整個(gè)實(shí)驗(yàn)儀就成為PC機(jī)的一臺(tái)“外部設(shè)備”。在監(jiān)控軟件的控制下,進(jìn)行PC機(jī)與實(shí)驗(yàn)儀的通訊,實(shí)現(xiàn)對(duì)實(shí)驗(yàn)過(guò)程的全程控制。 PCI卡采用了PLX公司的PCI9052芯片作為接口芯片。11.3.2Windows2000/XP下輸入輸出舉例第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 本節(jié)以Aedk-LabPCI計(jì)算機(jī)接口實(shí)驗(yàn)儀為例35 進(jìn)行硬件連接之后,需要安裝驅(qū)動(dòng)程序,在Win2000中也就是安裝WDM驅(qū)動(dòng)程序。 在實(shí)驗(yàn)設(shè)備所附帶的軟件中,驅(qū)動(dòng)程序文件有兩個(gè):INF文件,稱(chēng)為設(shè)備信息文件,供驅(qū)動(dòng)程序安裝時(shí)使用。INF文件指明了硬件驅(qū)動(dòng)該如何安裝到系統(tǒng)中,源文件在哪里、安裝到哪一個(gè)文件夾中、怎樣在注冊(cè)表中加入與設(shè)備有關(guān)的信息等;后綴為sys的文件,是整個(gè)實(shí)驗(yàn)儀的驅(qū)動(dòng)程序。一般情況下,INF文件會(huì)被復(fù)制到Windows2000系統(tǒng)目錄中的INF子目錄中,Sys文件被復(fù)制到System32/drivers子目錄中。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 進(jìn)行硬件連接之后,需要安裝驅(qū)動(dòng)程序,在Win2036安裝驅(qū)動(dòng)程序后,在設(shè)備管理器中可以看到相應(yīng)的設(shè)備第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)安裝驅(qū)動(dòng)程序后,在設(shè)備管理器中可以看到相應(yīng)的設(shè)備第11章Wi37//設(shè)備的頭文件//8255Demo.h//控制碼#defineIOCTL_PCI_CON //讀配置信息 CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)#defineIOCTL_IO_READ //IO讀 CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)#defineIOCTL_IO_WRITE //IO寫(xiě) CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,METHOD_BUFFERED,FILE_ANY_ACCESS)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)//設(shè)備的頭文件第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)38//設(shè)備的頭文件//PCI卡配置信息structpci_cfg{ ULONG MemBase[2]; //內(nèi)存基地址 ULONG MemLength[2]; //內(nèi)存大小 ULONG IOBase[2]; //IO基地址 ULONG IOPortLength[2]; //IO基長(zhǎng)度 ULONG IRQ; //中斷號(hào)}; //數(shù)據(jù)緩沖區(qū)structBuffers{ ULONG Address; UCHAR Data;};第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)//設(shè)備的頭文件第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)39三個(gè)控制碼800H、801H和802H分別對(duì)應(yīng)于讀配置信息、IO讀和IO寫(xiě)。pci_cfg是PCI配置信息的格式,下面的示例程序只用到了IOBase[2]數(shù)組,其中可以存放該P(yáng)CI設(shè)備申請(qǐng)獲得的三處IO空間的首地址。Buffers是應(yīng)用程序和驅(qū)動(dòng)程序交換數(shù)據(jù)的緩沖區(qū)格式。Buffers有兩個(gè)域,地址域名為Address,由用戶(hù)程序向驅(qū)動(dòng)程序傳遞需要讀寫(xiě)的IO端口地址,另一個(gè)是數(shù)據(jù)域Data,讀操作時(shí)由驅(qū)動(dòng)程序?qū)⒆x到的數(shù)據(jù)通過(guò)它傳遞給用戶(hù)程序,寫(xiě)操作時(shí)由用戶(hù)程序?qū)⑿枰敵龅臄?shù)據(jù)通過(guò)它傳遞給驅(qū)動(dòng)程序。需要注意的是,控制碼以及輸入、輸出緩沖區(qū)的具體格式由驅(qū)動(dòng)程序自行規(guī)定,操作系統(tǒng)對(duì)此不予干涉。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)三個(gè)控制碼800H、801H和802H分別對(duì)應(yīng)于讀配置信息40 8255A的PA口接8路開(kāi)關(guān)的輸入,PB口輸出,接8個(gè)發(fā)光二極管。 程序的功能是將PA輸入的開(kāi)關(guān)量,向PB口輸出,用8個(gè)開(kāi)關(guān)分別控制8個(gè)發(fā)光二極管。 輸入全零時(shí),程序結(jié)束運(yùn)行。使用實(shí)驗(yàn)儀8255A芯片進(jìn)行開(kāi)關(guān)量輸入輸出第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 8255A的PA口接8路開(kāi)關(guān)的輸入,PB口輸出,接8個(gè)發(fā)41 下面的示例程序中,"\\\\.\\PCI9052Device0"是設(shè)備名,只要安裝了設(shè)備驅(qū)動(dòng)程序,系統(tǒng)就可認(rèn)出該設(shè)備名。 除了主函數(shù),示例程序還包含了四個(gè)子函數(shù)。
OpenDevice函數(shù)打開(kāi)設(shè)備,如果成功則返回設(shè)備句柄,失敗則程序結(jié)束。
GetPCIConfig函數(shù)讀取設(shè)備的配置信息,如果不成功,程序也要結(jié)束。
ReadIO和WriteIO是對(duì)IO端口的讀、寫(xiě)函數(shù)。
上面三個(gè)子函數(shù)都通過(guò)調(diào)用API函數(shù)DeviceIoControl()實(shí)現(xiàn)他們各自的功能,區(qū)別主要在于使用了不同的控制代碼。使用實(shí)驗(yàn)儀8255A芯片進(jìn)行開(kāi)關(guān)量輸入輸出第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 下面的示例程序中,"\\\\.\\PCI9052Devi42示例程序函數(shù)關(guān)系第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)示例程序函數(shù)關(guān)系第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)43 主函數(shù)首先打開(kāi)設(shè)備,讀取PCI卡的配置信息。實(shí)驗(yàn)設(shè)備中8255的片選端連接在譯碼器的最低端,因此,PCI卡的IO基地址就是8255的PA口地址,依次是PB口的地址、PC口的地址和控制口的地址。 用戶(hù)編寫(xiě)的ReadIO函數(shù)調(diào)用DeviceIoControl函數(shù)時(shí),輸入和輸出緩沖區(qū)使用同一個(gè)緩沖區(qū)buf。端口地址是輸入?yún)?shù),調(diào)用之前預(yù)先置入輸入緩沖區(qū)buf的Address字段。讀操作獲得的數(shù)據(jù)是輸出參數(shù),調(diào)用完成后從buf的Data字段中取得。 主函數(shù)從PA口讀入數(shù)據(jù),然后向PB口輸出,這樣就可以用8個(gè)開(kāi)關(guān)來(lái)分別控制8個(gè)發(fā)光二極管。讀入數(shù)據(jù)data為零時(shí),程序結(jié)束。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 主函數(shù)首先打開(kāi)設(shè)備,讀取PCI卡的配置信息。實(shí)驗(yàn)設(shè)備中844//8255IO讀寫(xiě)演示程序,Demo.c#include"8255Demo.h"char*sLinkName="\\\\.\\PCI9052Device0";structpci_cfgpci;structBuffersbuf;HANDLEOpenDevice(){ HANDLEhDevice; hDevice=CreateFile( sLinkName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)//8255IO讀寫(xiě)演示程序,Demo.c第11章Windo45 if(hDevice==INVALID_HANDLE_VALUE) { printf("請(qǐng)檢查PCI卡和驅(qū)動(dòng)程序\n"); exit; } returnhDevice;}第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) if(hDevice==INVALID_HAND46voidGetPCIConfig(HANDLEhDevice){ BOOLstatus; DWORDrc; status=DeviceIoControl(hDevice,IOCTL_PCI_CON, NULL,0,&pci,sizeof(pci_cfg),&rc,NULL); //調(diào)用DeviceIoControl函數(shù); //獲取PCI設(shè)備配置 if(!status){ printf("無(wú)法獲取pci配置信息\n"); exit; } return;}第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)voidGetPCIConfig(HANDLEh47 if(hDevice==INVALID_HANDLE_VALUE) { printf("請(qǐng)檢查PCI卡和驅(qū)動(dòng)程序\n"); exit; } returnhDevice;}第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) if(hDevice==INVALID_HAND48 voidWriteIO(WORDport,BYTEdata){ BOOLstatus; DWORDrc; buf->Address=port; //端口地址寫(xiě)入IO緩沖區(qū) buf->Data=data; //輸出數(shù)據(jù)寫(xiě)入IO緩沖區(qū) status=DeviceIoControl(hDevice, IOCTL_IO_WRITE,&buf, sizeof(Buffers),NULL,0,&rc,NULL); //調(diào)用DeviceIoControl函數(shù) //向設(shè)備進(jìn)行輸出 if(!status)printf("無(wú)法寫(xiě)入\n");}第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) voidWriteIO(WORDport,BYTE49 UCHARReadIO(WORDport){ DWORDrc; BOOLstatus buf->Address=port;//將端口地址寫(xiě)入IO緩沖區(qū) status=DeviceIoControl(hDevice,IOCTL_IO_READ,
&buf,sizeof(Buffers),&buf,sizeof(Buffers), &rc,NULL); //調(diào)用DeviceIoControl函數(shù) //從設(shè)備輸入 if(!status)printf("無(wú)法讀出\n"); returnbuf->Data;}第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) UCHARReadIO(WORDport)第11章W50 voidmain(){ HANDLE hDevice; WORD 8255PAaddr,8255PBaddr,8255ConAddr; UCHAR data; hDevice=OpenDevice(); //打開(kāi)設(shè)備 GetPCIConfig(hDevice); //讀取配置信息 8255PAaddr=pci.IOBase[1] //取得PA口地址 8255PBaddr=pci.IOBase[1]+1; //取得PB口地址 8255ConAddr=pci.IOBase[1]+3; //取得控制口地址 WriteIO(8255ConAddr,0x90); //寫(xiě)控制字90h,方式0,PA口讀,PB口寫(xiě)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) voidmain()第11章Windows環(huán)境下輸入輸出51
do{ data=ReadIO(8255PAaddr); //從PA口讀取數(shù)據(jù) WriteIO(8255PBaddr,data); //將數(shù)據(jù)寫(xiě)入PB口 }while(data); //數(shù)據(jù)不為0繼續(xù)
CloseHandle(hDevice); //關(guān)閉設(shè)備 return;} 第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)52演講完畢,謝謝聽(tīng)講!再見(jiàn),seeyouagain3rew2022/12/17第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)演講完畢,謝謝聽(tīng)講!再見(jiàn),seeyouagain3rew53第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)2022/12/17第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)2022/12/54Windows是一個(gè)多任務(wù)操作系統(tǒng),在保護(hù)模式下工作。Windows操作系統(tǒng)不支持用戶(hù)程序?qū)τ?jì)算機(jī)底層硬件進(jìn)行直接控制。用戶(hù)程序需要輸入/輸出時(shí),可以通過(guò)通過(guò)API(ApplicationProgramInterface,應(yīng)用程序接口)來(lái)調(diào)用設(shè)備驅(qū)動(dòng)程序,對(duì)設(shè)備實(shí)現(xiàn)間接控制,進(jìn)行輸入/輸出。Windows9x使用VxDs(VirtualDeviceDriver’s,虛擬設(shè)備驅(qū)動(dòng))設(shè)備驅(qū)動(dòng)程序。Windows2000/XP使用WDM(WindowsDriverModel,Windows驅(qū)動(dòng)程序模型)設(shè)備驅(qū)動(dòng)程序。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)Windows是一個(gè)多任務(wù)操作系統(tǒng),在保護(hù)模式下工作。第115511.1Windows設(shè)備驅(qū)動(dòng)程序
11.1.1虛擬設(shè)備 在多任務(wù)運(yùn)行環(huán)境下,計(jì)算機(jī)內(nèi)的硬件、軟件資源為多個(gè)任務(wù)共享。任何一個(gè)用戶(hù)程序都不能獨(dú)占系統(tǒng)的硬件、軟件資源。虛擬設(shè)備實(shí)質(zhì)上是真實(shí)物理設(shè)備的部分資源和相關(guān)軟件的組合,用來(lái)完成用戶(hù)程序需要的功能。虛擬設(shè)備不但可以代表實(shí)際存在的硬件設(shè)備,還可以模擬實(shí)際上不存在的“設(shè)備”,供用戶(hù)使用。計(jì)算機(jī)上的“虛擬光驅(qū)”就是一個(gè)典型的虛擬設(shè)備。與這個(gè)設(shè)備同名的物理設(shè)備是不存在的,用戶(hù)使用的是硬盤(pán)的部分存儲(chǔ)空間以及相應(yīng)的服務(wù)程序。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.1Windows設(shè)備驅(qū)動(dòng)程序11.1.156使用虛擬設(shè)備好處:實(shí)現(xiàn)多任務(wù)對(duì)系統(tǒng)資源的共享,方便用戶(hù)的使用;實(shí)現(xiàn)任務(wù)與任務(wù)、任務(wù)與系統(tǒng)之間的隔離和保護(hù);規(guī)范外部設(shè)備輸入、輸出方法,使不同工作方式的設(shè)備用相同的方式進(jìn)行輸入輸出。對(duì)Windows應(yīng)用程序來(lái)講,虛擬設(shè)備就是真實(shí)設(shè)備,應(yīng)用程序分不清那個(gè)設(shè)備是由真實(shí)硬件支持的真實(shí)設(shè)備,那個(gè)設(shè)備是由虛擬設(shè)備驅(qū)動(dòng)程序模擬的虛擬設(shè)備。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)使用虛擬設(shè)備好處:第11章Windows環(huán)境下輸入輸出程序設(shè)5711.1.2
Windows9X設(shè)備驅(qū)動(dòng)程序Windows9x是一個(gè)分層結(jié)構(gòu)的操作系統(tǒng),由工作在兩個(gè)不同層面的組件構(gòu)成:頂層組件,工作在Ring3層;底層組件,工作在Ring0層。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.1.2Windows9X設(shè)備驅(qū)動(dòng)程序58頂層:Windows9x操作系統(tǒng)的頂層組件工作在特權(quán)級(jí)3,稱(chēng)為ring3層。它給應(yīng)用程序的運(yùn)行提供Win32API服務(wù)。Windows9x應(yīng)用程序和Win32API服務(wù)一起構(gòu)成操作系統(tǒng)的頂層,稱(chēng)為系統(tǒng)虛擬機(jī)(VM,VirtualMachine)。對(duì)于一個(gè)任務(wù)來(lái)說(shuō),這些服務(wù)程序以及他們所掌控的硬件資源就是一臺(tái)“實(shí)實(shí)在在”的計(jì)算機(jī)。但是,對(duì)于整個(gè)系統(tǒng)來(lái)說(shuō),他們只是由操作系統(tǒng)向用戶(hù)提供的一個(gè)運(yùn)行用戶(hù)程序的平臺(tái),包括為這個(gè)應(yīng)用程序服務(wù)的操作系統(tǒng)組件和部分的硬件資源。每一個(gè)DOS應(yīng)用程序都在一個(gè)獨(dú)立的虛擬機(jī)中運(yùn)行,操作系統(tǒng)允許多個(gè)虛擬機(jī)同時(shí)處于運(yùn)行狀態(tài)。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)頂層:第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)59底層:Windows9x操作系統(tǒng)的底層組件工作在0特權(quán)級(jí),稱(chēng)為ring0層,它就是虛擬機(jī)管理器(VMM,VirtualMachineManager)。Windows9x虛擬機(jī)管理器由一個(gè)內(nèi)核服務(wù)集和許多虛擬設(shè)備驅(qū)動(dòng)程序(VxDs,VirtualDeviceDriver’s)組成。許多VxDs是由Microsoft公司隨操作系統(tǒng)提供的,如鍵盤(pán)和顯示器等的VxDs,有的VxD則由設(shè)備制造商提供,或者由用戶(hù)自行編寫(xiě)。VxD用來(lái)支持特定的硬件或軟件,完成需要的功能。VxDs中的程序運(yùn)行在ring0層,可以執(zhí)行所有的指令,完成所需的任何軟硬件的操作。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)底層:第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)60 對(duì)于應(yīng)用程序而言,虛擬機(jī)管理器是透明的,應(yīng)用程序感覺(jué)不到管理器的存在。 微軟已經(jīng)宣布,從2006年6月起不再提供對(duì)Windows9x的技術(shù)支持。因此,Windows9x和VxDs的使用將逐漸減少。隨著Windows2000/XP的廣泛使用,WDM驅(qū)動(dòng)程序的開(kāi)發(fā)和使用已成為主流。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 對(duì)于應(yīng)用程序而言,虛擬機(jī)管理器是透明的,應(yīng)用程序感覺(jué)不到6111.1.3
Windows2000/XP設(shè)備驅(qū)動(dòng)程序Windows2000操作系統(tǒng)組件的層次結(jié)構(gòu) Windows2000操作系統(tǒng)的功能模塊劃分為用戶(hù)模式和內(nèi)核模式兩大類(lèi)。用戶(hù)模式的操作系統(tǒng)功能模塊工作在ring3層,他們不能使用CPU中的特權(quán)指令,連同IN、OUT這樣的非特權(quán)指令也被禁止。所有的用戶(hù)程序都在這一層上運(yùn)行。內(nèi)核模式的操作系統(tǒng)模塊工作在ring0層,可以使用CPU的任何指令。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.1.3Windows2000/XP設(shè)備驅(qū)動(dòng)程序Wi62Windows2000操作系統(tǒng)的層次結(jié)構(gòu)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)Windows2000操作系統(tǒng)的層次結(jié)構(gòu)第11章Windo632.Windows2000的設(shè)備驅(qū)動(dòng)程序Windows2000的驅(qū)動(dòng)程序也有兩種不同的類(lèi)型。
用戶(hù)模式驅(qū)動(dòng)程序工作在用戶(hù)模式,通過(guò)調(diào)用內(nèi)核模式驅(qū)動(dòng)程序?qū)崿F(xiàn)指定的功能。用戶(hù)模式驅(qū)動(dòng)程序不能直接對(duì)硬件設(shè)備進(jìn)行訪問(wèn),僅僅用于構(gòu)建一個(gè)硬件或軟件的運(yùn)行環(huán)境。
Windows內(nèi)核驅(qū)動(dòng)程序工作在內(nèi)核模式,可以直接訪問(wèn)硬件設(shè)備。每個(gè)設(shè)備驅(qū)動(dòng)程序都有一組完成各種功能的函數(shù),通過(guò)調(diào)用這些函數(shù)可以對(duì)某一設(shè)備完成特定的操作。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)2.Windows2000的設(shè)備驅(qū)動(dòng)程序第11章Wi64內(nèi)核模式驅(qū)動(dòng)程序的類(lèi)型文件系統(tǒng)驅(qū)動(dòng)程序可以在本地硬盤(pán)、網(wǎng)絡(luò)、移動(dòng)存儲(chǔ)設(shè)備或各種有存儲(chǔ)能力的硬件設(shè)備實(shí)現(xiàn)標(biāo)準(zhǔn)的文件系統(tǒng),如FAT32、NTFS系統(tǒng)等。PnP驅(qū)動(dòng)程序是一種遵循Windows2000即插即用協(xié)議的內(nèi)核模式驅(qū)動(dòng)程序。WDM驅(qū)動(dòng)程序是一種PnP驅(qū)動(dòng)程序。它同時(shí)還遵守電源管理協(xié)議。顯示驅(qū)動(dòng)程序是一種特殊的內(nèi)核驅(qū)動(dòng)程序。此類(lèi)的驅(qū)動(dòng)程序還有打印驅(qū)動(dòng)程序、多媒體驅(qū)動(dòng)程序、網(wǎng)絡(luò)驅(qū)動(dòng)程序等。遺留設(shè)備驅(qū)動(dòng)程序主要用在WindowsNT系統(tǒng)中,它也可以運(yùn)行在Windows2000系統(tǒng)中。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)內(nèi)核模式驅(qū)動(dòng)程序的類(lèi)型第11章Windows環(huán)境下輸入輸出程65Windows2000內(nèi)核模式驅(qū)動(dòng)程序的類(lèi)型第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)Windows2000內(nèi)核模式驅(qū)動(dòng)程序的類(lèi)型第11章Win6611.2WDM驅(qū)動(dòng)程序
WDM是Microsoft力推的新型驅(qū)動(dòng)程序模型,首先出現(xiàn)在WindowsNT中,現(xiàn)在的Windows98/Me/2000/XP都支持WDM。微軟宣稱(chēng),在后續(xù)的操作系統(tǒng)中將繼續(xù)支持WDM。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.2WDM驅(qū)動(dòng)程序WDM是Mi67WDM是一個(gè)分層的驅(qū)動(dòng)程序。它至少有功能驅(qū)動(dòng)程序(Functiondriver)和總線驅(qū)動(dòng)程序(Busdriver)兩個(gè)層面。功能驅(qū)動(dòng)程序提供一個(gè)設(shè)備的使用功能,或者可以認(rèn)為它就是一個(gè)設(shè)備的驅(qū)動(dòng)程序。用戶(hù)程序需要使用該設(shè)備時(shí),需要調(diào)用功能驅(qū)動(dòng)程序中的功能函數(shù)??偩€驅(qū)動(dòng)程序負(fù)責(zé)系統(tǒng)啟動(dòng)時(shí)設(shè)備的安裝、檢測(cè),并確定設(shè)備的資源使用情況。設(shè)備的啟動(dòng)、停止,設(shè)備的初始化,設(shè)備的電源管理等功能也都由總線驅(qū)動(dòng)程序提供。11.2.1WDM驅(qū)動(dòng)程序模型和層次結(jié)構(gòu)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)WDM是一個(gè)分層的驅(qū)動(dòng)程序。它68 WDM引入了
功能設(shè)備對(duì)象FDO(FunctionalDeviceObject)
物理設(shè)備對(duì)象PDO(PhysicalDeviceObject)
兩個(gè)新概念來(lái)描述硬件。一個(gè)PDO對(duì)應(yīng)一個(gè)真實(shí)硬件。一個(gè)硬件只允許有一個(gè)PDO,卻可以擁有多個(gè)FDO,在驅(qū)動(dòng)程序中直接操作的不是硬件而是相應(yīng)的PDO與FDO。根據(jù)具體的需要還可以選擇過(guò)濾驅(qū)動(dòng)程序(filterdriver)。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) WDM引入了
功能設(shè)備對(duì)象FDO(FunctionalDe69Windows20000的輸入輸出是包驅(qū)動(dòng)的應(yīng)用程序調(diào)用WDM驅(qū)動(dòng)程序時(shí),系統(tǒng)為每一個(gè)用戶(hù)的請(qǐng)求打包,形成一個(gè)I/O請(qǐng)求包(I/ORequestPackage,IRP),然后將其發(fā)送至驅(qū)動(dòng)程序。IRP中的PDO字段用來(lái)區(qū)別是發(fā)送給哪一個(gè)設(shè)備的。某個(gè)層次的驅(qū)動(dòng)程序得到IRP后,分析其中的請(qǐng)求,完成本層應(yīng)該完成的任務(wù)。如果IRP要求的任務(wù)已經(jīng)完成,該層次的驅(qū)動(dòng)程序就向上一層傳送結(jié)果并逐層返回。如果IRP中的請(qǐng)求尚未完成,那么就繼續(xù)向下層驅(qū)動(dòng)程序傳遞這個(gè)IRP。內(nèi)核組件就是這樣通過(guò)發(fā)送IRP來(lái)運(yùn)行驅(qū)動(dòng)程序中的代碼第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)Windows20000的輸入輸出是包驅(qū)動(dòng)的第11章Wind70WDM驅(qū)動(dòng)程序?qū)哟闻cI/O請(qǐng)求過(guò)程第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)WDM驅(qū)動(dòng)程序?qū)哟闻cI/O請(qǐng)求過(guò)程第11章Windows環(huán)7111.2.2
WDM驅(qū)動(dòng)程序開(kāi)發(fā)工具 目前有兩個(gè)主要的工具來(lái)開(kāi)發(fā)設(shè)備驅(qū)動(dòng)程序,一個(gè)是Microsoft公司提供的WindowsDDK。它有Windows98DDK、Windows2000DDK、WindowsXPDDK和Windows2003DDK四個(gè)版本,分別用來(lái)支持相應(yīng)的四個(gè)操作系統(tǒng)中VxD和WDM驅(qū)動(dòng)程序的開(kāi)發(fā)。 用WindowsDDK開(kāi)發(fā)驅(qū)動(dòng)程序難度較大。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.2.2WDM驅(qū)動(dòng)程序開(kāi)發(fā)工具 72另一個(gè)驅(qū)動(dòng)程序開(kāi)發(fā)工具是NuMega公司提供的DriverStudio,其中包含VtoolsD、DriversWorks、DriversNetWorks和SoftICE。VtoolsD用來(lái)開(kāi)發(fā)Windows98的VxD驅(qū)動(dòng)程序。DriversWorks和DriversNetWorks分別用來(lái)開(kāi)發(fā)一般設(shè)備和網(wǎng)絡(luò)設(shè)備的WDM驅(qū)動(dòng)程序。SoftICE是一個(gè)功能強(qiáng)大的調(diào)試工具。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)另一個(gè)驅(qū)動(dòng)程序開(kāi)發(fā)工具是NuMega公司提供的Dr73DriverStudio的開(kāi)發(fā)是建立在WindowsDDK的基礎(chǔ)上的,安裝DriverStudio時(shí),先要安裝WindowsDDK。DriverStudio將WindowsDDK的內(nèi)容封裝在一些基本的類(lèi)中,使用VC++編程。使用DriverStudio來(lái)開(kāi)發(fā)Windows的驅(qū)動(dòng)程序,相對(duì)WindowsDDK來(lái)講要容易得多。DriverStudio使用開(kāi)發(fā)向?qū)?,幫助你建立編?xiě)驅(qū)動(dòng)程序所需要的工程文件和程序框架文件,這些文件已經(jīng)組成了一個(gè)完整的設(shè)備驅(qū)動(dòng)程序。接下來(lái)的工作就是將這些文件導(dǎo)入到VC++的開(kāi)發(fā)環(huán)境中,添加具體的操作代碼,進(jìn)行進(jìn)一步的開(kāi)發(fā)。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)DriverStudio的開(kāi)發(fā)是建立在WindowsDDK7411.2.3
DriverStudio中的WDM驅(qū)動(dòng)程序結(jié)構(gòu)
從基本W(wǎng)DM啟動(dòng)程序的兩個(gè)頭文件中可以大致看清WDM驅(qū)動(dòng)程序的基本框架結(jié)構(gòu)。KDriver是WDM驅(qū)動(dòng)程序的基類(lèi),任何驅(qū)動(dòng)程序都要從繼承該類(lèi)開(kāi)始。SimpleWdmDriver驅(qū)動(dòng)程序從派生KDriver類(lèi)開(kāi)始。SimpleWdmDevice是KPnpDevice類(lèi)的派生類(lèi)。重載其某些成員函數(shù)便可處理相應(yīng)事件的發(fā)生。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.2.3DriverStudio中的WDM驅(qū)動(dòng)程序結(jié)75最重要的方法是virtualNTSTATUSDeviceControl(KIrpI),應(yīng)用程序中原本需要對(duì)硬件設(shè)備的I/O訪問(wèn)指令被移到了DeviceControl中。應(yīng)用程序需要訪問(wèn)硬件設(shè)備時(shí),可以使用DeviceIoControl函數(shù),最后DeviceIoControl會(huì)調(diào)用DeviceControl,從而完成對(duì)設(shè)備的I/O訪問(wèn)??梢哉f(shuō)DeviceControl就是功能驅(qū)動(dòng)程序。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)最重要的方法是virtualNTSTATUSDevice76//HelloWdm.h-includefileforbasicWDMdriverclassSimpleWdmDriver:publicKDriver{public:
//DriverEntry負(fù)責(zé)驅(qū)動(dòng)程序的初始化,必須重載 virtualNTSTATUS
DriverEntry(PUNICODE_STRINGRegistryPath);
//AddDevice初始化驅(qū)動(dòng)程序所控制的設(shè)備,必須重載virtualNTSTATUSAddDevice(PDEVICE_OBJECTPdo);
//Unload刪除由DriverEntry所分配的資源 virtualVOIDUnload(void);};第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)//HelloWdm.h-includefilef77//hellodev.h-includefilefordeviceclassofbasicdriverclassSimpleWdmDevice:publicKPnpDevice{public: SimpleWdmDevice(PDEVICE_OBJECTPdo,ULONGUnit);
//PlugandPlayhandlers NTSTATUSOnStartDevice(KIrpI); //設(shè)備啟動(dòng)時(shí)調(diào)用。 NTSTATUSOnStopDevice(KIrpI); //設(shè)備停止時(shí)調(diào)用。 NTSTATUSOnRemoveDevice(KIrpI);
//設(shè)備刪除時(shí)調(diào)用。
//UserControlhandlers
//設(shè)備打開(kāi)時(shí)調(diào)用,應(yīng)用程序使用Create函數(shù)時(shí)調(diào)用。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)//hellodev.h-includefilef78virtualNTSTATUSCreate(KIrpI); //設(shè)備關(guān)閉時(shí)調(diào)用,即應(yīng)用程序使用Create函數(shù)時(shí)調(diào)用。virtualNTSTATUSClose(KIrpI); //設(shè)備功能調(diào)用,應(yīng)用程序使用DeviceIoControl函數(shù)時(shí)被調(diào)用 virtualNTSTATUSDeviceControl(KIrpI); //PowerManagementhandlers NTSTATUSOnDevicePowerUp(KIrpI); // NTSTATUSOnDeviceSleep(KIrpI); //設(shè)備睡眠時(shí)調(diào)用 NTSTATUSOnSetPower(KIrpI); // NTSTATUSDefaultPnp(KIrpI); // NTSTATUSDefaultPower(KIrpI); };第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)virtualNTSTATUSCreate(KIrp7911.3Windows2000/XP下輸入
輸出的實(shí)現(xiàn)Windows是一個(gè)基于“消息傳遞”機(jī)制的多任務(wù)操作系統(tǒng)。用戶(hù)程序需要訪問(wèn)硬件設(shè)備時(shí),通過(guò)調(diào)用API函數(shù)調(diào)用該設(shè)備的驅(qū)動(dòng)程序。WIN32將用戶(hù)的請(qǐng)求組合成為一個(gè)IRP包,向內(nèi)核發(fā)送“消息”。 內(nèi)核組件根據(jù)IRP中的PDO字段,將該“消息”傳送給對(duì)應(yīng)的WDM驅(qū)動(dòng)程序。 驅(qū)動(dòng)程序完成硬件設(shè)備的訪問(wèn)后,向用戶(hù)程序返回結(jié)果。 調(diào)用驅(qū)動(dòng)程序的過(guò)程,就是用戶(hù)程序和驅(qū)動(dòng)程序之間傳遞消息,交換數(shù)據(jù),進(jìn)行通信的過(guò)程。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)11.3Windows2000/XP下輸入
80 用戶(hù)程序完成對(duì)設(shè)備的訪問(wèn)有兩種方式等待方式下,用戶(hù)程序調(diào)用驅(qū)動(dòng)程序,等待驅(qū)動(dòng)程序完成對(duì)硬件設(shè)備的訪問(wèn)。這種方式編程簡(jiǎn)單。異步方式下,應(yīng)用程序調(diào)用驅(qū)動(dòng)程序,啟動(dòng)了硬件設(shè)備后,直接返回進(jìn)行其它處理,并不等待輸入/輸出完成。硬件設(shè)備完成了數(shù)據(jù)輸入輸出后,由驅(qū)動(dòng)程序通知應(yīng)用程序進(jìn)行進(jìn)一步的處理。這時(shí),需要由驅(qū)動(dòng)程序發(fā)起和應(yīng)用程序的通信。這種方式下,要用到反調(diào)函數(shù)、Win32事件通知等方法。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 用戶(hù)程序完成對(duì)設(shè)備的訪問(wèn)有兩種方式第11章Windows環(huán)81CreateFile()函數(shù)用來(lái)打開(kāi)設(shè)備,獲取設(shè)備句柄;設(shè)備輸入輸出控制函數(shù)DeviceIoControl(),用來(lái)調(diào)用WDM驅(qū)動(dòng)程序執(zhí)行相應(yīng)的操作(包括設(shè)備的控制和數(shù)據(jù)的輸入,輸出);CloseHandle()函數(shù)用來(lái)關(guān)閉設(shè)備。也可以使用ReadFile()和WriteFile()函數(shù)進(jìn)行“標(biāo)準(zhǔn)”的輸入/輸出。11.3.1用于輸入/輸出的WIN32API函數(shù)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)CreateFile()函數(shù)用來(lái)打開(kāi)設(shè)備,獲取設(shè)備句柄;1821.打開(kāi)設(shè)備
CreateFile()函數(shù)用來(lái)打開(kāi)設(shè)備,獲取設(shè)備句柄,格式如下:HANDLECreateFile(“\\\\.\\SimpleWDMDevice”, //設(shè)備的符號(hào)鏈接名GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, //同步打開(kāi)設(shè)備N(xiāo)ULL );使用上述函數(shù)時(shí),除了設(shè)備名之外,不需要改變其它參數(shù)。這里假設(shè)設(shè)備的名字為SimpleWDMDevice。進(jìn)行打開(kāi)操作時(shí)首先搜索當(dāng)前目錄,然后搜索Windows系統(tǒng)目錄。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)1.打開(kāi)設(shè)備第11章Windows環(huán)境下輸入輸出程832.DeviceIoControl函數(shù)調(diào)用DeviceIoControl( HANDLE hDevice, //設(shè)備句柄 DWORD dwIoControlCode, //控制代碼 LPVOID lpInBuffer, //輸入數(shù)據(jù)塊指針 DWORD nInBufferSize,//輸入數(shù)據(jù)塊大小 LPVOID lpOutBuffer, //輸出數(shù)據(jù)塊指針 DWORD nOutBufferSize,//輸出數(shù)據(jù)塊大小 LPDWORD lpBytesReturned, //返回字節(jié)長(zhǎng)度指針 NULL //同步時(shí)為NULL )第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)2.DeviceIoControl函數(shù)調(diào)用第11章Wind84DeviceIoControl函數(shù)調(diào)用參數(shù)hDevice是由CreateFile函數(shù)獲取的設(shè)備句柄。dwIOControlCode是應(yīng)用程序向WDM驅(qū)動(dòng)程序發(fā)出的控制代碼。lpInBuffer和nInBufferSize是應(yīng)用程序向WDM驅(qū)動(dòng)程序傳送的I/O數(shù)據(jù)塊的地址及大小。lpOutBuffer、nOutBufferSize和lpBytesReturned是WDM驅(qū)動(dòng)程序返回給應(yīng)用程序的數(shù)據(jù)塊的地址、大小以及實(shí)際返回的字節(jié)數(shù)。輸入/輸出緩沖區(qū)的格式由驅(qū)動(dòng)程序自行規(guī)定。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)DeviceIoControl函數(shù)調(diào)用參數(shù)第11章W853.關(guān)閉設(shè)備 完成對(duì)設(shè)備的輸入、輸出控制后, 應(yīng)用程序調(diào)用CloseHandle(hDevice)關(guān)閉設(shè)備。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)3.關(guān)閉設(shè)備第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)864.ReadFile和WriteFile函數(shù)ReadFile( HANDLE hFile, //設(shè)備句柄 LPVOID lpBuffer, //輸入數(shù)據(jù)塊指針 DWORDnNumberOfBytesToRead,//輸入數(shù)據(jù)塊大小 LPDWORD lpNumberOfBytesRead, //返回的字節(jié)數(shù)長(zhǎng)度指針 NULL ) //同步時(shí)為NULLWriteFile( HANDLE hFile, //設(shè)備句柄 LPVOID lpBuffer, //輸出數(shù)據(jù)塊指針 DWORDnNumberOfBytesToWrite,//輸出數(shù)據(jù)塊大小 LPDWORD lpNumberOfBytesWritten,
//實(shí)際輸出的字節(jié)數(shù)長(zhǎng)度指針 NULL ) //同步時(shí)為NULL第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)4.ReadFile和WriteFile函數(shù)第11章Wi87 本節(jié)以Aedk-LabPCI計(jì)算機(jī)接口實(shí)驗(yàn)儀為例,介紹WDM驅(qū)動(dòng)程序的使用。 該實(shí)驗(yàn)設(shè)備由一塊PCI接口卡和一臺(tái)接口實(shí)驗(yàn)儀組成,將PCI接口卡插入PC機(jī)的PCI總線插槽,用連接線把PCI卡和實(shí)驗(yàn)機(jī)相連接,整個(gè)實(shí)驗(yàn)儀就成為PC機(jī)的一臺(tái)“外部設(shè)備”。在監(jiān)控軟件的控制下,進(jìn)行PC機(jī)與實(shí)驗(yàn)儀的通訊,實(shí)現(xiàn)對(duì)實(shí)驗(yàn)過(guò)程的全程控制。 PCI卡采用了PLX公司的PCI9052芯片作為接口芯片。11.3.2Windows2000/XP下輸入輸出舉例第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 本節(jié)以Aedk-LabPCI計(jì)算機(jī)接口實(shí)驗(yàn)儀為例88 進(jìn)行硬件連接之后,需要安裝驅(qū)動(dòng)程序,在Win2000中也就是安裝WDM驅(qū)動(dòng)程序。 在實(shí)驗(yàn)設(shè)備所附帶的軟件中,驅(qū)動(dòng)程序文件有兩個(gè):INF文件,稱(chēng)為設(shè)備信息文件,供驅(qū)動(dòng)程序安裝時(shí)使用。INF文件指明了硬件驅(qū)動(dòng)該如何安裝到系統(tǒng)中,源文件在哪里、安裝到哪一個(gè)文件夾中、怎樣在注冊(cè)表中加入與設(shè)備有關(guān)的信息等;后綴為sys的文件,是整個(gè)實(shí)驗(yàn)儀的驅(qū)動(dòng)程序。一般情況下,INF文件會(huì)被復(fù)制到Windows2000系統(tǒng)目錄中的INF子目錄中,Sys文件被復(fù)制到System32/drivers子目錄中。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 進(jìn)行硬件連接之后,需要安裝驅(qū)動(dòng)程序,在Win2089安裝驅(qū)動(dòng)程序后,在設(shè)備管理器中可以看到相應(yīng)的設(shè)備第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)安裝驅(qū)動(dòng)程序后,在設(shè)備管理器中可以看到相應(yīng)的設(shè)備第11章Wi90//設(shè)備的頭文件//8255Demo.h//控制碼#defineIOCTL_PCI_CON //讀配置信息 CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)#defineIOCTL_IO_READ //IO讀 CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)#defineIOCTL_IO_WRITE //IO寫(xiě) CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,METHOD_BUFFERED,FILE_ANY_ACCESS)第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)//設(shè)備的頭文件第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)91//設(shè)備的頭文件//PCI卡配置信息structpci_cfg{ ULONG MemBase[2]; //內(nèi)存基地址 ULONG MemLength[2]; //內(nèi)存大小 ULONG IOBase[2]; //IO基地址 ULONG IOPortLength[2]; //IO基長(zhǎng)度 ULONG IRQ; //中斷號(hào)}; //數(shù)據(jù)緩沖區(qū)structBuffers{ ULONG Address; UCHAR Data;};第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)//設(shè)備的頭文件第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)92三個(gè)控制碼800H、801H和802H分別對(duì)應(yīng)于讀配置信息、IO讀和IO寫(xiě)。pci_cfg是PCI配置信息的格式,下面的示例程序只用到了IOBase[2]數(shù)組,其中可以存放該P(yáng)CI設(shè)備申請(qǐng)獲得的三處IO空間的首地址。Buffers是應(yīng)用程序和驅(qū)動(dòng)程序交換數(shù)據(jù)的緩沖區(qū)格式。Buffers有兩個(gè)域,地址域名為Address,由用戶(hù)程序向驅(qū)動(dòng)程序傳遞需要讀寫(xiě)的IO端口地址,另一個(gè)是數(shù)據(jù)域Data,讀操作時(shí)由驅(qū)動(dòng)程序?qū)⒆x到的數(shù)據(jù)通過(guò)它傳遞給用戶(hù)程序,寫(xiě)操作時(shí)由用戶(hù)程序?qū)⑿枰敵龅臄?shù)據(jù)通過(guò)它傳遞給驅(qū)動(dòng)程序。需要注意的是,控制碼以及輸入、輸出緩沖區(qū)的具體格式由驅(qū)動(dòng)程序自行規(guī)定,操作系統(tǒng)對(duì)此不予干涉。第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)三個(gè)控制碼800H、801H和802H分別對(duì)應(yīng)于讀配置信息93 8255A的PA口接8路開(kāi)關(guān)的輸入,PB口輸出,接8個(gè)發(fā)光二極管。 程序的功能是將PA輸入的開(kāi)關(guān)量,向PB口輸出,用8個(gè)開(kāi)關(guān)分別控制8個(gè)發(fā)光二極管。 輸入全零時(shí),程序結(jié)束運(yùn)行。使用實(shí)驗(yàn)儀8255A芯片進(jìn)行開(kāi)關(guān)量輸入輸出第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 8255A的PA口接8路開(kāi)關(guān)的輸入,PB口輸出,接8個(gè)發(fā)94 下面的示例程序中,"\\\\.\\PCI9052Device0"是設(shè)備名,只要安裝了設(shè)備驅(qū)動(dòng)程序,系統(tǒng)就可認(rèn)出該設(shè)備名。 除了主函數(shù),示例程序還包含了四個(gè)子函數(shù)。
OpenDevice函數(shù)打開(kāi)設(shè)備,如果成功則返回設(shè)備句柄,失敗則程序結(jié)束。
GetPCIConfig函數(shù)讀取設(shè)備的配置信息,如果不成功,程序也要結(jié)束。
ReadIO和WriteIO是對(duì)IO端口的讀、寫(xiě)函數(shù)。
上面三個(gè)子函數(shù)都通過(guò)調(diào)用API函數(shù)DeviceIoControl()實(shí)現(xiàn)他們各自的功能,區(qū)別主要在于使用了不同的控制代碼。使用實(shí)驗(yàn)儀8255A芯片進(jìn)行開(kāi)關(guān)量輸入輸出第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì) 下面的示例程序中,"\\\\.\\PCI9052Devi95示例程序函數(shù)關(guān)系第11章Windows環(huán)境下輸入輸出程序設(shè)計(jì)示例程序
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年環(huán)保型土地平整工程服務(wù)合同3篇
- 2025年度大數(shù)據(jù)分析與應(yīng)用服務(wù)合同范本9篇
- 2025版汽車(chē)租賃居間服務(wù)合同2篇
- 2025版購(gòu)物卡預(yù)付卡發(fā)行與監(jiān)管服務(wù)合同3篇
- 2025年度城市巴士線路優(yōu)化升級(jí)合同3篇
- 2024年納米材料研發(fā)與許可合同
- 2024年版醫(yī)療設(shè)備購(gòu)買(mǎi)與維護(hù)合同
- 2024智能交通系統(tǒng)集成開(kāi)發(fā)合同
- 2024年精簡(jiǎn)版二手車(chē)買(mǎi)賣(mài)合同:清晰交易條款版B版
- 2024年門(mén)窗行業(yè)綠色施工與安裝勞務(wù)分包合同樣本3篇
- GB/T 5483-2024天然石膏
- 2024年度托管班二人合伙協(xié)議書(shū)3篇
- 山東中醫(yī)藥大學(xué)中西醫(yī)臨床(專(zhuān)升本)學(xué)士學(xué)位考試復(fù)習(xí)題
- 鄉(xiāng)村振興暨干部素質(zhì)提升培訓(xùn)班學(xué)習(xí)心得體會(huì)
- IATF16949:2024標(biāo)準(zhǔn)質(zhì)量手冊(cè)
- 飼料加工混凝土施工合同
- 會(huì)議會(huì)務(wù)服務(wù)投標(biāo)方案投標(biāo)文件(技術(shù)方案)
- 機(jī)械結(jié)構(gòu)工程師年終總結(jié)
- 成都大學(xué)《Python數(shù)據(jù)分析》2023-2024學(xué)年期末試卷
- 2024年醫(yī)院消毒隔離制度范文(六篇)
- 2024年國(guó)家開(kāi)放大學(xué)(電大)-行政管理(本科)考試近5年真題集錦(頻考類(lèi)試題)帶答案
評(píng)論
0/150
提交評(píng)論