日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

对USB驱动程序的理解

發(fā)布時(shí)間:2025/3/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对USB驱动程序的理解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

對(duì)USB驅(qū)動(dòng)程序的理解

學(xué)了兩個(gè)多星期了,對(duì)USB驅(qū)動(dòng)程序的有一小小的理解。現(xiàn)在總結(jié)如下!!!!!!!!
1、每個(gè)設(shè)備對(duì)應(yīng)一個(gè)PDO,每個(gè)PDO又對(duì)應(yīng)多個(gè)FDO,在驅(qū)動(dòng)程序中直接操作的不是硬件而是相應(yīng)的PDO和FDO。在USER和KERNEL通信方面,系統(tǒng)將每一個(gè)用戶請(qǐng)求打包成IRP結(jié)構(gòu),將其發(fā)送至驅(qū)動(dòng)程序,并通過識(shí)別IRP中的PDO來區(qū)別是發(fā)送給哪個(gè)設(shè)備的。另外,在驅(qū)動(dòng)程序加載方面,WDM不通過驅(qū)動(dòng)程序名稱識(shí)別,而是通過一個(gè)128位的全局唯一的標(biāo)識(shí)符GUID來實(shí)現(xiàn)驅(qū)動(dòng)程序的識(shí)別,即每一個(gè)固件都有一個(gè)GUID,你通過GUID來區(qū)分是哪個(gè)固件。
2、USB主機(jī)驅(qū)動(dòng)符合WDM驅(qū)動(dòng)體系結(jié)構(gòu)也使用IRP(I/O請(qǐng)求包)的機(jī)制。但實(shí)際的USB驅(qū)動(dòng)程序使用URB(USB請(qǐng)求塊)結(jié)構(gòu)向其硬件設(shè)備發(fā)送請(qǐng)求。USB驅(qū)動(dòng)程序高度依賴其總線驅(qū)動(dòng)程序(USBD.SYS),而不直接使用硬件抽象層(HAL)函數(shù)與硬件通信。
3、USBD是USB系統(tǒng)軟件中最關(guān)鍵的一層,它負(fù)責(zé)控制全部USB協(xié)議的操作和中斷處理控制。主要功能有:設(shè)備設(shè)置、資源管理、數(shù)據(jù)傳輸(管道層次)以及公共數(shù)據(jù)定義等。管道機(jī)制和命令機(jī)制。管道機(jī)制:管道是設(shè)備和主機(jī)之間的邏輯連接,分為標(biāo)準(zhǔn)管道和邏輯管道,標(biāo)準(zhǔn)管道用語完成一些客戶通過命令接口所傳遞的請(qǐng)求,如設(shè)置設(shè)備的地址等,但USBD不允許客戶直接訪問設(shè)備的標(biāo)準(zhǔn)管道。客戶管道則有客戶進(jìn)行管理,并提供相應(yīng)的數(shù)據(jù)緩沖區(qū)。命令機(jī)制允許客戶以讀寫的方式對(duì)設(shè)備的數(shù)據(jù)及其控制部分進(jìn)行訪問,客戶所要做的,僅僅是向USBD提供設(shè)備的地址及相關(guān)的數(shù)據(jù)緩沖區(qū)的指針。命令機(jī)制所提供的功能主要是USB總線管理相關(guān)的內(nèi)容,如設(shè)備設(shè)置管理、設(shè)備數(shù)據(jù)訪問、總線設(shè)備管理以及電流分配等。
4、USB設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)
??? 2000DDK+VC6.0(只能用C,不能用C++)
??? 三個(gè)關(guān)鍵的例程:DriverEntry、AddDevice、ReadWrite
(1)DriverEntry,完成某些全局初始化操作,它是內(nèi)核模式驅(qū)動(dòng)程序主入口點(diǎn)。
extern "C"
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,
??????????????? IN PUNICODE_STRING RegistryPath )
通過PDRIVER_OBJECT這一重要的數(shù)據(jù)結(jié)構(gòu),I/O管理器使用它來定義每一個(gè)設(shè)備驅(qū)動(dòng)程序,DriverEntry主要工作是各種函數(shù)指針填入驅(qū)動(dòng)程序?qū)ο蟮母鱾€(gè)域中,這些指針為操作系統(tǒng)指明了驅(qū)動(dòng)程序容器中各種子例程,重要包括下面指針成員:
??? 1、DriverUnload
??? 2、DriverExtension->AddDevice指向驅(qū)動(dòng)程序的AddDevice函數(shù)
??? 3、DriverStartIo指向驅(qū)動(dòng)程序處理串行I/O請(qǐng)求的函數(shù)。如果驅(qū)動(dòng)程序采用標(biāo)準(zhǔn)的IRP排隊(duì)的方式,應(yīng)該設(shè)置該成員,使得指向驅(qū)動(dòng)程序的StartIo例程。
??? 4、MajorFunction是一個(gè)指針數(shù)組,指向存在于驅(qū)動(dòng)程序中的多種IRP處理函數(shù)。
??? DriverObject->DriverUnload = DriverUnload;
??? DriverObject->DriverExtension->AddDevice =AddDevice;
??? DriverObject->MajorFunction[IRP_MJ_CREATE]= DispatchCreate;
?~~~~~~~~~~~~~~
(2)AddDevice
?? 一個(gè)驅(qū)動(dòng)程序可以被多個(gè)設(shè)備使用。WDM驅(qū)動(dòng)程序有一個(gè)特殊的AddDevice函數(shù),PnP管理器為每個(gè)實(shí)例調(diào)用該函數(shù)。原形如下:
NTSTATUS
AddDevice( IN PDRIVER_OBJECT DriverObject,
??? IN PDEVICE_OBJECT PhysicalDeviceObject);
AddDevice函數(shù)的基本職責(zé)是創(chuàng)建一個(gè)設(shè)備對(duì)象并把它連接到以PDO為底的設(shè)備棧中。
具體步驟如下:
1) 用IoCreateDevice創(chuàng)建設(shè)備對(duì)象,并建立一個(gè)私有的設(shè)備擴(kuò)展對(duì)象。
PDEVICE_OBJECT fdo;
NTSTATUS status = IoCreateDevice(DriverObject,
?????????????????????????????? sizeof(DEVICE_EXTENSION),
?????????????????????????????? NULL,
?????????????????????????????? FILE_DEVICE_UNKNOWN,
?????????????????????????????? FILE_DEVICE_SECURE_OPEN,
?????????????????????????????? FALSE,
?????????????????????????????? &fdo);
2) 初始化設(shè)備擴(kuò)展和設(shè)備對(duì)象的Flag成員。
PDEVICE_EXTENSION pdc = (PDEVICE_EXTENSION)fdo->DeviceExtension;
fdo->DeviceExtension;
fdo->Flag2|=DO_BUFFERED_IO;
3) 調(diào)用IoAttachDeviceToDeviceStace函數(shù)把新設(shè)備對(duì)象放到堆棧上。
pdx->LowerDeviceObject=IoAttachDeviceToDeviceStack(fdo,pfo);
?設(shè)備對(duì)象(DEVICE_OBJECT或*PDEVICE_OBJECT)也是DDK定義的一個(gè)重要結(jié)構(gòu)。它可以在其設(shè)備名稱(DeviceName)域中(第三個(gè)參數(shù))為設(shè)備對(duì)象進(jìn)行命名。?設(shè)備對(duì)象另一個(gè)關(guān)鍵的域?yàn)閿U(kuò)展設(shè)備對(duì)象(DeviceExtension)大小,I/O管理器為設(shè)備對(duì)象分配一塊內(nèi)存,該指針指向一個(gè)用戶定義的數(shù)據(jù)結(jié)構(gòu),用于保存每個(gè)設(shè)備實(shí)例的信息
typedef struct _DEVICE_EXTENSION
{
??? PDEVICE_OBJECT DeviceObject; //device object this extension
//belongs to
??? PDEVICE_OBJECT LowerDeviceObject;? //next lower driver in//same stack
??? PDEVICE_OBJECT Pdo;???? //the PDO
??? IO_REMOVE_LOCK RemoveLock;? //removal control locking structure
??? UNICODE_STRING ifname;???? //interface name
??? DEVSTATE state???? //current state of device
??? DEVSTATE prevstate;?? //state prior to removal query
??? DEVICE_POWER_STATE devpower; //current device power state
??? SYSTEM_POWER_STATE syspower;? //currnet system power state
??? DEVICE_CAPABILITIES devcaps;?? //copy of most recent device capabilities
??? LONG handles;??? //#open handle
??? USBD_DEVICE_DESCRIPTOR dd;?? //device descriptor
??? USBD_CONFIGURATION_HANDLE hconfig;?? //selected configuration handle
??? PUSB_CONFIGURATION_DESCRIPTOR pcd;?? //Configuration descriptor;
??? LANGID langid;???? //default language id for strings
??? USBD_PIPE_HANDLE hPipe;
??? USBD_PIPE_HANDLE hPipe_WriteCode;
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
AddDevice為設(shè)備對(duì)象注冊(cè)一個(gè)接口,以便應(yīng)用程序能通過注冊(cè)接口來訪問該設(shè)備。一個(gè)設(shè)備接口被一個(gè)128位的GUID唯一標(biāo)識(shí)。
??? status = IoRegisterDeviceInferface(pdo,&GUID_INTERFACE_USB,NULL,&pdx->ifname);得到GUID后,當(dāng)響應(yīng)PnP請(qǐng)求IRP_MN_START_DEVICE時(shí),驅(qū)動(dòng)程序調(diào)用下面函數(shù)使其可用,IoSetDeviceInterfacestate(&pdx->ifname,TRUE);
在響應(yīng)這個(gè)調(diào)用過程中,I/O管理器將創(chuàng)建一個(gè)指向設(shè)備的PDO符號(hào)連接對(duì)象。因?yàn)榻涌诿罱K指向PDO,所以PDO的安全描述符將最終控制設(shè)備的訪問權(quán)限。(3)ReadWrite實(shí)現(xiàn)設(shè)備驅(qū)動(dòng)程序功能的各個(gè)派遣函數(shù),并實(shí)現(xiàn)總線枚舉和管理函數(shù),用于設(shè)備初始化以及錯(cuò)誤恢復(fù)。是整個(gè)驅(qū)動(dòng)最重要部分,以讀數(shù)據(jù)請(qǐng)求為例子,即主機(jī)要求設(shè)備向其傳輸數(shù)據(jù)。
1)建立并提交一個(gè)URB,USB驅(qū)動(dòng)從不直接和硬件對(duì)話,通過創(chuàng)建URB并把URB提交到總線驅(qū)動(dòng)程序就可以完成硬件操作,USBD.SYS是接受URB的實(shí)體,向USBD的調(diào)用被轉(zhuǎn)化為帶有主功能代碼為IRP_MJ_XXX的IRP。然后USBD再調(diào)度總線時(shí)間,發(fā)出URB中指定的操作。
創(chuàng)建一個(gè)URB是USB驅(qū)動(dòng)最基本的工作,首先應(yīng)該為URB分配內(nèi)存,然后調(diào)用初始化例程把URB結(jié)構(gòu)中的各個(gè)域填入請(qǐng)求要求的內(nèi)容。最后通過創(chuàng)建并發(fā)送一個(gè)內(nèi)部I/O控制(IOCTL)請(qǐng)求到USBD驅(qū)動(dòng)程序來發(fā)送這個(gè)URB包,從而完成USB請(qǐng)求。
2)創(chuàng)建并發(fā)送IOCTL請(qǐng)求
創(chuàng)建完URB后,我們創(chuàng)建并發(fā)送一個(gè)IOCTL(內(nèi)部I/O控制)請(qǐng)求到USBD,然后等待設(shè)備回應(yīng),相應(yīng)的函數(shù)為SendAwaitUrb
3) 返回設(shè)備完成狀態(tài)

總結(jié)

以上是生活随笔為你收集整理的对USB驱动程序的理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。