驅動程序范例6篇

前言:中文期刊網精心挑選了驅動程序范文供你參考和學習,希望我們的參考范文能激發你的文章創作靈感,歡迎閱讀。

驅動程序范文1

由于工作關系,我經常涉及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表示此驅動程序手動載入,ErrorControl=1表示當驅動程序發生錯誤時,日志記錄錯誤并顯示一個消息框。這樣當Windows重新啟動后,通過使用控制面板中的Device小應用程序,從列表中找到IOCardA設備名,按Start按鈕,于是,設備驅動程序就駐留內存并在底層開始工作了。

第七,調試。設備驅動程序沒有界面,完全在系統底層運行,為了觀察驅動程序的運行狀態,WindowsNTDDK提供windbj.exe程序用于設備驅動程序的調試,調試設備驅動程序需要兩臺CPU體系結構完全相同的計算機,一臺為‘宿主機’,運行windbj.exe程序,另一臺為‘目標機’,運行設備驅動程序,兩臺計算機用串口線連好,進行一系列軟件設置(參見[1]第17章),就可以開始調試了,從‘宿主機’可以控制及觀察‘目標機’上驅動程序的運行情況。最常用的調試手段是在驅動程序中必要的位置加入DbgPrint()函數,這個函數可以把指定信息輸出到‘宿主機’windbg.exe窗口中,通過分析這些信息,可以了解驅動程序當前的運行情況。

結束語

WindowsNT是一個復雜而嚴密的系統,驅動程序的開發不可避免的涉及現代操作系統理論及其它許多計算機理論,內涵相當廣泛,本文圍繞著開發實踐從一定深度探討了WindowsNT設備驅動程序開發最基本的知識及一般方法,希望對讀者有所幫助,對于復雜,特殊應用的實現及編程技巧,有待于讀者在各自實際應用中不斷探索。

參考文獻

驅動程序范文2

鑒于設備驅動程序通知應用程序的重要性,本人結合一些經驗,對它進行了總結,歸納出5種方法:異步過程調用(APC)、事件方式(VxD)、消息方式、異步I/O方式和事件方式(WDM)。下面分別說明這幾種方式的原理,并給出實現的部分源代碼。

1異步過程調用(APC)

Win32應用程序使用CreateFile()函數動態加載設備驅動程序,然后定義一個回調函數backFunc(),并且將回調函數的地址&backFunc()作為參數,通過DeviceIoControl()傳送給設備驅動程序。設備驅動程序獲得回調函數的地址后,將它保存在一個全局變量(如callback)中,同時調用Get_Cur_Thread_Handle()函數獲取它的應用程序線程的句柄,并且將該句柄保存在一個全局變量(如appthread)中。當條件成熟時,設備驅動程序調用_VWIN32_QueueUserApc()函數,向Win32應用程序發送消息。這個函數帶有三個參數:第一個參數為回調函數的地址(已經注冊);第二個參數為傳遞給回調函數的消息;第三個參數為調用者的線程句柄(已經注冊)。Win32應用程序收到消息后,自動調用回調函數(實際是由設備驅動程序調用)。回調函數的輸入參數是由設備驅動程序填入的,回調函數在這里主要是對消息進行處理。

2事件方式(VxD)

首先,Win32應用程序創建一個事件的句柄,稱其為Ring3句柄。由于虛擬設備驅動程序使用事件的Ring0句柄,因此,需要創建Ring0句柄。用LoadLibrary()函數加載未公開的動態鏈接庫Kernel32.dll,獲得動態鏈接庫的句柄。然后,調用GetProcAddress(),找到函數OpenVxDHandle()在動態鏈接庫中的位置。接著,用OpenVxDHandle()函數將Ring3事件句柄轉化為Ring0事件句柄。Win32應用程序用CreateFile()函數加載設備驅動程序。如果加載成功,則調用DeviceIoControl()函數將Ring0事件句柄傳給VxD;同時,創建一個輔助線程等待信號變成有信號狀態,本身則可去干其它的事情。當條件成熟時,VxD置Ring0事件為有信號狀態(調用_VWIN32_SetWin32Event()函數),這馬上觸發對應的Ring3事件為有信號狀態。一旦Ring3事件句柄為有信號狀態,Win32應用程序的輔助線程就對這個消息進行相應的處理。

3消息方式

