1 引言
USB是目前發(fā)展應(yīng)用非常廣泛的一項(xiàng)技術(shù)。它是一種計(jì)算機(jī)系統(tǒng)連接外圍設(shè)備的標(biāo)準(zhǔn)輸入/輸出接口。根據(jù)外圍設(shè)備的不同的類型USB協(xié)議將其分類,每個(gè)設(shè)備類型都定義了類似功能設(shè)備的共同行為和協(xié)議。相同類型的設(shè)備都由一組標(biāo)準(zhǔn)定義的功能模塊組成。這樣主機(jī)與USB設(shè)備之間的通信就可以通過(guò)一些標(biāo)準(zhǔn)格式的數(shù)據(jù)包來(lái)完成。USB開(kāi)發(fā)者論壇發(fā)布了一系列USB設(shè)備的類型定義,并配以相應(yīng)的使用說(shuō)明。下面表格顯示出 USB的設(shè)備類型(DEVEICE CLASS):
雖然Windows已經(jīng)提供了底層總線操作的驅(qū)動(dòng)程序,但與此類底層驅(qū)動(dòng)程序接口的是i/o請(qǐng)求包的IRPs的結(jié)構(gòu),而Windows為應(yīng)用程序提供的接口是API函數(shù)。因此必須在其間建立一個(gè)驅(qū)動(dòng)程序,在USB底層驅(qū)動(dòng)與Windows應(yīng)用程序之間傳遞消息。VB、 C/C++、Delphi等通用編程語(yǔ)言編寫的應(yīng)用程序都可以在設(shè)備驅(qū)動(dòng)程序的支持下,調(diào)用Readfile、WriteFile、DeviceIoControl等API函數(shù)。而編寫底層總線的驅(qū)動(dòng)程序是非常復(fù)雜的一項(xiàng)工程。為了消除編寫設(shè)備驅(qū)動(dòng)程序的問(wèn)題,可對(duì)于一些具有相似功能的設(shè)備可以組成一類,分享共有的特性,便于使用Windows提供共同的類驅(qū)動(dòng)程序。
2 HID類型概述
第一個(gè)被windows支持的usb外圍設(shè)備類是人機(jī)接口設(shè)備。hid是human interface device人機(jī)接口設(shè)備的英文縮寫。是指直接和人進(jìn)行互動(dòng)的設(shè)備。如鼠標(biāo)、鍵盤等。運(yùn)行在WINDOWS98或其他更高的版本的操作系統(tǒng)的PC機(jī),系統(tǒng)除了提供通用的USB設(shè)備的底層驅(qū)動(dòng)以外,還單獨(dú)提供了一些HID設(shè)備的完整驅(qū)動(dòng),應(yīng)用程序可以很容易的與操作系統(tǒng)內(nèi)部的hid通訊。這樣使得符合hid類的USB設(shè)備很容易開(kāi)發(fā)與運(yùn)行。也就是說(shuō),我們?nèi)绻雽?shí)現(xiàn)一個(gè)USB的HID類設(shè)備,是不需要在Windows下開(kāi)發(fā)自己的驅(qū)動(dòng)程序。HID不一定要是標(biāo)準(zhǔn)的外設(shè)類型,唯一的要求是交換的數(shù)據(jù)存儲(chǔ)在報(bào)文的結(jié)構(gòu)內(nèi),設(shè)備固件必須支持報(bào)文的格式。任何工作在該限制之內(nèi)的設(shè)備都可以成為一個(gè)hid,例如溫度計(jì),電壓計(jì),讀卡機(jī)等。
hid類設(shè)備只能使用控制傳輸與中斷傳輸兩種方式。HID的交換的數(shù)據(jù)格式稱為報(bào)文。報(bào)文形式靈活,能處理任何類型的數(shù)據(jù)。HID特有的請(qǐng)求,Set_Report和Get_Report為主機(jī)和設(shè)備之間的任何類型數(shù)據(jù)塊傳輸提供了一種方法。主機(jī)發(fā)出Get_Report請(qǐng)求,設(shè)備響應(yīng)向主機(jī)傳送數(shù)據(jù)塊;主機(jī)發(fā)出Set_Report請(qǐng)求,設(shè)備響應(yīng)準(zhǔn)備接收主機(jī)發(fā)出的數(shù)據(jù)塊。對(duì)于一個(gè)全速設(shè)備,中斷傳輸方式下每筆事務(wù)能夠傳送的最大數(shù)據(jù)量是64字節(jié),全速設(shè)備每毫秒不能有超過(guò)一筆事務(wù),所以每秒最多傳送64000字節(jié)。高速設(shè)備,每筆事務(wù)能夠傳送的最大數(shù)據(jù)量是1024字節(jié)。對(duì)于不能一次傳輸完畢的數(shù)據(jù),接收和發(fā)送報(bào)文可以采用多筆事務(wù)。
表2列舉出了與HID類設(shè)備通信過(guò)程中使用到的大量函數(shù),這些函數(shù)的用法在DDK的幫助文檔中均有詳細(xì)地解釋。這些函數(shù)包含在Hid.dll、Setupapi.dll、Kernel32.dll三個(gè)動(dòng)態(tài)鏈接庫(kù)中,分別起到與HID設(shè)備通訊,尋找與識(shí)別設(shè)備,交換數(shù)據(jù)的作用。
Visual Basic編程語(yǔ)言,語(yǔ)法簡(jiǎn)單用法靈活易于掌握。用它來(lái)開(kāi)發(fā)通信程序是一種非?旖莸耐緩。但是需要指出的是,API函數(shù)的聲明格式在DDK的文檔內(nèi)全部是采用C語(yǔ)言的格式聲明,而VB與C語(yǔ)言的在變量的聲明、存儲(chǔ)格式上都有很大的區(qū)別。所以首先需要進(jìn)行類型轉(zhuǎn)換,例如CHAR轉(zhuǎn)換為Byte類型,USHORT、ULONG、BOOLEAN、LP_(長(zhǎng)指針前綴)、P_(指針前綴)轉(zhuǎn)換為L(zhǎng)ong 類型,PCTSTR轉(zhuǎn)換為String類型。其次,C語(yǔ)言的結(jié)構(gòu)體可以轉(zhuǎn)換為VB中的自定義數(shù)據(jù)類型,并且特別值得注意,在涉及到自定義數(shù)據(jù)類型中子類存儲(chǔ)位置必須注意到VB與C語(yǔ)言對(duì)應(yīng)轉(zhuǎn)換類型所占內(nèi)存空間不同的問(wèn)題。最后C語(yǔ)言中有指針的概念,而VB中沒(méi)有,所以需用Byref按地址傳遞,VarPtr取變量地址等方法進(jìn)行相應(yīng)的操作。
3 VB中調(diào)用API函數(shù)詳述
第一步需要獲得GUID(global unique identifier),需要調(diào)用函數(shù) HidD_GetHidGuid ,他在可以如下定義:
Public Declare Function HidD_GetHidGuid Lib_
"hid.dll" _
(ByRef HidGuid As GUID)
As Long
通過(guò)調(diào)用它可以得到HID 類設(shè)備的 GUID,應(yīng)用程序在與HID設(shè)備通訊之前,必須獲取HID類的獨(dú)特標(biāo)志符GUID,它是一個(gè)128位值,每一位唯一表示了一個(gè)對(duì)象。通過(guò)這個(gè)API函數(shù)就可以從系統(tǒng)中讀取該值,得到 HID 設(shè)備句柄。接下來(lái)應(yīng)檢測(cè)符合設(shè)定參數(shù)的HID,應(yīng)使用函數(shù) SetupDiGetClassDevs,轉(zhuǎn)換為VB中的定義是:
Public Declare Function SetupDiGetClassDevs_
Lib "setupapi.dll" _
Alias "SetupDiGetClassDevsA" _
(ByRef ClassGuid As GUID, _
ByVal Enumerator As String, _
ByVal hwndParent As Long, _
ByVal Flags As Long) _
As Long
當(dāng)調(diào)用該函數(shù)成功是,他返回一個(gè)包含所有的與設(shè)定參數(shù)匹配如:已連接和列舉,的設(shè)備信息的結(jié)構(gòu)體數(shù)組地址,該值在下一個(gè)將要調(diào)用的函數(shù)SetupDiEnumDeviceInterfaces中將使用到。SetupDiEnumDeviceInterfaces可定義為:&





