freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

畢業(yè)設(shè)計論文usb接口通信(驅(qū)動)的設(shè)計與實現(xiàn)-資料下載頁

2025-06-28 10:42本頁面
  

【正文】 程序的結(jié)構(gòu)設(shè)計圖5-1HID USB鍵盤I/O請求處理由圖5-1可以看出,HID類與USB類之間的調(diào)用關(guān)系,鍵盤驅(qū)動程序是系統(tǒng)中的一個中層驅(qū)動,它的下層驅(qū)動接口是USBDI,通過對USBDI的調(diào)用,實現(xiàn)對USB鍵盤的讀寫操作,以及配置設(shè)備等。它的上層是HID類驅(qū)動程序,本論文涉及的鍵盤驅(qū)動程序要為上層的HID類驅(qū)動程序提供接口。下面的兩節(jié)分別描述了對USB鍵盤的操作,和HID類小驅(qū)動程序的實現(xiàn)。這兩者嵌套在一起,實現(xiàn)了一個完整的USB鍵盤驅(qū)動。一個makefile工程是這樣的,它所編譯的文件都列在Sources文件中的宏里。Makefile工程有幾個設(shè)置文件,來設(shè)置編譯的環(huán)境和其他信息。VC++的build項規(guī)定了將DriverEntry函數(shù)作為驅(qū)動程序的入口,事實上這個入口可以通過修改build項來改變,但是這不重要。我們知道這個工程雖然沒有一個主函數(shù),但是它的確是從DriverEntry開始的。DriverEntry函數(shù)當中規(guī)定了一些項,這些項規(guī)定了各個例程在哪個函數(shù)中。具體運行的時候會找到這些代碼并執(zhí)行。 為了方便起見,我們將程序當中的文件分為三種,一種是頭文件,第二種是實現(xiàn)文件,第三種是配置文件, ,,它們定義了一些結(jié)構(gòu),象鍵盤報告描述符,系統(tǒng)中用到的函數(shù)定義等。 , , , ,它們實現(xiàn)各個例程的函數(shù)。,MAKEFILE,Sources等,象MAKEFILE這樣的文件,它的內(nèi)容是不推薦改變的。MakeDrvr是一個設(shè)置環(huán)境變量的批處理文件,將在后面描述。 我們并不是十分關(guān)心函數(shù)在每個文件里是如何被放置的,在DriverEntry中已經(jīng)做了一些設(shè)置,還是取幾乎是公例的文件名和函數(shù)名的原因,是編寫規(guī)范代碼的需要。一個函數(shù)名文件名規(guī)范,代碼編寫規(guī)范的好的源碼,是便于調(diào)試和閱讀的。 調(diào)用USBDI實現(xiàn)USB鍵盤控制USB設(shè)備交互的第一件事是復(fù)位設(shè)備,確保設(shè)備可用。向USBDI發(fā)送IOCTL_INTERNAL_USB_GET_PORT_STATUS請求,獲取USB設(shè)備狀態(tài)信息。如果設(shè)備是未連接狀態(tài),驅(qū)動程序不會安裝。如果設(shè)備沒有處于使能狀態(tài),就要發(fā)送IOCTL_INTERNAL_USB_RESET_PORT請求給USBDI來復(fù)位設(shè)備。USB設(shè)備在正常被使用以前,必須被配置,由主機負責配置設(shè)備。主機一般會從USB設(shè)備獲取配置信息后再判定此設(shè)備有哪些功能。,是配置設(shè)備的過程,首先要獲得設(shè)備的配置描述符(見UsbGetConfigurationDescriptors函數(shù)),然后找出接口,設(shè)備接口的每個管道的最大傳輸數(shù)據(jù)包為8,創(chuàng)建配置設(shè)備的URB請求發(fā)送給USBDI(見CreateConfigurationRequest函數(shù)),配置設(shè)備,配置設(shè)備成功之后保存配置句柄和管道句柄,以備將來使用讀鍵盤容易理解,寫鍵盤則是設(shè)置鍵盤上的LED燈。另外需要提供一個數(shù)據(jù)緩沖區(qū)來保存數(shù)據(jù),上一節(jié)提到最大數(shù)據(jù)包的大小為8,因此這個緩沖區(qū)的大小不能小于8字節(jié),如果小于8字節(jié),應(yīng)該提示出錯。,USB鍵盤適合中斷傳輸方式,用創(chuàng)建URB的接口創(chuàng)建一個_URB_BULK_OR_INTERRUPT_TRANSFER類型的URB請求,發(fā)送到USBDI,處理之后,URB中就會有輸入的數(shù)據(jù)。完成IRP,將數(shù)據(jù)返回給請求者。讀操作完成()。寫操作是設(shè)置鍵盤上的LED燈,首先要創(chuàng)建一個_URB_CONTROL_VENDOR_OR_CLASS_REQUEST 類型的URB請求。然后發(fā)送給USBDI,USBDI處理這個請求,設(shè)置鍵盤上的LED燈,完成IRP,通知請求者,鍵盤的寫操作完成()。 為HID類提供接口從某種意義上可以說,HID小驅(qū)動程序提供了對HID類設(shè)備進行操作的框架。在一些例程中,我們需要添加一些東西,來實現(xiàn)對HID類設(shè)備的操作。DriverEntry例程除了自己需要做的工作之外,它需要注冊成為HID小驅(qū)動程序,注冊的示例代碼如下:代碼清單5-1 1DriverEntry例程externCNTSTATUSDriverEntry(PDRIVER_OBJECTDriverObject,PUNICODE_STRINGRegistryPath){ //例程的函數(shù)DriverObjectDriverExtensionAddDevice=AddDevice。DriverObjectDriverUnload=DriverUnload。DriverObjectMajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]=DispatchInternalControl。DriverObjectMajorFunction[IRP_MJ_PNP]=DispatchPnp。DriverObjectMajorFunction[IRP_MJ_POWER]=DispatchPower。 //注冊成為HID MinidriverHID_MINIDRIVER_REGISTRATIONreg。RtlZeroMemory(amp。reg,sizeof(reg))。=HID_REVISION。 =DriverObject。=RegistryPath。=sizeof(DEVICE_EXTENSION)。=FALSE。//以具體硬件為準returnHidRegisterMinidriver(amp。reg)。}HidRegisterMinidriver是注冊的系統(tǒng)例程,可以看到首先是填寫一個注冊HID小驅(qū)動的結(jié)構(gòu)體HID_MINIDRIVER_REGISTRATION,然后用這個結(jié)構(gòu)體注冊。這個例程中有一些IOCTL,它們用來與HID設(shè)備交互。 節(jié)HIDCLASS小驅(qū)動的IOCTL中,有對這幾個IOCTL的詳細描述。IOCTL_HID_GET_DEVICE_ATTRIBUTES這個IOCTL返回給HID類小驅(qū)動程序設(shè)備屬性信息,程序填寫一個PHID_DEVICE_ATTRIBUTES結(jié)構(gòu),并將其返回。IOCTL_HID_GET_DEVICE_DESCRIPTOR這個IOCTL返回HID描述符,程序填充一個HID_DESCRIPTOR結(jié)構(gòu),并將其返回。IOCTL_HID_GET_REPORT_DESCRIPTOR這個IOCTL給HID小驅(qū)動程序返回報告描述符,將ReportDescriptor變量復(fù)制到HID類小驅(qū)動程序的緩沖區(qū)。IOCTL_HID_READ_REPORT這個IOCTL是讀取鍵盤數(shù)據(jù),程序清單如下:代碼清單5-2 IOCTL_HID_READ_REPOR if(outLen8) //不小于8字節(jié) { status = STATUS_BUFFER_TOO_SMALL。 break。 } if(dxbStarted==FALSE) { status = STATUS_DEVICE_NOT_READY。 break。 } if(Buffer==NULL) //緩沖區(qū)為空? { status=STATUS_INVALID_PARAMETER。 break。 } IoMarkIrpPending(Irp)。 //置IRP為未處理 IoStartPacket(fdo,Irp,0,NULL)。 return STATUS_PENDING。 //返回未處理狀態(tài)先判斷緩沖區(qū)的大小是不是比最大值8小,如果小于8個字節(jié),則返回錯誤信息STATUS_BUFFER_TOO_SMALL,并退出。然后檢查系統(tǒng)線程的狀態(tài),檢查緩沖區(qū)是否已經(jīng)有值,如果錯誤,返回錯誤信息并退出。接下來的IoMarkIrpPending函數(shù)是將IRP置為未處理狀態(tài),然后放入隊列,返回未處理的狀態(tài)。IOCTL_HID_WRITE_REPORT是用來設(shè)置LED燈的,代碼如下:代碼清單5-3 IOCTL_HID_WRITE_REPORTif(inLensizeof(HID_XFER_PACKET) || Buffer == NULL) { status = STATUS_INVALID_PARAMETER。 break。 } IoMarkIrpPending(Irp)。 IoStartPacket(fdo,Irp,0,NULL)。 return STATUS_PENDING。首先需判斷格式的正確與緩沖區(qū)是否已經(jīng)有了數(shù)據(jù),如果出錯,則返回錯誤信息,并退出處理。如果無誤,則將Irp置為未處理狀態(tài),放入隊列,并返回未處理標志。從這個處理過程可以看出,對于讀和寫的操作,我們并沒有直接在處理IRP_MJ_INTERNAL_DEVICE_CONTROL例程的時候調(diào)用,注意到每次都調(diào)用IoStartPacket函數(shù)將Irp放到隊列中,StartIo例程對是讀或者寫做出選擇,在系統(tǒng)線程中()中進行讀寫操作。這個系統(tǒng)線程在設(shè)備啟動的時候創(chuàng)建。 重要例程的實現(xiàn)設(shè)備驅(qū)動程序是一個包含了許多操作系統(tǒng)可調(diào)用例程的容器,這些例程包括DriverEntry例程,AddDevice例程,Dispath例程,StartIo例程等。PnP管理器先裝入硬件需要的驅(qū)動程序,然后再調(diào)用驅(qū)動程序中的AddDevice函數(shù)。一個驅(qū)動程序可以被多個類似的硬件使用,但驅(qū)動程序的某些全局初始化操作只能在第一次被裝入時執(zhí)行一次。而DriverEntry例程就是用于這個目的。DriverEntry是內(nèi)核模式驅(qū)動程序主入口點常用的名字。I/O管理器按下面方式調(diào)用該例程:extern C NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath){ ...}DriverEntry的第一個參數(shù)是一個指針,指向一個剛被初始化的驅(qū)動程序?qū)ο螅搶ο缶痛砟愕尿?qū)動程序。WDM驅(qū)動程序的DriverEntry例程應(yīng)完成對這個對象的初始化并返回。DriverEntry的第二個參數(shù)是設(shè)備服務(wù)鍵的鍵名。這個串不是長期存在的(函數(shù)返回后可能消失),如果以后想使用該串就必須先把它復(fù)制到安全的地方。對于WDM驅(qū)動程序的DriverEntry例程,其主要工作是把各種函數(shù)指針填入驅(qū)動程序?qū)ο?。這些指針為操作系統(tǒng)指明了驅(qū)動程序容器中各種子例程的位置。它們包括下面這些指針成員(驅(qū)動程序?qū)ο笾?: DriverUnload 指向驅(qū)動程序的清除例程。I/O管理器會在卸載驅(qū)動程序前調(diào)用該例程。通常,WDM驅(qū)動程序的DriverEntry例程一般不分配任何資源,所以DriverUnload例程也沒有什么清除工作要做。 DriverExtensionAddDevice 指向驅(qū)動程序的AddDevice函數(shù)。PnP管理器將為每個硬件實例調(diào)用一次AddDevice例程。DriverStartIo 如果驅(qū)動程序使用標準的IRP排隊方式,應(yīng)該設(shè)置該成員,使其指向驅(qū)動程序的StartIo例程。 MajorFunction 是一個指針數(shù)組,I/O管理器把每個數(shù)組元素都初始化成指向一個啞派遣函數(shù),這個啞派遣函數(shù)僅返回失敗。驅(qū)動程序可能僅需要處理幾種類型的IRP,所以至少應(yīng)該設(shè)置與那幾種IRP類型相對應(yīng)的指針元素,使它們指向相應(yīng)的派遣函數(shù)。 通常,一個驅(qū)動程序可以被多個設(shè)備利用。WDM驅(qū)動程序有一個特殊的AddDevice函數(shù),PnP管理器為每個設(shè)備實例調(diào)用該函數(shù)。該函數(shù)的原型如下:NTSTATUS AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT pdo){}DriverObject參數(shù)指向一個驅(qū)動程序?qū)ο?,就是你在DriverEntry例程中初始化的那個驅(qū)動程序?qū)ο蟆do參數(shù)指向設(shè)備堆棧底部的物理設(shè)備對象。對于功能驅(qū)動程序,其AddDevice函數(shù)的基本職責是創(chuàng)建一個設(shè)備對象并把它連接到以pdo為底的設(shè)備堆棧中。相關(guān)步驟如下: (1)調(diào)用IoCreateDevice創(chuàng)建設(shè)備對象,并建立一個私有的設(shè)備擴展對象。 (2)寄存一個或多個設(shè)備接口,以便應(yīng)用程序能知道設(shè)備的存在。另外,還可以給出設(shè)備名并創(chuàng)建符號連接。 (3)初始化設(shè)備擴展和設(shè)備對象的Flag成員。 (4)調(diào)用IoAttachDeviceToDeviceStack函數(shù)把新設(shè)備對象放到堆棧上。Dispatch例程由I/O管理器定義如下:NTSTATUS(*PDRIVER_DISPATCH) (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);通常,大多數(shù)驅(qū)動程序必須處理一些或者所有以下請求:LRP_MJ_PNP表明一個包括PnP設(shè)備識別的請求,硬件配置,或者資源分配的請求。這類請求顯然從PnP管理器或者從一個與較高層驅(qū)動程序密切相關(guān)的設(shè)備發(fā)送到一個設(shè)備驅(qū)動程序。IRP_MJ_POWER表明一個屬于設(shè)備或者系統(tǒng)的電源狀態(tài)請求。這類請求通過電源管理器或者一個密
點擊復(fù)制文檔內(nèi)容
公司管理相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1