Win32應用程序調用CreateFile()函數動態加載虛擬設備驅動程序。加載成功后,通過調用DeviceIoControl()函數將窗體句柄傳送給VxD,VxD利用這個句柄向窗體發消息。當條件滿足時,VxD調用SHELL_PostMessage()函數向Win32應用程序發送消息。要讓該函數使用成功,必須用#define來自定義一個消息,并且也要照樣在應用程序中定義它;還要在消息循環中使用ON_MESSAGE()來定義消息對應的消息處理函數,以便消息產生時,能夠調用消息處理函數。SHELL_PostMessage()函數的第一個參數為Win32窗體句柄,第二個參數為消息ID號,第三、四個參數為發送給消息處理函數的參數,第五、六個參數為回調函數和傳給它的參數。Win32應用程序收到消息后,對消息進行處理。

4異步I/O方式

Win32應用程序首先調用CreateFile()函數加載設備驅動程序。在調用該函數時,將倒數第2個參數設置為FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,表示以后可以對文件進行重疊I/O操作。當設備驅動程序文件創建成功后,創建一個初始態為無信號、需要手動復位的事件,并且將這個事件傳給類型為OVERLAPPED的數據結構(如Overlapped)。然后,將Overlapped作為一個參數,傳給DeviceIoControl()函數。設備驅動程序把這個I/O請求包(IRP)設置為掛起狀態,并且設置一個取消例程。如果當前IRP隊列為空,則將這個IRP傳送給StartIo()例程;否則,將它放到IRP隊列中。設備驅動程序做完這些工作后,結束這個DeviceIoControl()的處理,于是Win32應用程序可能不等待IRP處理完,就從DeviceIoControl()的調用中返回。通過判斷返回值,得到IRP的處理情況。如果當前IRP處于掛起狀態,則主程序先做一些其它的工作,然后調用WaitForSingleObject()或WaitForMultipleObject()函數等待Overlapped中的事件成為有信號狀態。設備驅動程序在適當的時候處理排隊的IRP,處理完成后,調用IoCompleteRequest()函數。該函數將Overlapped中的事件設置為有信號狀態。Win32應用程序對這個事件馬上進行響應,退出等待狀態,并且將事件復位為無信號狀態,然后調用GetOverlappedResult()

函數獲取IRP的處理結果。

5事件方式(WDM)

Win32應用程序首先創建一個事件,然后將該事件句柄傳給設備驅動程序,接著創建一個輔助線程,等待事件的有信號狀態,自己則接著干其它事情。設備驅動程序獲得該事件的句柄后,將它轉換成能夠使用的事件指針,并且把它寄存起來,以便后面使用。當條件具備后,設備驅動程序將事件設置為有信號狀態,這樣應用程序的輔助線程馬上知道這個消息,于是進行相應的處理。當設備驅動程序不再使用這個事件時,應該解除該事件的指針。

驅動程序范文3

關鍵詞:電源管理; WDM; PCI; IRP

中圖分類號:TN302.7 文獻標識碼:A

文章編號:1004-373X(2010)14-0196-03

Driver Development of Power Management for PCI Device

CHENG Hai-quan1,2, HU Jun1, XU Shu-yan1, XIE Ai-ping3

(1. Space Optics Research Department, Changchun Institute of Optics, Fine Mechanics and Physics, Chinese Academy of Sciences, Changchun 130033, China;

2. Graduate School, Chinese Academy of Sciences, Beijing 100039, China;

3. College of Communication Engineering, Jilin University, Changchun 130032, China)

Abstract: The cooperation of operating system (OS) and driver is needed to control the power status of equipments for making PCI device to possess the function of power management. By the aid of the study on the power supply of systems and devices under Windows OS, a power management scheme is proposed to control the power status of equipments through processing system power IRP in WDM driver. WDM driver's mechanism of processing the power management IRP is elaborated. An experiment shows that WDM driver based on this scheme can work well with Windows XP.

Keywords: power management; WDM; PCI; IRP

0 引 言

隨著計算機軟硬件技術發展,要求設備能夠從待機或睡眠中快速啟動;要求在不使用時,移動設備能夠保持待機或休眠以節省電能的情況越來越多,傳統的冷啟動或熱啟動(復位啟動)已不能滿足人們的要求。微軟在Windows操作系統下設計了電源管理構架,為系統和設備的電源管理需求提供了廣泛的支持。目前Windows系統下的電源管理支持(advanced configuration and power interface ,ACPI) 高級配置和電源界面工業標準。

