摘 要 本文首先簡(jiǎn)單介紹了USB HID設(shè)備的基礎(chǔ)知識(shí),然后針對(duì)HID藍(lán)牙設(shè)備,詳細(xì)闡述了對(duì)設(shè)備的讀寫操作方法和在使用中的斷連處理方式。
關(guān)鍵詞 USB;HID;藍(lán)牙
中圖分類號(hào)TP391.41 文獻(xiàn)標(biāo)識(shí)碼A 文章編號(hào)1673-9671-(2009)111-0013-01
0前言
通用串行總線(USB)是連接外部設(shè)備的一個(gè)串口總線標(biāo)準(zhǔn),在計(jì)算機(jī)上使用廣泛。目前市場(chǎng)上的USB設(shè)備種類繁多,根據(jù)設(shè)備類型,大致可以分為:音頻設(shè)備、打印設(shè)備、通信設(shè)備、大容量存儲(chǔ)設(shè)備、視頻設(shè)備和人機(jī)接口設(shè)備(HID)等。其中HID設(shè)備由于其兼容性的優(yōu)勢(shì),是目前最為常用的USB設(shè)備之一。本文所要介紹的HID藍(lán)牙設(shè)備,是一種采用藍(lán)牙無(wú)線連接方式的HID設(shè)備。本文將詳細(xì)闡述如何通過(guò)軟件實(shí)現(xiàn)對(duì)HID藍(lán)牙設(shè)備的數(shù)據(jù)讀寫及斷連處理。
1HID藍(lán)牙設(shè)備的讀寫操作
Windows操作系統(tǒng)自從Windows98開始就實(shí)現(xiàn)了對(duì)各種類型的常用HID設(shè)備的內(nèi)置支持。如果插入一個(gè)USB HID鍵盤,則相關(guān)的系統(tǒng)驅(qū)動(dòng)程序會(huì)自動(dòng)被裝入,用戶馬上可以開始使用該設(shè)備。這一切都是由于HID設(shè)備使用各種描述符定義它的功能。報(bào)告描述符詳細(xì)說(shuō)明它可以產(chǎn)生的輸入報(bào)告和可以接收的輸出報(bào)告。HID設(shè)備大多數(shù)時(shí)候?yàn)橛?jì)算機(jī)提供輸入數(shù)據(jù),但是,也可以輸出到HID設(shè)備。也可以控制設(shè)備的特性。
作為一個(gè)Windows平臺(tái)下的用戶態(tài)應(yīng)用程序,可以通過(guò)WDK(Windows Driver Kit)或DDK(Device Driver Kit)所提供的Windows API接口,實(shí)現(xiàn)對(duì)某個(gè)HID設(shè)備的讀寫操作。但從Windows 2000開始,系統(tǒng)將HID鍵盤和鼠標(biāo)作為獨(dú)占設(shè)備進(jìn)行訪問(wèn),用戶態(tài)的應(yīng)用程序是無(wú)法訪問(wèn)的。因此,本文所涉及的HID設(shè)備將不包括HID鍵盤和鼠標(biāo)。
對(duì)于一個(gè)HID藍(lán)牙設(shè)備而言,只要通過(guò)相關(guān)驅(qū)動(dòng)完成連接操作,對(duì)這個(gè)設(shè)備的讀寫操作與普通HID設(shè)備是一樣的。通常一個(gè)用戶態(tài)的應(yīng)用程序要訪問(wèn)HID設(shè)備,須經(jīng)過(guò)以下幾個(gè)步驟:
1.1遍歷系統(tǒng)中所有的HID設(shè)備
要查找所有的HID設(shè)備,首先需要知道HID類的GUID(Globally Unique Identifier),這個(gè)GUID可以通過(guò)例程HidD_GetHidGuid獲取。
在獲得HID類的GUID之后,則可以通過(guò)例程SetupDiGetClassDevs獲取匹配的HID設(shè)備集。
之后便可以通過(guò)SetupDiEnumDeviceInterfaces,SetupDiGetDeviceInterface-Detail等例程依次遍歷系統(tǒng)中所有的HID設(shè)備。并通過(guò)CreateFile例程打開查找到的HID設(shè)備,為下一步讀取設(shè)備功能特性做準(zhǔn)備。
1.2讀取每個(gè)HID設(shè)備的功能與特性
通過(guò)讀取HID設(shè)備的功能與特性,可以確定該設(shè)備是否是所要訪問(wèn)的設(shè)備。HID設(shè)備的功能特性可以從以下幾方面獲取:
通過(guò)HidD_GetPreparsedData和HidP_GetCaps例程可以獲取HIDP_CAPS信息,其中包含了UsagePage, Usage, FeatureReportByteLength, InputReportByteLength, OutputReportByteLength等信息,這些信息可以用來(lái)識(shí)別設(shè)備類型和功能。同時(shí),還可以進(jìn)一步的通過(guò)HidP_GetButtonCaps, HidP_GetSpecificButtonCaps, HidP_GetValueCaps, HidP_GetSpecificValueCaps等例程了解該設(shè)備的詳細(xì)信息。
通過(guò)HidD_GetAttributes例程可以獲取HIDD_ATTRIBUTES信息,其中包含了VendorID(廠商ID), ProductID(產(chǎn)品ID)及VersionNumber等信息,可以用來(lái)識(shí)別該設(shè)備的生產(chǎn)廠商及產(chǎn)品型號(hào)。
從以上兩方面獲得的結(jié)果,基本可以確定該HID設(shè)備是否為所要訪問(wèn)的設(shè)備了。
1.3在需要時(shí)對(duì)該設(shè)備執(zhí)行讀寫操作
在遍歷過(guò)程中找到了所要訪問(wèn)的設(shè)備之后,即可通過(guò)CreateFile例程打開該設(shè)備并獲取該設(shè)備的設(shè)備句柄(Handle)。在獲得Handle之后,即可通過(guò)ReadFile和WriteFile例程實(shí)現(xiàn)對(duì)該設(shè)備的讀寫操作。
2HID藍(lán)牙設(shè)備的斷連處理
對(duì)于一個(gè)有線的HID設(shè)備而言,只要該設(shè)備不從計(jì)算機(jī)上拔出,就不會(huì)存在設(shè)備斷連的問(wèn)題。但對(duì)于HID藍(lán)牙設(shè)備而言,就存在較多的設(shè)備斷連的可能,例如斷電、設(shè)備超出接收范圍等。因此,對(duì)于斷連的處理就成為了一個(gè)較為重要的問(wèn)題。
要對(duì)一個(gè)HID設(shè)備進(jìn)行讀寫操作,需要獲得該設(shè)備的設(shè)備句柄(Handle)。通常情況下,在一個(gè)應(yīng)用程序的運(yùn)行過(guò)程中,這個(gè)設(shè)備句柄是始終有效的;但當(dāng)該設(shè)備發(fā)生斷時(shí),這個(gè)設(shè)備句柄就可能失效。當(dāng)該設(shè)備與計(jì)算機(jī)重新連接之后,可能無(wú)法使用原設(shè)備句柄對(duì)該設(shè)備進(jìn)行讀寫操作。在這種情況下,就需要對(duì)該設(shè)備進(jìn)行相應(yīng)的斷連處理。
在HID藍(lán)牙設(shè)備出現(xiàn)斷連情況后,較為穩(wěn)妥的方法是再次遍歷系統(tǒng)中所有的HID設(shè)備,并通過(guò)CreateFile重新打開設(shè)備并獲取該設(shè)備的設(shè)備句柄。但在多個(gè)相同HID藍(lán)牙設(shè)備同時(shí)工作的情況下,重新遍歷HID藍(lán)牙設(shè)備并不能通過(guò)設(shè)備功能與特性區(qū)分哪個(gè)是剛斷連的設(shè)備,哪個(gè)是正常的設(shè)備。在這種情況下,就需要通過(guò)一種唯一標(biāo)識(shí)符來(lái)區(qū)分這些相同的設(shè)備。
為了解決這個(gè)問(wèn)題,在遍歷HID設(shè)備的過(guò)程中增加對(duì)SetupDiGetDeviceInstanceId例程的調(diào)用,以獲取設(shè)備實(shí)例標(biāo)識(shí)符(Device Instance Identifier),作為HID藍(lán)牙設(shè)備的唯一標(biāo)識(shí)符。這樣,即可在再次遍歷HID設(shè)備的過(guò)程中正確的識(shí)別出斷連的設(shè)備,以解決HID藍(lán)牙設(shè)備斷連處理的問(wèn)題。
3總結(jié)
隨著藍(lán)牙等無(wú)線技術(shù)的不斷成熟,無(wú)線HID設(shè)備也在不斷的發(fā)展,不斷的完善。因此,對(duì)于這一領(lǐng)域的研究將具有極大的應(yīng)用背景和市場(chǎng)背景。
參考文獻(xiàn)
[1]孫義等譯. Chris Cant. Windows WDM設(shè)備驅(qū)動(dòng)程序開發(fā)指南[M]. 北京. 機(jī)械工業(yè)出版社,2000.
[2]Device Class Definition for HID version 1.11. www.usb.org. 2001.