?

< p > Java?平臺(tái)一直都以其平臺(tái)無(wú)關(guān)性自豪。雖然這種無(wú)關(guān)性有許多好處,但是它也使得編寫(xiě)與硬件交互的?
??????????????Java?應(yīng)用程序的過(guò)程變得相當(dāng)復(fù)雜。在本文中,研究科學(xué)家蔣清野討論了兩個(gè)項(xiàng)目,它們通過(guò)提供使Java?應(yīng)用程序可以使用?USB?
??????????????設(shè)備的?API?而使這個(gè)過(guò)程變得更容易。雖然這兩個(gè)項(xiàng)目仍然處于萌芽狀態(tài),但是它們都顯示了良好的前景,并已經(jīng)成為一些實(shí)用應(yīng)用程序的基礎(chǔ)。?
????????????
</ p >
????????????
< p > 通用串行總線(Universal?Serial?Bus?USB)規(guī)范的第一個(gè)版本發(fā)表于?1996年?1月。因?yàn)樗牡统杀尽⒏邤?shù)據(jù)傳輸率、使用容易和靈活性,USB?
??????????????在計(jì)算機(jī)行業(yè)里獲得了廣泛接受。今天,許多周邊設(shè)備和裝置都是通過(guò)?USB?接口連接到計(jì)算機(jī)上的。目前,大多數(shù)一般用途的操作系統(tǒng)都提供了對(duì)?
??????????????USB?設(shè)備的支持,并且用?C?或者?C++?可以相對(duì)容易地開(kāi)發(fā)訪問(wèn)這些外設(shè)的應(yīng)用程序。不過(guò),Java?編程語(yǔ)言在設(shè)計(jì)上對(duì)硬件訪問(wèn)提供的支持很少,所以編寫(xiě)與?
??????????????USB?設(shè)備交互的應(yīng)用程序是相當(dāng)困難的。?
</ p > ?
????????????
< p > IBM?的?Dan?Streetman?最早開(kāi)始了在?Java?語(yǔ)言中提供對(duì)?USB?設(shè)備的訪問(wèn)的努力。2001年,他的項(xiàng)目通過(guò)?
??????????????Java?規(guī)范請(qǐng)求(Java?Specification?Request,JSR)過(guò)程被接受為?Java?語(yǔ)言的候選擴(kuò)展標(biāo)準(zhǔn)。這個(gè)項(xiàng)目現(xiàn)在稱(chēng)為?
??????????????JSR-80?并且指定了官方包?javax.usb。同時(shí),在?2000年?6月,Mojo?Jojo?和?David?Brownell?
??????????????在?SourceForge?開(kāi)始了?jUSB?項(xiàng)目。這兩個(gè)項(xiàng)目都開(kāi)發(fā)出了?Linux?開(kāi)發(fā)人員可以使用的包,盡管它們都還很不完善。這兩個(gè)項(xiàng)目也都開(kāi)始試圖向其他操作系統(tǒng)上的?
??????????????Java?應(yīng)用程序提供對(duì)?USB?設(shè)備的訪問(wèn),盡管它們都還沒(méi)有開(kāi)發(fā)出可以使用的包(參閱?參考資料?中有關(guān)本文中討論的這兩個(gè)項(xiàng)目及其他項(xiàng)目的資料)。
</ p > ?
????????????
< p > 在本文中,將對(duì)?jUSB?和?JSR-80?項(xiàng)目作一個(gè)簡(jiǎn)要介紹,不過(guò),我們首先要看一下?USB?協(xié)議的具體細(xì)節(jié),這樣您就可以理解這兩個(gè)項(xiàng)目是如何與?
??????????????USB?設(shè)備交互的。我們還將提供代碼片段以展示如何用這兩個(gè)項(xiàng)目的?API?訪問(wèn)?USB?設(shè)備。?USB?介紹
</ p > ?
????????????
< p > 1994年,一個(gè)由四個(gè)行業(yè)伙伴(Compaq、Intel、Microsoft?和?NEC)組成的聯(lián)盟開(kāi)始制定?USB?協(xié)議。該協(xié)議最初的目的是將?
??????????????PC?與電話相連并提供容易擴(kuò)展和重新配置的?I/O?接口。1996年?1月,發(fā)表了?USB?規(guī)范的第一個(gè)版本,1998年?9月發(fā)表了后續(xù)版本(版本?
??????????????1.1)。這個(gè)規(guī)范允許?127臺(tái)設(shè)備同時(shí)連接到一起,總的通信帶寬限制為?12?Mbps。后來(lái),又有三個(gè)成員(Hewlett-Packard、Lucent?
??????????????和?Philips)加入了這個(gè)聯(lián)盟。2000年?4月,發(fā)表了?USB?規(guī)范的?2.0版本,它支持高達(dá)?480?Mbps?的傳輸率。今天,USB?
??????????????在高速(視頻、圖像、儲(chǔ)存)和全速(音頻、寬帶、麥克風(fēng))數(shù)據(jù)傳輸應(yīng)用中起了關(guān)鍵作用。它還使各種低速設(shè)備(鍵盤(pán)、鼠標(biāo)、游戲外設(shè)、虛擬現(xiàn)實(shí)外設(shè))連接到?
??????????????PC?上。
</ p > ?
????????????
< p > USB?協(xié)議有嚴(yán)格的層次結(jié)構(gòu)。在所有?USB?系統(tǒng)中,只有一個(gè)主設(shè)備,到主計(jì)算機(jī)的的?USB?接口稱(chēng)為主控器(host?controller)。主控器有兩個(gè)標(biāo)準(zhǔn)??開(kāi)放主控器接口(Compaq?
??????????????的?Open?Host?Controller?Interface,OHCI)和通用主控器接口(Intel?的?Universal?
??????????????Host?Controller?Interface,UHCI)。這兩個(gè)標(biāo)準(zhǔn)提供了同樣的能力,并可用于所有的?USB?設(shè)備,UHCI?
??????????????的硬件實(shí)現(xiàn)更簡(jiǎn)單一些,但是需要更復(fù)雜的設(shè)備驅(qū)動(dòng)程序(因而?CPU?的負(fù)荷更大一些)。
</ p > ?
????????????
< p > USB?物理互連是分層的星形拓樸,最多有七層。一個(gè)?hub?是每個(gè)星形的中心,USB?主機(jī)被認(rèn)為是?root?hub。每一段連線都是?
??????????????hub?與?USB?設(shè)備的點(diǎn)對(duì)點(diǎn)連接,后者可以是為系統(tǒng)提供更多附加點(diǎn)的另一個(gè)?hub,也可以是一個(gè)提供功能的某種設(shè)備。主機(jī)使用主/從協(xié)議與?
??????????????USB?設(shè)備通信。這種方式解決了包沖突的問(wèn)題,但是同時(shí)也阻止了附加的設(shè)備彼此建立直接通信。
</ p > ?
????????????
< p > 所有傳輸?shù)臄?shù)據(jù)都是由主控器發(fā)起的。數(shù)據(jù)從主機(jī)流向設(shè)備稱(chēng)為下行(downstream)或者輸出(out)傳輸,數(shù)據(jù)從設(shè)備流向主機(jī)稱(chēng)為上?
??????????????行(upstream)或者輸入(in)傳輸。數(shù)據(jù)傳輸發(fā)生在主機(jī)和?USB?設(shè)備上特定的端點(diǎn)(endpoint)?之間,主機(jī)與端點(diǎn)之間的數(shù)據(jù)鏈接稱(chēng)為管道(pipe)。?
??????????????一個(gè)給定的?USB?設(shè)備可以有許多個(gè)端點(diǎn),主機(jī)與設(shè)備之間數(shù)據(jù)管道的數(shù)量與該設(shè)備上端點(diǎn)的數(shù)量相同。一個(gè)管道可以是單向或者是雙向的,一個(gè)管道中的數(shù)據(jù)流與所有其他管道中的數(shù)據(jù)流無(wú)關(guān)。
</ p > ?
????????????
< p > USB?網(wǎng)絡(luò)中的通信可以使用下面四種數(shù)據(jù)傳輸類(lèi)型中的任意一種: </ p > ?
????????????
< p > 控制傳輸:?這些是一些短的數(shù)據(jù)包,用于設(shè)備控制和配置,特別是在設(shè)備附加到主機(jī)上時(shí)。? </ p >
????????????
< p > 批量傳輸:?這些是數(shù)量相對(duì)大的數(shù)據(jù)包。像掃描儀或者?SCSI?適配器這樣的設(shè)備使用這種傳輸類(lèi)型。? </ p > ?
????????????
< p > 中斷傳輸:?這些是定期輪詢(xún)的數(shù)據(jù)包。主控器會(huì)以特定的間隔自動(dòng)發(fā)出一個(gè)中斷。? </ p >
????????????
< p > 等時(shí)傳輸:?這些是實(shí)時(shí)的數(shù)據(jù)流,它們對(duì)帶寬的要求高于可靠性要求。音頻和視頻設(shè)備一般使用這種傳輸類(lèi)型。? </ p >
????????????
< p > 像串行端口一樣,計(jì)算機(jī)上每一個(gè)?USB?端口都由?USB?控制器指定了一個(gè)惟一的標(biāo)識(shí)數(shù)字(端口?ID)。當(dāng)?USB?設(shè)備附加到?
??????????????USB?端口上時(shí),就將這個(gè)?惟一端口?ID?分配給這臺(tái)設(shè)備,并且?USB?控制器會(huì)讀取設(shè)備描述符。設(shè)備描述符包括適用于該設(shè)備的全局信息、以及設(shè)備的配置信息。配置定義了一臺(tái)?
??????????????USB?設(shè)備的功能和?I/O?行為。一臺(tái)?USB?設(shè)備可以有一個(gè)或者多個(gè)配置,這由它們相應(yīng)的配置描述符所描述。每一個(gè)配置都有一個(gè)或者多個(gè)接口,它可以視為一個(gè)物理通信渠道?
??????????????;每一個(gè)接口有零個(gè)或者多個(gè)端點(diǎn),它可以是數(shù)據(jù)提供者或者數(shù)據(jù)消費(fèi)者,或者同時(shí)具有這兩種身份。接口由接口描述符描述,端點(diǎn)由端點(diǎn)描述符描述。并且一臺(tái)?
??????????????USB?設(shè)備可能還有字符串描述符以提供像廠商名、設(shè)備名或者序列號(hào)這樣的附加信息。
</ p > ?
????????????
< p > 正如您所看到的,像?USB?這樣的協(xié)議為使用?Java?這種強(qiáng)調(diào)平臺(tái)和硬件無(wú)關(guān)性的語(yǔ)言的開(kāi)發(fā)人員提出了挑戰(zhàn)。現(xiàn)在讓我們看兩個(gè)試圖解決這個(gè)問(wèn)題的項(xiàng)目。 </ p > ?
????????????
< p >< span? class ="f14" >< b > jUSB?API </ b ></ span ></ p >
????????????
< p >< span? class ="f14" > ?jUSB?項(xiàng)目是由?Mojo?Jojo?和?David?Brownell?于?2000年?
??????????????6月創(chuàng)立的。其目標(biāo)是提供一組免費(fèi)的、在?Linux?平臺(tái)上訪問(wèn)?USB?設(shè)備的?Java?API。這個(gè)?API?是按照?Lesser?
??????????????GPL?(LGPL)條款發(fā)表的,這意味著您可以在專(zhuān)有和免費(fèi)軟件項(xiàng)目中使用它。這個(gè)?API?提供了對(duì)多個(gè)物理?USB?設(shè)備的多線程訪問(wèn),并支持本機(jī)和遠(yuǎn)程設(shè)備。具有多個(gè)接口的設(shè)備可以同時(shí)被多個(gè)應(yīng)用程序(或者設(shè)備驅(qū)動(dòng)程序)所訪問(wèn),其中每一個(gè)應(yīng)用程序(或者設(shè)備驅(qū)動(dòng)程序)都占據(jù)一個(gè)不同的接口。該?
??????????????API?支持控制傳輸、批量傳輸和中斷傳輸,不支持等時(shí)傳輸,因?yàn)榈葧r(shí)傳輸用于媒體數(shù)據(jù)(如音頻和視頻),JMF?API?已經(jīng)在其他標(biāo)準(zhǔn)設(shè)備驅(qū)動(dòng)程序上對(duì)此提供了很好的支持(參閱?
??????????????參考資料)。當(dāng)前,該?API?可以在具有?Linux?2.4?核心或者以前的?2.2.18?核心的?GNU/Linux?版本上工作。因此可支持大多數(shù)最新的版本,例如,該?
??????????????API?可以在沒(méi)有任何補(bǔ)丁或者升級(jí)的?Red?Hat?7.2?和?9.0?上工作。
</ span ></ p >
????????????
< p >< span? class ="f14" > ?jUSB?API?包括以下包: < br >
?????????????? 
< br >
??????????????·usb.core:?這個(gè)包是?jUSB?API?的核心部分。它使得?Java?應(yīng)用程序可以從?USB?主機(jī)訪問(wèn)?USB?設(shè)備。
< br >
??????????????·usb.linux:?這個(gè)包包含?usb.core.Host?對(duì)象的?Linux?實(shí)現(xiàn)、bootstrapping?支持和其他可以提升?
??????????????Linux?USB?支持的類(lèi)。這個(gè)實(shí)現(xiàn)通過(guò)虛擬?USB?文件系統(tǒng)(usbdevfs)訪問(wèn)?USB?設(shè)備。
< br >
??????????????·usb.windows:?這個(gè)包包含?usb.core.Host?對(duì)象的?Windows?實(shí)現(xiàn)、bootstrapping?支持和其他可以提升?
??????????????Windows?USB?支持的類(lèi)。這個(gè)實(shí)現(xiàn)仍然處于非常初級(jí)的階段。
< br >
??????????????·usb.remote:?這個(gè)包是?usb.core?API?的遠(yuǎn)程版本。它包括一個(gè)?RMI?proxy?和一個(gè)?daemon?
??????????????應(yīng)用程序,它讓?Java?應(yīng)用程序可以訪問(wèn)遠(yuǎn)程計(jì)算機(jī)上的?USB?設(shè)備。
< br >
??????????????·usb.util:?這個(gè)包提供了一些有用的實(shí)用程序,可以將?firmware下載到?USB?設(shè)備上、將?USB?系統(tǒng)的內(nèi)容轉(zhuǎn)儲(chǔ)到?
??????????????XML?中、以及將只有?bulk?I/O?的?USB?設(shè)備工具轉(zhuǎn)換成一個(gè)套接字(socket)。
< br >
??????????????·usb.devices:?這個(gè)可選包收集了用?jUSB?API?訪問(wèn)不同?USB?設(shè)備的?Java?代碼,包括柯達(dá)數(shù)碼相機(jī)和?
??????????????Rio?500?MP3?播放器。這些?API?經(jīng)過(guò)特別編寫(xiě)以簡(jiǎn)化訪問(wèn)特定?USB?設(shè)備的過(guò)程,并且不能用于訪問(wèn)其他設(shè)備。這些?API?
??????????????是在?usb.core?API?之上構(gòu)建的,它們可以工作在所有支持?jUSB?的操作系統(tǒng)上。
< br >
??????????????·usb.view:?這個(gè)可選包提供了基于?Swing?的?USB?樹(shù)簡(jiǎn)單瀏覽器。它是一個(gè)展示?jUSB?API?應(yīng)用的很好的示例程序。
</ span ></ p >
????????????
< p >< span? class ="f14" > ?盡管?usb.core.Host?對(duì)象的實(shí)現(xiàn)對(duì)于不同的操作系統(tǒng)是不同的,但是?Java?
??????????????程序員只需要理解?usb.core?包就可以用?jUSB?API?開(kāi)始應(yīng)用程序的開(kāi)發(fā)。表?1?列出了?usb.core?的接口和類(lèi),Java?
??????????????程序員應(yīng)該熟悉它們:
</ span ></ p >
????????????
< p >< span? class ="f14" > ?表?1.?jUSB?中的接口和類(lèi) </ span ></ p >
????????????
< span? class ="f14" >
????????????
< table? width ="90%" ?border ="1" ?align ="center" ?cellPadding ="2" ?cellSpacing ="0" ?class ="content" >
??????????????
< tbody >
????????????????
< tr >
??????????????????
< td > 接口 </ td >
??????????????????
< td > 說(shuō)明 </ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td > Bus </ td >
??????????????????
< td > 將一組?USB?設(shè)備連接到?Host?上 </ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td > Host </ td >
??????????????????
< td > 表示具有一個(gè)或者多個(gè)?Bus?的?USB?控制器 </ td >
????????????????
</ tr >
??????????????
</ tbody >
????????????
</ table >
????????????
< br >
????????????
< table? width ="90%" ?border ="1" ?align ="center" ?cellPadding ="2" ?cellSpacing ="0" ?class ="content" >
??????????????
< tbody >
????????????????
< tr >
??????????????????
< td? width ="17%" > 類(lèi) </ td >
??????????????????
< td? width ="83%" > 說(shuō)明 </ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td? width ="17%" > Configuration </ td >
??????????????????
< td? width ="83%" > 提供對(duì)設(shè)備所支持的?USB?
????????????????????配置的訪問(wèn),以及對(duì)與該配置關(guān)聯(lián)的接口的訪問(wèn)
</ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td? width ="17%" > Descriptor </ td >
??????????????????
< td? width ="83%" > 具有?USB?
????????????????????類(lèi)型的描述符的實(shí)體的基類(lèi)
</ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td? width ="17%" > Device </ td >
??????????????????
< td? width ="83%" > 提供對(duì)?USB?設(shè)備的訪問(wèn) </ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td? width ="17%" > DeviceDescriptor </ td >
??????????????????
< td? width ="83%" > 提供對(duì)?USB?設(shè)備描述符的訪問(wèn) </ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td? width ="17%" > EndPoint </ td >
??????????????????
< td? width ="83%" > 提供對(duì)?USB?
????????????????????端點(diǎn)描述符的訪問(wèn)、在給定設(shè)備配置中構(gòu)造設(shè)備數(shù)據(jù)輸入或者輸出
</ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td? width ="17%" > HostFactory </ td >
??????????????????
< td? width ="83%" > 包含?bootstrapping?方法 </ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td? width ="17%" > Hub </ td >
??????????????????
< td? width ="83%" > 提供對(duì)?USB?hub?描述符以及一些?hub?
????????????????????操作的訪問(wèn)
</ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td? width ="17%" > Interface </ td >
??????????????????
< td? width ="83%" > 描述一組端點(diǎn),并與一個(gè)特定設(shè)備配置相關(guān)聯(lián) </ td >
????????????????
</ tr >
????????????????
< tr >
??????????????????
< td? width ="17%" > PortIdentifier </ td >
??????????????????
< td? width ="83%" > 為?USB?
????????????????????設(shè)備提供穩(wěn)定的字符串標(biāo)識(shí)符,以便在操作和故障診斷時(shí)使用
</ td >
????????????????
</ tr >
??????????????
</ tbody >
????????????
</ table >
????????????
</ span > ? < p >< span? class ="f14" >< br >
??????????????用?jUSB?API?訪問(wèn)一臺(tái)?USB?設(shè)備的正常過(guò)程如下:
< br >
??????????????
</ span >< span? class ="f14" >< br >
??????????????·通過(guò)從?HostFactory?得到?USB?Host?進(jìn)行?Bootstrap。
< br >
??????????????·從?Host?訪問(wèn)?USB?Bus,然后從這個(gè)?Bus?訪問(wèn)?USB?root?hub(即?USB?Device)。
< br >
??????????????·得到?hub?上可用的?USB?端口數(shù)量,遍歷所有端口以找到正確的?Device。
< br >
??????????????·訪問(wèn)附加到特定端口上的?USB?Device。可以用一臺(tái)?Device?的?PortIdentifier?直接從?Host?訪問(wèn)它,也可以通過(guò)從?
??????????????root?hub?開(kāi)始遍歷?USB?Bus?找到它。
< br >
??????????????·用?ControlMessage?與該?Device?直接交互,或者從該?Device?的當(dāng)前?Configuration?中要求一個(gè)?
??????????????Interface,并與該?Interface?上可用的?Endpoint?進(jìn)行?I/O?。
</ span ></ p >
????????????
< p >< span? class ="f14" > 清單?1?展示了如何用?jUSB?API?獲得?USB?系統(tǒng)中的內(nèi)容。這個(gè)程序編寫(xiě)為只是查看?
??????????????root?hub?上可用的?USB?設(shè)備,但是很容易將它改為遍歷整個(gè)?USB?樹(shù)。這里的邏輯對(duì)應(yīng)于上述步驟?1?到步驟?4。
</ span ></ p >
????????????
< p >< span? class ="f14" > 清單?1.?用?jUSB?API?獲得?USB?系統(tǒng)的內(nèi)容 </ span ></ p >
????????????
< span? class ="f14" >
????????????
< table? width ="90%" ?border ="1" ?align ="center" ?borderColor ="#ffcc66" ?bgColor ="#dadacf" ?class ="content" >
??????????????
< tbody >
????????????????
< tr >
??????????????????
< td > import?usb.core.*; < br >
????????????????????
< br >
????????????????????public?class?ListUSB
< br >
????????????????????{
< br >
???????????????????? public?static?void?main(String[]?args)
< br >
???????????????????? {
< br >
????????????????????  try
< br >
????????????????????  {
< br >
????????????????????   //?Bootstrap?by?getting?the?USB?Host?from?the?
????????????????????HostFactory.
< br >
????????????????????   Host?host?=?HostFactory.getHost();
< br >
????????????????????
< br >
????????????????????   //?Obtain?a?list?of?the?USB?buses?available?on?the?
????????????????????Host.
< br >
????????????????????   Bus[]?bus?=?host.getBusses();
< br >
????????????????????   int?total_bus?=?bus.length;
< br >
????????????????????
< br >
????????????????????   //?Traverse?through?all?the?USB?buses.
< br >
????????????????????   for?(int?i=0;?i
&lt; total_bus;?i++) < br >
????????????????????   {
< br >
????????????????????    //?Access?the?root?hub?on?the?USB?bus?and?obtain?
????????????????????the
< br >
????????????????????    //?number?of?USB?ports?available?on?the?root?
????????????????????hub.
< br >
????????????????????    Device?root?=?bus[i].getRootHub();
< br >
????????????????????    int?total_port?=?root.getNumPorts();
< br >
????????????????????
< br >
????????????????????    //?Traverse?through?all?the?USB?ports?available?
????????????????????on?the
< br >
????????????????????    //?root?hub.?It?should?be?mentioned?that?the?
????????????????????numbering
< br >
????????????????????    //?starts?from?1,?not?0.
< br >
????????????????????    for?(int?j=1;?j
&lt; =total_port;?j++) < br >
????????????????????    {
< br >
????????????????????     //?Obtain?the?Device?connected?to?the?port.
< br >
????????????????????     Device?device?=?root.getChild(j);
< br >
????????????????????     if?(device?!=?null)
< br >
????????????????????     {
< br >
????????????????????      //?USB?device?available,?do?something?
????????????????????here.
< br >
????????????????????     }
< br >
????????????????????    }
< br >
????????????????????   }
< br >
????????????????????  }?catch?(Exception?e)
< br >
????????????????????  {
< br >
????????????????????   System.out.println(e.getMessage());
< br >
????????????????????  }
< br >
???????????????????? }
</ td >
????????????????
</ tr >
??????????????
</ tbody >
????????????
</ table >
????????????
</ span >< br >
????????????
< p >< span? class ="f14" > 清單?2?展示了在應(yīng)用程序成功地找到了?Device?的條件下,如何與?Interface?
??????????????和?EndPoint?進(jìn)行批量?I/O。?這個(gè)代碼段也可以修改為執(zhí)行控制或者中斷?I/O。它對(duì)應(yīng)于上述步驟?5。
</ span >
????????????
< p >< span? class ="f14" > ?清單?2.?用?jUSB?API?執(zhí)行批量?I/O </ span >< span? class ="f14" > ?
????????????
< table? width ="90%" ?border ="1" ?align ="center" ?borderColor ="#ffcc66" ?bgColor ="#dadacf" ?class ="content" >
??????????????
< tbody >
????????????????
< tr > ?
??????????????????
< td > if?(device?!=?null) < br >
????????????????????{
< br >
???????????????????? //?Obtain?the?current?Configuration?of?the?device?and?the?
????????????????????number?of
< br >
???????????????????? //?Interfaces?available?under?the?current?Configuration.
< br >
???????????????????? Configuration?config?=?device.getConfiguration();
< br >
???????????????????? int?total_interface?=?config.getNumInterfaces();
< br > ? < br >
???????????????????? //?Traverse?through?the?Interfaces
< br >
???????????????????? for?(int?k=0;?k
&lt; total_interface;?k++) < br >
???????????????????? {
< br >
????????????????????  //?Access?the?currently?Interface?and?obtain?the?number?
????????????????????of
< br >
????????????????????  //?endpoints?available?on?the?Interface.
< br >
????????????????????  Interface?itf?=?config.getInterface(k,?0);
< br >
????????????????????  int?total_ep?=?itf.getNumEndpoints();
< br > ? < br >
????????????????????  //?Traverse?through?all?the?endpoints.
< br >
????????????????????  for?(int?l=0;?l
&lt; total_ep;?l++) < br >
????????????????????  {
< br >
????????????????????   //?Access?the?endpoint,?and?obtain?its?I/O?type.
< br >
????????????????????   Endpoint?ep?=?itf.getEndpoint(l);
< br >
????????????????????   String?io_type?=?ep.getType();
< br >
????????????????????   boolean?input?=?ep.isInput();
< br > ? < br >
????????????????????   //?If?the?endpoint?is?an?input?endpoint,?obtain?its
< br >
????????????????????   //?InputStream?and?read?in?data.
< br >
????????????????????   if?(input)
< br >
????????????????????   {
< br >
????????????????????    InputStream?in;
< br >
????????????????????    in?=?ep.getInputStream();
< br >
????????????????????    //?Read?in?data?here
< br >
????????????????????    in.close();
< br >
????????????????????   }
< br >
????????????????????   //?If?the?Endpoint?is?and?output?Endpoint,?obtain?its
< br >
????????????????????   //?OutputStream?and?write?out?data.
< br >
????????????????????   else
< br >
????????????????????   {
< br >
????????????????????    OutputStream?out;
< br >
????????????????????    out?=?ep.getOutputStream();
< br >
????????????????????    //?Write?out?data?here.
< br >
????????????????????    out.close();
< br >
????????????????????   }
< br >
????????????????????  }
< br >
???????????????????? }
< br >
????????????????????}
</ td >
????????????????
</ tr >
??????????????
</ tbody >
????????????
</ table >
????????????
</ span >
????????????
< p >< span? class ="f14" > jUSB?項(xiàng)目在?2000年?6月到?2001年?2月期間非常活躍。該?API?的最新的版本?
??????????????0.4.4發(fā)表于?2001年?2月?14日。從那以后只提出了很少的改進(jìn),原因可能是?IBM?小組成功地成為了?Java?語(yǔ)言的候選擴(kuò)展標(biāo)準(zhǔn)。不過(guò),基于?
??????????????jUSB?已經(jīng)開(kāi)發(fā)出一些第三方應(yīng)用程序,包括?JPhoto?項(xiàng)目(這是一個(gè)用?jUSB?連接到數(shù)碼照相機(jī)的應(yīng)用程序)和?jSyncManager?
??????????????項(xiàng)目(這是一個(gè)用?jUSB?與使用?Palm?操作系統(tǒng)的?PDA?同步的應(yīng)用程序)。
</ span > ? </ p >
????????????
< p >< span? class ="f14" >< b > JSR-80?API?(javax.usb) </ b ></ span >
????????????
< p >< span? class ="f14" > 正如前面提到的,JSR-80?項(xiàng)目是由?IBM?的?Dan?Streetman?于?1999年創(chuàng)立的。2001年,這個(gè)項(xiàng)目通過(guò)?
??????????????Java?規(guī)范請(qǐng)求(JSR)過(guò)程被接受為?Java?語(yǔ)言的候選擴(kuò)展標(biāo)準(zhǔn)。這個(gè)項(xiàng)目現(xiàn)在稱(chēng)為?JSR-80?并且被正式分派了?Java?
??????????????包?javax.usb。這個(gè)項(xiàng)目使用?Common?Public?License?的許可證形式,并通過(guò)?Java?Community?
??????????????Process?進(jìn)行開(kāi)發(fā)。這個(gè)項(xiàng)目的目標(biāo)是為?Java?平臺(tái)開(kāi)發(fā)一個(gè)?USB?接口,可以從任何?Java?應(yīng)用程序中完全訪問(wèn)?USB?
??????????????系統(tǒng)。JSR-80?API?支持?USB?規(guī)范所定義的全部四種傳輸類(lèi)型。目前,該?API?的?Linux?實(shí)現(xiàn)可以在支持?2.4?
??????????????核心的大多數(shù)最新?GNU/Linux?版本上工作,如?Red?Hat?7.2?和?9.0。
</ span >
????????????
< p >< span? class ="f14" > ?JSR-80?項(xiàng)目包括三個(gè)包:javax-usb?(javax.usb?API)、javax-usb-ri?
??????????????(操作系統(tǒng)無(wú)關(guān)的基準(zhǔn)實(shí)現(xiàn)的公共部分)以及?javax-usb-ri-linux?(Linux?平臺(tái)的基準(zhǔn)實(shí)現(xiàn),它將公共基準(zhǔn)實(shí)現(xiàn)鏈接到?
??????????????Linux?USB?堆棧)。所有這三個(gè)部分都是構(gòu)成?Linux?平臺(tái)上?java.usb?API?完整功能所必需的。在該項(xiàng)目的電子郵件列表中可以看到有人正在致力于將這個(gè)?
??????????????API?移植到其他操作系統(tǒng)上(主要是?Microsoft?Windows),但是還沒(méi)有可以工作的版本發(fā)表。
</ span >
????????????
< p >< span? class ="f14" > ?盡管?JSR-80?API?的操作系統(tǒng)無(wú)關(guān)的實(shí)現(xiàn)在不同的操作系統(tǒng)上是不同的,但是?Java?
??????????????程序員只需要理解?javax.usb?包就可以開(kāi)始開(kāi)發(fā)應(yīng)用程序了。表?2?列出了?javax.usb?中的接口和類(lèi),?Java?
??????????????程序員應(yīng)該熟悉它們:
</ span >
????????????
< p >< span? class ="f14" > ?表?2.?JSR-80?API?中的接口和類(lèi) </ span >< span? class ="f14" > ?
????????????
< table? width ="90%" ?border ="1" ?align ="center" ?cellPadding ="2" ?cellSpacing ="0" ?class ="content" >
??????????????
< tbody >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > 接口 </ td >
??????????????????
< td? width ="75%" > 說(shuō)明 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbConfiguration </ td >
??????????????????
< td? width ="75%" > 表示?USB?設(shè)備的配置 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbConfigurationDescriptor </ td >
??????????????????
< td? width ="75%" > USB?配置描述符的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbDevice </ td >
??????????????????
< td? width ="75%" > USB?設(shè)備的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbDeviceDescriptor </ td >
??????????????????
< td? width ="75%" > USB?設(shè)備描述符的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbEndpoint </ td >
??????????????????
< td? width ="75%" > USB?端點(diǎn)的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbEndpointDescriptor </ td >
??????????????????
< td? width ="75%" > USB?端點(diǎn)描述符的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbHub </ td >
??????????????????
< td? width ="75%" > USB?hub?的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbInterface </ td >
??????????????????
< td? width ="75%" > USB?接口的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbInterfaceDescriptor </ td >
??????????????????
< td? width ="75%" > USB?接口描述符的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbPipe </ td >
??????????????????
< td? width ="75%" > USB?管道的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbPort </ td >
??????????????????
< td? width ="75%" > USB?端口的接口 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbServices </ td >
??????????????????
< td? width ="75%" > javax.usb?實(shí)現(xiàn)的接口 </ td >
????????????????
</ tr >
??????????????
</ tbody >
????????????
</ table >
????????????
< br >
????????????
< table? width ="90%" ?border ="1" ?align ="center" ?cellPadding ="2" ?cellSpacing ="0" ?class ="content" >
??????????????
< tbody >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > 類(lèi) </ td >
??????????????????
< td? width ="75%" > 說(shuō)明 </ td >
????????????????
</ tr >
????????????????
< tr > ?
??????????????????
< td? width ="25%" > UsbHostManager </ td >
??????????????????
< td? width ="75%" > javax.usb?的入口點(diǎn) </ td >
????????????????
</ tr >
??????????????
</ tbody >
????????????
</ table >
????????????
</ span >
????????????
< p >< span? class ="f14" > 用?JSR-80?API?訪問(wèn)?USB?設(shè)備的正常過(guò)程如下: < br >
??????????????
< br >
??????????????·通過(guò)從?UsbHostManager?得到相應(yīng)的?UsbServices?進(jìn)行?Bootstrap。
< br >
??????????????·通過(guò)?UsbServices?訪問(wèn)?root?hub。在應(yīng)用程序中?root?hub?就是一個(gè)?UsbHub。
< br >
??????????????·獲得連接到?root?hub?的?UsbDevices?清單。遍歷所有低級(jí)?hub?以找到正確的?UsbDevice。
< br >
??????????????·用控制消息(UsbControlIrp)與?UsbDevice?直接交互,或者從?UsbDevice?的相應(yīng)?UsbConfiguration?
??????????????中要求一個(gè)?UsbInterface?并與該?UsbInterface?上可用的?UsbEndpoint?進(jìn)行?I/O。
< br >
??????????????·如果一個(gè)?UsbEndpoint?用于進(jìn)行?I/O,那么打開(kāi)與它關(guān)聯(lián)的?UsbPipe。通過(guò)這個(gè)?UsbPipe?可以同步或者異步提交上行數(shù)據(jù)(從?
??????????????USB?設(shè)備到主計(jì)算機(jī))和下行數(shù)據(jù)(從主計(jì)算機(jī)到?USB?設(shè)備)。
< br >
??????????????·當(dāng)應(yīng)用程序不再需要訪問(wèn)該?UsbDevice?時(shí),關(guān)閉這個(gè)?UsbPipe?并釋放相應(yīng)的?UsbInterface。
< br >
??????????????
< br >
??????????????在清單?3?中,我們用?JSR-80?API?獲得?USB?系統(tǒng)的內(nèi)容。這個(gè)程序遞歸地遍歷?USB?系統(tǒng)上的所有?USB?hub?
??????????????并找出連接到主機(jī)計(jì)算機(jī)上的所有?USB?設(shè)備。這段代碼對(duì)應(yīng)于上述步驟?1?到步驟?3。
</ span ></ p >
????????????
< p >< span? class ="f14" > ?清單?3.?用?JSR-80?API?獲得?USB?系統(tǒng)的內(nèi)容 </ span ></ p >
????????????
< span? class ="f14" > ?
????????????
< table? width ="90%" ?border ="1" ?align ="center" ?borderColor ="#ffcc66" ?bgColor ="#dadacf" ?class ="content" >
??????????????
< tbody >
????????????????
< tr > ?
??????????????????
< td > import?javax.usb.*; < br >
????????????????????import?java.util.List;
< br > ? < br >
????????????????????public?class?TraverseUSB
< br >
????????????????????{
< br >
???????????????????? public?static?void?main(String?argv[])
< br >
???????????????????? {
< br >
????????????????????  try
< br >
????????????????????  {
< br >
????????????????????   //?Access?the?system?USB?services,?and?access?to?the?root
< br >
????????????????????   //?hub.?Then?traverse?through?the?root?hub.
< br >
????????????????????   UsbServices?services?=?UsbHostManager.getUsbServices();
< br >
????????????????????   UsbHub?rootHub?=?services.getRootUsbHub();
< br >
????????????????????   traverse(rootHub);
< br >
????????????????????  }?catch?(Exception?e)?{}
< br >
???????????????????? }
< br > ? < br >
???????????????????? public?static?void?traverse(UsbDevice?device)
< br >
???????????????????? {
< br >
????????????????????  if?(device.isUsbHub())
< br >
????????????????????  {
< br >
????????????????????   //?This?is?a?USB?Hub,?traverse?through?the?hub.
< br >
????????????????????   List?attachedDevices?=?((UsbHub)?device).getAttachedUsbDevices();
< br >
????????????????????   for?(int?i=0;?i
&lt; attachedDevices.size();?i++) < br >
????????????????????   {
< br >
????????????????????    traverse((UsbDevice)?attachedDevices.get(i));
< br >
????????????????????   }
< br >
????????????????????  }
< br >
????????????????????  else
< br >
????????????????????  {
< br >
????????????????????   //?This?is?a?USB?function,?not?a?hub.
< br >
????????????????????   //?Do?something.
< br >
????????????????????  }
< br >
???????????????????? }
< br >
????????????????????}
</ td >
????????????????
</ tr >
??????????????
</ tbody >
????????????
</ table >
????????????
</ span >
????????????
< p >< span? class ="f14" > 清單?4?展示了在應(yīng)用程序成功地找到?Device?后,如何與?Interface?和?EndPoint?
??????????????進(jìn)行?I/O。這段代碼還可以修改為進(jìn)行所有四種數(shù)據(jù)傳輸類(lèi)型的?I/O。它對(duì)應(yīng)于上述步驟?4?到步驟?6。
</ span ></ p >
????????????
< p >< span? class ="f14" > ?清單?4.?用?JSR-80?API?進(jìn)行?I/O </ span ></ p >
????????????
< span? class ="f14" > ?
????????????
< table? width ="90%" ?border ="1" ?align ="center" ?borderColor ="#ffcc66" ?bgColor ="#dadacf" ?class ="content" >
??????????????
< tbody >
????????????????
< tr > ?
??????????????????
< td > public?static?void?testIO(UsbDevice?device) < br >
????????????????????{
< br >
???????????????????? try
< br >
???????????????????? {
< br >
????????????????????  //?Access?to?the?active?configuration?of?the?USB?device,?
????????????????????obtain
< br >
????????????????????  //?all?the?interfaces?available?in?that?configuration.
< br >
????????????????????  UsbConfiguration?config?=?device.getActiveUsbConfiguration();
< br >
????????????????????  List?totalInterfaces?=?config.getUsbInterfaces();
< br > ? < br >
????????????????????  //?Traverse?through?all?the?interfaces,?and?access?the?endpoints
< br >
????????????????????  //?available?to?that?interface?for?I/O.
< br >
????????????????????  for?(int?i=0;?i
&lt; totalInterfaces.size();?i++) < br >
????????????????????  {
< br >
????????????????????   UsbInterface?interf?=?(UsbInterface)?totalInterfaces.get(i);
< br >
????????????????????   interf.claim();
< br >
????????????????????   List?totalEndpoints?=?interf.getUsbEndpoints();
< br >
????????????????????   for?(int?j=0;?j
&lt; totalEndpoints.size();?j++) < br >
????????????????????   {
< br >
????????????????????    //?Access?the?particular?endpoint,?determine?the?direction
< br >
????????????????????    //?of?its?data?flow,?and?type?of?data?transfer,?and?open?
????????????????????the
< br >
????????????????????    //?data?pipe?for?I/O.
< br >
????????????????????    UsbEndpoint?ep?=?(UsbEndpoint)?totalEndpoints.get(i);
< br >
????????????????????    int?direction?=?ep.getDirection();
< br >
????????????????????    int?type?=?ep.getType();
< br >
????????????????????    UsbPipe?pipe?=?ep.getUsbPipe();
< br >
????????????????????    pipe.open();
< br >
????????????????????    //?Perform?I/O?through?the?USB?pipe?here.
< br >
????????????????????    pipe.close();
< br >
????????????????????   }
< br >
????????????????????   interf.release();
< br >
????????????????????  }
< br >
???????????????????? }?catch?(Exception?e)?{}
< br >
????????????????????}
</ td >
????????????????
</ tr >
??????????????
</ tbody >
????????????
</ table >
????????????
</ span >
????????????
< p >< span? class ="f14" > JSR-80?項(xiàng)目從一開(kāi)始就非常活躍。2003年?2月發(fā)表了?javax.usb?API、RI?
??????????????和?RI?的?0.10.0?版本。看起來(lái)這一版本會(huì)提交給?JSR-80?委員會(huì)做最終批準(zhǔn)。預(yù)計(jì)正式成為?Java?語(yǔ)言的擴(kuò)展標(biāo)準(zhǔn)后,其他操作系統(tǒng)上的實(shí)現(xiàn)會(huì)很快出現(xiàn)。Linux?
??????????????開(kāi)發(fā)者團(tuán)體看來(lái)對(duì)?JSR-80?項(xiàng)目的興趣比?jUSB?項(xiàng)目更大,使用?Linux?平臺(tái)的?javax.usb?API?的項(xiàng)目數(shù)量在不斷地增加。
</ span ></ p >
????????????
< p >< span? class ="f14" >< b > 結(jié)束語(yǔ) </ b ></ span ></ p >
????????????
< p >< span? class ="f14" > ?jUSB?API?和?JSR-80?API?都為應(yīng)用程序提供了從運(yùn)行?Linux?操作系統(tǒng)的計(jì)算機(jī)中訪問(wèn)?
??????????????USB?設(shè)備的能力。JSR-80?API?提供了比?jUSB?API?更多的功能,很有可能成為?Java?語(yǔ)言的擴(kuò)展標(biāo)準(zhǔn)。目前,只有?
??????????????Linux?開(kāi)發(fā)人員可以利用?jUSB?和?JSR-80?API?的功能。不過(guò),有人正在積極地將這兩種?API?移植到其他操作系統(tǒng)上。Java?
??????????????開(kāi)發(fā)人員應(yīng)該在不久就可以在其他操作系統(tǒng)上訪問(wèn)?USB?設(shè)備。從現(xiàn)在起就熟悉這些?API,當(dāng)這些項(xiàng)目可以在多個(gè)平臺(tái)上發(fā)揮作用時(shí),您就可以在自己的應(yīng)用程序中加入?
??????????????USB?功能了。
</ span ></ p ></ td >
????????
</ tr >
??????
</ table >