根據微軟的WDM驅動程序模型,很容易寫出具有一定功能的驅動程序,可是在設備運行了一段時間后,當系統要進入待機或休眠狀態時,就會發現桌面上彈出一個窗口――禁止待機。出現這種現象是由操作系統的默認電源管理策略所致,實際的原因在于驅動程序中沒有寫關于電源管理的代碼。本文中研究的WDM驅動就是為了使設備配合操作系統支持系統的待機和休眠。

1 系統和設備的電源策略

電源管理主要涉及操作系統和設備,系統電源狀態指示整個系統的總體電源使用,而設備電源狀態指示鞲霆設備使用多少能量。PCI設備支持的電源等級是由PCI配置空間中的電源管理能力結構描述的[1]。PCI總線電源管理接口規范描述了電源管理能力結構寄存器和電源管理事件信號以及輔助電源,這些寄存器和信號讓操作系統可以控制PCI總線以及總線上每個功能的電源[2]。

電源管理器管理著系統級的電源策略,設備電源策略主負責設備的電源策略,它們互相配合才能完成系統和設備的電源狀態轉換。

1.1 系統和設備電源狀態

Windows操作系統定義了6種系統狀態S0~S5,S0稱為工作狀態,S1~S4屬于睡眠狀態。S5是關閉狀態。設備按照ACPI規范定義了4種設備狀態D0~D3。在D0狀態中,設備處于全供電狀態。在D3狀態中,設備處于無供電(或最小限度的電流)狀態。中間的D1和D2狀態指出設備的2個不同睡眠狀態。Microsoft規定了不同類型設備的類專用的電源需求,該規范要求每個設備至少要支持D0和D3兩個狀態[3]。

1.2 電源狀態轉換

應用程序請求、系統活動/電池級別或用戶按下電源按鈕會導致電源狀態的改變,例如系統在響應待機(standby)命令過程中,電源管理器首先向每個驅動程序發送帶有IRP_MN_QUERY_POWER副功能碼的IRP_MJ_POWER請求以詢問設備能否接受即將到來的電源關閉請求。如果所有驅動程序都同意,電源管理器將發送第2個帶有IRP_MN_SET_POWER副功能碼的電源管理IRP(I/O reequest package),然后驅動程序把其設備置入低電源狀態以響應這個IRP[3-4]。

前文中驅動程序不能待機的原因,也就在這里,不符合電源管理要求的驅動程序否決了電源管理器發來的要求改變電源狀態IRP,導致系統不能待機。

1.3 PCI總線驅動程序與電源管理能力結構

總線驅動程序在電源管理中發揮著重要作用,甚至可以是電源策略主[5]。PCI電源管理能力結構為操作系統提供了一種標準機制來控制設備的功耗管理。對于某一個PCI設備來講,設備本身直接由PCI總線驅動程序管理[3]。總線驅動程序通過存取PCI電源管理能力結構的寄存器直接控制設備運行,達到物理上改變設備的電源狀態。

2 驅動程序設計過程

要使WDM驅動程序具有電源管理功能,首先需要在DriverEntry入口函數中注冊IRP_MJ_POWER IRP的派遣函數例程[6-7]。

pDriverObject->MajorFunction[IRP_MJ_POWER]= PowerDispatchRoutine;

驅動程序的電源管理例程圍繞電源IRP_MJ_POWER IRP進行處理,這些例程處理這個IRP,并在需要時產生這個IRP。這個IRP有4個電源管理次功能代碼,如表1所示。

表1 IRP_MJ_POWER次功能代碼

次功能IRP代碼描述

IRP_MN_QUERY_

POWER查詢系統或設備狀態變化是否可行

IRP_MN_SET_POWER設置系統或設備電源狀態

IRP_MN_WAIT_WAKE喚醒計算機,響應1個外部事件

IRP_MN_POWER_SEQUENCE發送這個IRP,確定設備是否真正進入特定的電源狀態

大多數驅動程序要求必須處理表1中前2個IRP,具有喚醒能力的設備驅動要處理IRP_MN_WAIT_WAKE。這里對IRP_MN_WAIT_WAKE和IRP_MN_POWER_SEQUENCE做默認處理。

NTSTATUS PowerDispatchRoutine(IN PDEVICE_OBJECT fdo, IN PIRP Irp) {

PAGED_CODE();

KdPrint(("Enter PowerDispatchRoutine\\n"));

NTSTATUS status = STATUS_SUCCESS;

switch(stack->MinorFunction) {

case IRP_MN_SET_POWER:

status = SetPowerState(fdo, Irp);

break;

case IRP_MN_QUERY_POWER:

status =QueryPowerState(fdo, Irp);

break;

case IRP_MN_WAIT_WAKE:

case IRP_MN_POWER_SEQUENCE:

default:

status = DispatchPowerDefault(fdo, Irp);

break;

}

return status;

}

電源管理器,維護一個單獨的電源IRP內部隊列,這保證在系統中只有一個“設置系統電源”IRP在處理,還保證每個設備只有一個“設置設備電源”IRP在運行[5]。

設備在完成一個電源IRP的處理時,必須告訴電源管理程序,使得它可以開始下一個電源IRP的處理。一般的默認處理就是簡單地把一個IRP沿設備棧向下傳遞(沒有完成例程),在跳過或復制當前IRP棧單元之前,應調用PoStartNextPowerIrp函數,如果使用完成例程,通常也必須調用PoStartNextPowerIrp。

NTSTATUS DispatchPowerDefault(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

PoStartNextPowerIrp(Irp);

IoSkipCurrentIrpStackLocation(Irp);

return PoCallDriver(pdx->LowerDeviceObject, Irp);

}

2.1 設備電源能力結構

PnP管理器在啟動設備后向設備發出查詢設備能力的請求,該請求的參數是一個DEVICE_CAPABILITIES結構,PCI總線驅動程序通常填充DEVICE_CAPABILITIES結構,該結構包含了與電源管理有關的幾個域。功能設備驅動程序應該首先向設備棧下轉發該IRP,等待IRP完成后,在必要時可以更改DEVICE_CAPABILITIES結構。

電源策略主負責檢查DEVICE_CAPABILITIES結構中的DeviceState域來確定每個系統電源狀態對應的設備電源狀態。這個結構中指出了對應于一個系統電源級設備可以處于的最高電源狀態。功能驅動程序可以在設備擴展中存儲這個結構中相關的域,在這個IRP完成以后,驅動程序不能改變它的內容[3]。

2.2 處理系統電源IRP

如果驅動程序收到一個“設置系統電源狀態”IRP,首先必須確定等效的設備電源狀態,如果當前設備電源狀態與要求的設備狀態不同,必須改變設備的狀態。通常總是把設備設置成與設備的當前活動、設備的電源能力以及系統的電源狀態相一致的最低電源狀態。

在向底層驅動程序傳遞“設置系統電源狀態”IRP之前改變設備狀態,在所有底層驅動程序處理后再給設備加電。必須給自己發出“設置設備電源狀態”IRP以改變設備電源狀態,然后等待這個IRP完成,然后可以繼續處理“設置系統電源狀態”IRP。以處理系統將要管理為例說明這個過程[4],如圖1所示。

圖1 降低系統電源IRP處理過程

2.3 處理設備電源IRP

如果收到“設置設備電源狀態”IRP,在調用低層驅動程序前,必須關閉設備的電源。在所有低層驅動程序啟動后,再啟動設備。這意味著應設置一個完成例程,并在那里給設備加電。這里以處理降低設備電源狀態為例[5]說明這個過程,如圖2所示。

圖2 降低設備電源IRP處理過程

2.4 實驗結果及分析

在Windows XP系統上加載采用這種電源管理方案的虛擬設備驅動程序,使系統從全功耗運行轉向休眠,再從休眠中恢復,用DebugView工具得到驅動打印的Log信息如下:

Enter HelloWDMPower

Power Manager query power state

Enter DispatchSystemPowerIrp

Enter CompletionSystemPowerRoutine

Send device power IRP according to system power IRP

Enter HelloWDMPower

Power Manager query power state

Enter DispatchDeviceQueryPower

Device power state query

newDeviceState = 4

Ready to pass down IRP for device power state query

Enter PowerDownPrepCallback

Enter DevicePowerCompleteCallback

Enter HelloWDMPower

System or device power is going to be change

Enter DispatchSystemPowerIrp

System power state change

newSystemState = 5

Enter CompletionSystemPowerRoutine

Send device power IRP according to system power IRP

Enter HelloWDMPower

System or device power is going to be change

Enter DispatchDeviceSetPower

Device power down

newDeviceState = 4

Ready to pass down IRP for device power state change

Enter PowerDownPrepCallback

Enter DevicePowerCompleteCallback

Enter HelloWDMPower

System or device power is going to be change

Enter DispatchSystemPowerIrp

System power state change

newSystemState = 1

Enter CompletionSystemPowerRoutine

Send device power IRP according to system power IRP

Enter HelloWDMPower

System or device power is going to be change

Enter DispatchDeviceSetPower

Device power up

newDeviceState = 1

Enter CompletionDevicePowerUp

Enter PowerUpCallback

Enter DevicePowerCompleteCallback

上述結果表明使用這種電源管理方案的驅動程序能和系統配合休眠,并能夠成功從休眠的狀態下啟動,另外具體應用到硬件上時要在說明的地方加上與設備相關的代碼。

3 結 語

本文介紹了PCI設備電源管理驅動程序的開發,電源管理在PCI規范中是可選的,現在PCI Express設備越來越多,而PCI Express設備必須實現電源管理能力。由于PCI Express與PCI軟件上兼容這里研究的電源管理方案同樣適用于PCI Express設備[8-10]。限于篇幅本文只給出了部分實現代碼,完整實例請參考WDK給出的toaster程序。

參考文獻

[1]PCI-SIG. PCI bus power management interface specification revision 1.2[EB/OL].[ 2004-03-03] . .

[2]李貴山,陳金鵬.PCI局部總線及其應用[M].西安:西安電子科技大學出版社,2003.

[3]Microsoft. Windows driver kit 7600[EB/OL].[ 2009-10-01] ..

[4]ONEY Walter. Programming the microsoft windows driver model[M]. US: Microsoft Press, 1999.

[5]Chris Cant.Windows WDM設備驅動程序開發指南[M].孫義,譯.北京:機械工業出版社,2000.

[6]PCI-SIG. PCI local bus specification v3.0[EB/OL].[ 2010-03-10] ..February 3,2004.

[7]張強.Compact PCl板卡硬件設計與傳輸速率測試[J].光學精密工程,2009,17(8):2049-2050.

[8]PCI-SIG. PCI.Express.Base.Specification.v1.1 [EB/OL].[ 2005-03-28] ..

驅動程序范文4

關鍵詞:TMS320DM642;DSP/BIOS;類/微型驅動模型;GIO;幀視頻模塊

中圖分類號:TP391 文獻標識碼:B 文章編號:1004373X(2008)1517404

Development of Video Port Driver Based on DSP/BIOS Device Driver Model

YAN Xinzhong,LIU Zhe

(School of Electronic Information and Automation,Tianjin University of Science & Technology,Tianjin,300222,China)

Abstract:This paper takes TMS320DM642 DSP for example and introduces a method of programming the device driver,which based on DSP/BIOS Class/Mini driver model.The Class/Mini driver model is divided into two layers.One is device-independent layer and the other is device-specific layer.This architecture makes it easier to program the device driver.The application uses class driver API to call the mini driver function indirectly in order to control the peripheral pared with the traditional software development,the driver development based on the two-layer device driver model improves efficiency and increases compatibility and portability.

Keywords:TMS320DM642;DSP/BIOS;class/mini driver model;GIO;frame video model

通過給外部設備編寫驅動程序是一種有效的控制外設的方法。隨著DSP的應用越來越廣泛,DSP實時系統的日趨復雜及新技術的出現,DSP處理器所連接的外部設備也是種類繁多,各不相同,而每一個外設都需要一個特定的驅動程序來支持外設的正常工作,這就要為每一個外設編寫驅動程序,這是一項十分繁雜的工作。如何能夠使系統開發人員從這些編寫繁雜的驅動程序工作中解脫出來,進而能夠專心投入到應用程序的開發中呢?TI公司提出了基于DSP/BIOS的設備驅動模型,該模型分為兩層:類驅動即與硬件不相關的層和微型驅動即與硬件相關的層。使用這種結構,應用程序只需調用類驅動的API函數,通過類驅動使用微型驅動,用微型驅動來控制外設。這種結構,將驅動程序合理分層,使得驅動程序模塊化,可移植性、復用性大大增強,縮短了驅動程序的開發時間。

1 DSP/BIOS設備驅動模型

1.1 類/微型驅動模型

DSP/BIOS是TI公司所設計開發的一個尺寸可裁剪的實時多任務操作系統內核,通過使用DSP/BIOS提供的豐富的內核服務,開發者能快速地創建滿足實時性能要求的精細復雜的多任務應用程序。為了使開發設備驅動更加簡單方便,提出了DSP/BIOS Device Driver Kit,定義了標準的設備驅動模型,一種將設備驅動分為與硬件無關和與硬件相關的雙層結構,這樣就使開發驅動程序不像以前那樣復雜了,為開發者提供了便利。這兩層結構稱為“類/微型驅動模型”[1],它們每一層都有各自通用的接口,所以相似設備驅動程序的主要部分可以復用,驅動代碼的移植成為可能,使開發驅動的過程大大簡化。

與硬件無關的層稱為類驅動(Class Driver),它處在應用程序與微型驅動之間,提供對多線程I/O請求的串行化和同步,并且維護設備數據緩沖區,向上提供API接口供應用程序調用,向下通過適配層與微型驅動相連,實現API接口函數到微型驅動層的映射。

與硬件相關的層稱為微型驅動(Mini-driver),它處在類驅動與芯片支持庫(Chip Support Library)之間,對于類驅動的接口是統一的,即每一個微型驅動都為類驅動和DSP/BIOS設備驅動管理提供了標準接口。微型驅動采用芯片支持庫(CSL)管理設備的寄存器、內存和中斷資源[2]。但由于硬件是千差萬別的,所以微型驅動對底層硬件的操作是根據硬件的不同而不同的。對于完成同樣功能的不同外設,只需稍加修改微型驅動,而不需重新編寫驅動程序,就可以實現驅動程序的移植與復用,使驅動程序的開發過程大大簡化。類/微型驅動模型結構如圖1所示。

1.2 類驅動

通過將應用軟件,驅動程序分層之后,可以看到,位于頂層的應用程序并不直接與微型驅動產生聯系,而是通過類驅動與微型驅動連接。每一種類驅動向上層應用程序提供一個API接口,并且與微型驅動接口進行通信。

DSP/BIOS定義了三種類驅動:流輸入輸出模塊(SIO),管道管理模塊(PIP),通用輸入輸出模塊(GIO)。其中,SIO和PIP分別需要使用適配器DIO和PIO來與微型驅動進行通信。SIO/DIO是基于流的I/O模型,使用異步方式來操作I/O,對于數據的讀寫、處理可以同時進行。PIP/PIO是基于管道的I/O模型,每個管道維護著一個被劃分為多個大小相同的幀的緩沖區。GIO類驅動采用基于流的同步I/O數據傳輸模式,適合大流量數據的傳輸,更適合文件系統。與SIO/DIO和PIP/PIO不同,GIO包含內置的IOM(I/O Manager輸入輸出管理)適配層,可以直接與微型驅動進行通信。

GIO模塊與其他兩個模塊相比,有一個很重要的特性,就是可以擴展API函數支持新的應用領域,這樣就實現了對GIO類驅動的擴展。這種可擴展API的特性正好可以用在視頻驅動開發方面。例如這種擴展可以滿足視頻設備存儲區的需要。另外,在提供了視頻驅動和應用程序之間的視頻數據同步機制之后,這種擴展也能夠允許使用一個單獨的調用來“交換”視頻緩沖區。這種交換緩沖區的機制對于實時視頻信號的采集與顯示是十分重要的。所以,在視頻驅動中,我們采用通用輸入輸出模塊GIO。應用程序可以直接地調用GIO API函數和IOM微型驅動程序進行交互,這些GIO API就可以看作是類驅動。GIO類驅動接口如圖

2所示。

GIOcreate會為一個特定的IOM通道實例創建一個GIO對象,這是類驅動使用微型驅動的第一步,首先創建對象及IOM通道,然后在此通道上進行數據傳輸工作。其結構體類型為GIOObj:

Typedef struct GIOObj{

IOMFxn *fxns;//指向IOM函數表fxn

Uns mode;//通道的使用模式 IOMINPUT IOM

OUTPUT IOMINOUT三種模式

Uns timeout;//模塊調用所用時間

IOMPacket syncPacket;//只用于同步操作的IOMPacket

QUEObj freeList;//用于異步操作,存放在類與微型驅動

之間使用的任何IOMPacket

Ptr syncObj;//同步對象的隱性指針

Ptr mdChan;//微型驅動通道對象指針

}GIOObj,*GIOHandle;

1.3 微型驅動

微型驅動主要通過一些函數來完成對外部設備的直接控制。只要微型驅動創建了規定的函數,應用程序就可以方便地通過DIO適配模塊、PIO適配模塊或(和)GIO類驅動調用[2]。

例如:GIOcreate被調用時,會運行mdCreateChan來創建一個通道。

這些微型驅動函數包括:mdBindDev/mdUBindDev(綁定/刪除通道函數):在程序建立接口時調用,完成設備的初始化硬件設備/在程序結束時調用,卸載設備。mdCreateChan/mdDeleteChan(創建/刪除通道):需要在應用程序與設備實例之間創建一個邏輯通信通道,用于交換驅動數據。應用程序可創建一個或多個邏輯通道,微型驅動用通道對象來代表這些通道。這兩個函數就是用來分配和釋放通道對象。mdSubmitChan(遞交I/O請求):該函數處理傳遞給它的IOMPacket結構體中的命令代碼(cmd),根據命令代碼,完成相應的處理或返回錯誤代碼。ISR(服務設備中斷并完成I/O操作):IOM微型驅動在中斷的ISR中將以處理完的IOMPacket請求出隊,啟動下一次傳輸或服務請求,調用類驅動的回調函數與應用程序進行同步,并返回出隊的IOMPacket。mdControlChan(控制設備):用來操作外部設備。

這些微型驅動的函數入口放在接口表(IOMFxns)中,供適配模塊或GIO類驅動調用。

2 TMS320DM642視頻驅動

下面以TMS320DM642芯片為例,介紹有關TMS320DM642視頻采集與顯示的驅動程序的開發。通過編寫驅動程序,完成視頻信號的實時采集與顯示功能。TMS320DM642是TI公司推出的一款專門用于視頻/圖像處理的定點數字信號處理器,它基于C64x內核,帶有3個可配置的視頻端口,與視頻采集芯片直接相連,無需外加邏輯電路或FIFO緩存,只需編寫相關解編碼芯片的驅動程序,就可以完成視頻信號的采集與顯示。在這里使用的解碼、編碼芯片分別為PHILIPS SAA7115和SAA7105。

2.1 視頻類驅動

在視頻驅動程序結構中,為了最大程度地提高視頻驅動代碼的復用性和通用性,將類驅動又劃分為兩層結構[3],其中上層為FVID模型,它是在DSP/BIOS GIO類驅動之上的簡單封裝,下層是GIO類驅動程序。GIO類驅動提供獨立的、一般的API函數集并且為微型驅動提供廣泛的服務,而上層的FVID模型向上層的視頻采集、顯示結構提供定制的API函數。

在視頻驅動中,主要是通過調用FVID模塊函數來完成類驅動代碼的編寫工作。FVID主要有以下幾個API函數:FVIDcreate:分配并初始化通道對象;FVIDcontrol:向微型驅動發送控制命令;FVIDalloc:向應用程序分配視頻端口緩沖區;FVIDexchange:交換緩沖區;FVIDfree:釋放緩沖區;FVIDdelete:刪除通道對象。

在配備視頻接口的設備驅動時,至少指定它要開設3個以上的視頻緩沖區(FVID模型中,默認分配3個緩沖區)[4],幀緩沖區通過FVIDalloc(),FVIDfree(),FVIDexchange()三個函數在應用程序與驅動之間交換。

2.2 視頻微型驅動

視頻微型驅動也分為兩層結構[3],上層為通用視頻端口層部分,下層為指定編解碼芯片微驅動層部分,它們通過外部設備控制接口(External Device Control,EDC)實現對芯片的操作。這種微驅動結構的好處是,當使用不同的芯片時,只需修改指定編解碼芯片微驅動那一部分,不需將整個微驅動重新編寫,使得驅動的復用性大大增強。

視頻驅動程序模型如圖3所示。

2.3 TMS320DM642視頻驅動設計步驟

2.3.1 注冊微型驅動

由于應用程序、類驅動最終都是要通過微型驅動的函數來完成對外部設備的直接控制,所以驅動程序設計的第一步就是要在DSP/BIOS Config中的Input/Output->Device Drivers->User-Defined Devices項目添加設備并注冊微驅動,進行屬性的設置[5],并指明IOMFxns函數表地址和設備參數地址,如圖4所示。

DSP/BIOS會在內部維護一個“設備表”,其中包含User-Defined Devices對象進行配置的設備實例。

2.3.2 編寫類驅動代碼

FVID函數會在設備表中查找已注冊的微驅動,并調用微驅動函數完成對外部設備的操作控制。

通常,首先利用FVIDcreate函數完成分配并初始化通道對象,返回值為設備實例句柄,這個句柄用于后續其他FVID函數調用這個已經創建的通道。然后調用FVIDcontrol函數向微型驅動發送控制命令,如配置編解碼器,發送開始采集或顯示圖像的控制命令。然后利用FVIDalloc分配緩沖區,接著應用程序將緩沖區的數據進行復制的搬移工作,當應用程序完成對緩沖區數據的采集后,調用FVIDexchange來交換緩沖區,保證視頻數據能夠實時地、源源不斷地供應用程序使用。

過程的流程圖如圖5所示。

下面是簡單的視頻采集顯示驅動的部分實現代碼:

FVIDHandle disChan;//定義顯示句柄

FVIDHandle capChan;//定義采集句柄

capChan = FVIDcreate("/VP0CAPTURE/A/0",

IOMINPUT,&status,(Ptr)&EVMDM642vCapParamsChan,NULL);//創建采集通道

disChan = FVIDcreate("/VP2DISPLAY",

IOMOUTPUT,&status,(Ptr)&EVMDM642vDisParamsChan,NULL);//創建顯示通道

FVIDcontrol(disChan,VPORTCMDEDCBASE + EDCCONFIG,

(Ptr)&EVMDM642vDisParamsSAA7105);

驅動程序范文5

2、點擊“打印服務器屬性”。

3、在“驅動程序”一欄下點擊“添加”。

4、此時會出現添加打印機驅動程序向導,點擊:下一步。

5、根據電腦的操作系統位數來選擇,然后點擊:下一步。

6、選擇要安裝的打印機驅動的制造商和型號,點擊:下一步。

驅動程序范文6

關鍵字 Windows系統 驅動程序 通知應用程序 設計 方法

中圖分類號: TP316 文獻標識碼:A

1 前言

操作系統的穩定性及可移植性是務必要優先確保的,為此Windows操作系統不支持應用程序直接訪問系統的硬件資源,而是必須借助于相應的設備驅動程序。設備驅動程序可以直接操作硬件,假如應用程序和設備驅動程序之間實現了雙向通信,也就達到了應用程序控制底層硬件設備的目的。

2 通知應用程序設計四種方法

鑒于設備驅動程序通知應用程序的重要性,本人結合一些經驗,對它進行了總結,歸納出5種方法摘要:異步過程調用(APC)、事件方式(VxD)、消息方式、異步I/O方式和事件方式(WDM)。下面分別說明這幾種方式的原理。

2.1 異步過程調用(APC)

Win32應用程序使用CreateFile()函數動態加載設備驅動程序,然后定義一個回調函數backFunc(),并且將回調函數的地址%26amp;backFunc()作為參數,通過DeviceIoControl()傳送給設備驅動程序。回調函數的輸入參數是由設備驅動程序填入的,回調函數在這里主要是對消息進行處理。

2.2 事件方式(VxD)

首先,Win32應用程序創建一個事件的句柄,稱其為Ring3句柄。由于虛擬設備驅動程序使用事件的Ring0句柄,因此,需要創建Ring0句柄。用LoadLibrary()函數加載未公開的動態鏈接庫Kernel32.dll,獲得動態鏈接庫的句柄。然后,調用GetProcAddress(), 找到函數OpenVxDHandle()在動態鏈接庫中的位置。接著,用OpenVxDHandle()函數將Ring3事件句柄轉化為Ring0事件句柄。Win32應用程序用CreateFile()函數加載設備驅動程序。

2.3 消息方式

Win32應用程序調用CreateFile()函數動態加載虛擬設備驅動程序。加載成功后,通過調用DeviceIoControl()函數將窗體句柄傳送給VxD,VxD利用這個句柄向窗體發消息。當條件滿足時,VxD調用SHELL_PostMessage()函數向Win32應用程序發送消息。SHELL_PostMessage()函數的第一個參數為Win32窗體句柄,第二個參數為消息ID號,第三、四個參數為發送給消息處理函數的參數,第五、六個參數為回調函數和傳給它的參數。Win32應用程序收到消息后,對消息進行處理。

2.4 事件方式(WDM)

Win32應用程序首先創建一個事件,然后將該事件句柄傳給設備驅動程序,接著創建一個輔助線程,等待事件的有信號狀態,自己則接著干其他事情。設備驅動程序獲得該事件的句柄后,將它轉換成能夠使用的事件指針,并且把它寄存起來,以便后面使用。

3 結語

在目前流行的Windows操作系統中,設備驅動程序是操縱硬件的最底層軟件接口。它向上提供和硬件無關的用戶接口,向下直接進行I/O、硬件中斷、DMA和內存訪問等操作。它將應用程序和硬件細節屏蔽開來,使軟件不依靠于硬件并且可在多個不同的平臺之間移植。這4種方法都經過實際測試。測試結果表明,它們都能夠達到設備驅動程序通知應用程序的目的。

參考文獻

[1] 李和平. 基于DSP的ICT圖像重建系統探究. 北京摘要: 北京航空航天大學機械工程及自動化學院, 2002

亚洲精品一二三区-久久