?
<
p
>
Java?平臺一直都以其平臺無關性自豪。雖然這種無關性有許多好處,但是它也使得編寫與硬件交互的?
??????????????Java?應用程序的過程變得相當復雜。在本文中,研究科學家蔣清野討論了兩個項目,它們通過提供使Java?應用程序可以使用?USB?
??????????????設備的?API?而使這個過程變得更容易。雖然這兩個項目仍然處于萌芽狀態,但是它們都顯示了良好的前景,并已經成為一些實用應用程序的基礎。?
????????????
</
p
>
????????????
<
p
>
通用串行總線(Universal?Serial?Bus?USB)規范的第一個版本發表于?1996年?1月。因為它的低成本、高數據傳輸率、使用容易和靈活性,USB?
??????????????在計算機行業里獲得了廣泛接受。今天,許多周邊設備和裝置都是通過?USB?接口連接到計算機上的。目前,大多數一般用途的操作系統都提供了對?
??????????????USB?設備的支持,并且用?C?或者?C++?可以相對容易地開發訪問這些外設的應用程序。不過,Java?編程語言在設計上對硬件訪問提供的支持很少,所以編寫與?
??????????????USB?設備交互的應用程序是相當困難的。?
</
p
>
?
????????????
<
p
>
IBM?的?Dan?Streetman?最早開始了在?Java?語言中提供對?USB?設備的訪問的努力。2001年,他的項目通過?
??????????????Java?規范請求(Java?Specification?Request,JSR)過程被接受為?Java?語言的候選擴展標準。這個項目現在稱為?
??????????????JSR-80?并且指定了官方包?javax.usb。同時,在?2000年?6月,Mojo?Jojo?和?David?Brownell?
??????????????在?SourceForge?開始了?jUSB?項目。這兩個項目都開發出了?Linux?開發人員可以使用的包,盡管它們都還很不完善。這兩個項目也都開始試圖向其他操作系統上的?
??????????????Java?應用程序提供對?USB?設備的訪問,盡管它們都還沒有開發出可以使用的包(參閱?參考資料?中有關本文中討論的這兩個項目及其他項目的資料)。
</
p
>
?
????????????
<
p
>
在本文中,將對?jUSB?和?JSR-80?項目作一個簡要介紹,不過,我們首先要看一下?USB?協議的具體細節,這樣您就可以理解這兩個項目是如何與?
??????????????USB?設備交互的。我們還將提供代碼片段以展示如何用這兩個項目的?API?訪問?USB?設備。?USB?介紹
</
p
>
?
????????????
<
p
>
1994年,一個由四個行業伙伴(Compaq、Intel、Microsoft?和?NEC)組成的聯盟開始制定?USB?協議。該協議最初的目的是將?
??????????????PC?與電話相連并提供容易擴展和重新配置的?I/O?接口。1996年?1月,發表了?USB?規范的第一個版本,1998年?9月發表了后續版本(版本?
??????????????1.1)。這個規范允許?127臺設備同時連接到一起,總的通信帶寬限制為?12?Mbps。后來,又有三個成員(Hewlett-Packard、Lucent?
??????????????和?Philips)加入了這個聯盟。2000年?4月,發表了?USB?規范的?2.0版本,它支持高達?480?Mbps?的傳輸率。今天,USB?
??????????????在高速(視頻、圖像、儲存)和全速(音頻、寬帶、麥克風)數據傳輸應用中起了關鍵作用。它還使各種低速設備(鍵盤、鼠標、游戲外設、虛擬現實外設)連接到?
??????????????PC?上。
</
p
>
?
????????????
<
p
>
USB?協議有嚴格的層次結構。在所有?USB?系統中,只有一個主設備,到主計算機的的?USB?接口稱為主控器(host?controller)。主控器有兩個標準??開放主控器接口(Compaq?
??????????????的?Open?Host?Controller?Interface,OHCI)和通用主控器接口(Intel?的?Universal?
??????????????Host?Controller?Interface,UHCI)。這兩個標準提供了同樣的能力,并可用于所有的?USB?設備,UHCI?
??????????????的硬件實現更簡單一些,但是需要更復雜的設備驅動程序(因而?CPU?的負荷更大一些)。
</
p
>
?
????????????
<
p
>
USB?物理互連是分層的星形拓樸,最多有七層。一個?hub?是每個星形的中心,USB?主機被認為是?root?hub。每一段連線都是?
??????????????hub?與?USB?設備的點對點連接,后者可以是為系統提供更多附加點的另一個?hub,也可以是一個提供功能的某種設備。主機使用主/從協議與?
??????????????USB?設備通信。這種方式解決了包沖突的問題,但是同時也阻止了附加的設備彼此建立直接通信。
</
p
>
?
????????????
<
p
>
所有傳輸的數據都是由主控器發起的。數據從主機流向設備稱為下行(downstream)或者輸出(out)傳輸,數據從設備流向主機稱為上?
??????????????行(upstream)或者輸入(in)傳輸。數據傳輸發生在主機和?USB?設備上特定的端點(endpoint)?之間,主機與端點之間的數據鏈接稱為管道(pipe)。?
??????????????一個給定的?USB?設備可以有許多個端點,主機與設備之間數據管道的數量與該設備上端點的數量相同。一個管道可以是單向或者是雙向的,一個管道中的數據流與所有其他管道中的數據流無關。
</
p
>
?
????????????
<
p
>
USB?網絡中的通信可以使用下面四種數據傳輸類型中的任意一種:
</
p
>
?
????????????
<
p
>
控制傳輸:?這些是一些短的數據包,用于設備控制和配置,特別是在設備附加到主機上時。?
</
p
>
????????????
<
p
>
批量傳輸:?這些是數量相對大的數據包。像掃描儀或者?SCSI?適配器這樣的設備使用這種傳輸類型。?
</
p
>
?
????????????
<
p
>
中斷傳輸:?這些是定期輪詢的數據包。主控器會以特定的間隔自動發出一個中斷。?
</
p
>
????????????
<
p
>
等時傳輸:?這些是實時的數據流,它們對帶寬的要求高于可靠性要求。音頻和視頻設備一般使用這種傳輸類型。?
</
p
>
????????????
<
p
>
像串行端口一樣,計算機上每一個?USB?端口都由?USB?控制器指定了一個惟一的標識數字(端口?ID)。當?USB?設備附加到?
??????????????USB?端口上時,就將這個?惟一端口?ID?分配給這臺設備,并且?USB?控制器會讀取設備描述符。設備描述符包括適用于該設備的全局信息、以及設備的配置信息。配置定義了一臺?
??????????????USB?設備的功能和?I/O?行為。一臺?USB?設備可以有一個或者多個配置,這由它們相應的配置描述符所描述。每一個配置都有一個或者多個接口,它可以視為一個物理通信渠道?
??????????????;每一個接口有零個或者多個端點,它可以是數據提供者或者數據消費者,或者同時具有這兩種身份。接口由接口描述符描述,端點由端點描述符描述。并且一臺?
??????????????USB?設備可能還有字符串描述符以提供像廠商名、設備名或者序列號這樣的附加信息。
</
p
>
?
????????????
<
p
>
正如您所看到的,像?USB?這樣的協議為使用?Java?這種強調平臺和硬件無關性的語言的開發人員提出了挑戰。現在讓我們看兩個試圖解決這個問題的項目。
</
p
>
?
????????????
<
p
><
span?
class
="f14"
><
b
>
jUSB?API
</
b
></
span
></
p
>
????????????
<
p
><
span?
class
="f14"
>
?jUSB?項目是由?Mojo?Jojo?和?David?Brownell?于?2000年?
??????????????6月創立的。其目標是提供一組免費的、在?Linux?平臺上訪問?USB?設備的?Java?API。這個?API?是按照?Lesser?
??????????????GPL?(LGPL)條款發表的,這意味著您可以在專有和免費軟件項目中使用它。這個?API?提供了對多個物理?USB?設備的多線程訪問,并支持本機和遠程設備。具有多個接口的設備可以同時被多個應用程序(或者設備驅動程序)所訪問,其中每一個應用程序(或者設備驅動程序)都占據一個不同的接口。該?
??????????????API?支持控制傳輸、批量傳輸和中斷傳輸,不支持等時傳輸,因為等時傳輸用于媒體數據(如音頻和視頻),JMF?API?已經在其他標準設備驅動程序上對此提供了很好的支持(參閱?
??????????????參考資料)。當前,該?API?可以在具有?Linux?2.4?核心或者以前的?2.2.18?核心的?GNU/Linux?版本上工作。因此可支持大多數最新的版本,例如,該?
??????????????API?可以在沒有任何補丁或者升級的?Red?Hat?7.2?和?9.0?上工作。
</
span
></
p
>
????????????
<
p
><
span?
class
="f14"
>
?jUSB?API?包括以下包:
<
br
>
??????????????
<
br
>
??????????????·usb.core:?這個包是?jUSB?API?的核心部分。它使得?Java?應用程序可以從?USB?主機訪問?USB?設備。
<
br
>
??????????????·usb.linux:?這個包包含?usb.core.Host?對象的?Linux?實現、bootstrapping?支持和其他可以提升?
??????????????Linux?USB?支持的類。這個實現通過虛擬?USB?文件系統(usbdevfs)訪問?USB?設備。
<
br
>
??????????????·usb.windows:?這個包包含?usb.core.Host?對象的?Windows?實現、bootstrapping?支持和其他可以提升?
??????????????Windows?USB?支持的類。這個實現仍然處于非常初級的階段。
<
br
>
??????????????·usb.remote:?這個包是?usb.core?API?的遠程版本。它包括一個?RMI?proxy?和一個?daemon?
??????????????應用程序,它讓?Java?應用程序可以訪問遠程計算機上的?USB?設備。
<
br
>
??????????????·usb.util:?這個包提供了一些有用的實用程序,可以將?firmware下載到?USB?設備上、將?USB?系統的內容轉儲到?
??????????????XML?中、以及將只有?bulk?I/O?的?USB?設備工具轉換成一個套接字(socket)。
<
br
>
??????????????·usb.devices:?這個可選包收集了用?jUSB?API?訪問不同?USB?設備的?Java?代碼,包括柯達數碼相機和?
??????????????Rio?500?MP3?播放器。這些?API?經過特別編寫以簡化訪問特定?USB?設備的過程,并且不能用于訪問其他設備。這些?API?
??????????????是在?usb.core?API?之上構建的,它們可以工作在所有支持?jUSB?的操作系統上。
<
br
>
??????????????·usb.view:?這個可選包提供了基于?Swing?的?USB?樹簡單瀏覽器。它是一個展示?jUSB?API?應用的很好的示例程序。
</
span
></
p
>
????????????
<
p
><
span?
class
="f14"
>
?盡管?usb.core.Host?對象的實現對于不同的操作系統是不同的,但是?Java?
??????????????程序員只需要理解?usb.core?包就可以用?jUSB?API?開始應用程序的開發。表?1?列出了?usb.core?的接口和類,Java?
??????????????程序員應該熟悉它們:
</
span
></
p
>
????????????
<
p
><
span?
class
="f14"
>
?表?1.?jUSB?中的接口和類
</
span
></
p
>
????????????
<
span?
class
="f14"
>
????????????
<
table?
width
="90%"
?border
="1"
?align
="center"
?cellPadding
="2"
?cellSpacing
="0"
?class
="content"
>
??????????????
<
tbody
>
????????????????
<
tr
>
??????????????????
<
td
>
接口
</
td
>
??????????????????
<
td
>
說明
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td
>
Bus
</
td
>
??????????????????
<
td
>
將一組?USB?設備連接到?Host?上
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td
>
Host
</
td
>
??????????????????
<
td
>
表示具有一個或者多個?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%"
>
類
</
td
>
??????????????????
<
td?
width
="83%"
>
說明
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td?
width
="17%"
>
Configuration
</
td
>
??????????????????
<
td?
width
="83%"
>
提供對設備所支持的?USB?
????????????????????配置的訪問,以及對與該配置關聯的接口的訪問
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td?
width
="17%"
>
Descriptor
</
td
>
??????????????????
<
td?
width
="83%"
>
具有?USB?
????????????????????類型的描述符的實體的基類
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td?
width
="17%"
>
Device
</
td
>
??????????????????
<
td?
width
="83%"
>
提供對?USB?設備的訪問
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td?
width
="17%"
>
DeviceDescriptor
</
td
>
??????????????????
<
td?
width
="83%"
>
提供對?USB?設備描述符的訪問
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td?
width
="17%"
>
EndPoint
</
td
>
??????????????????
<
td?
width
="83%"
>
提供對?USB?
????????????????????端點描述符的訪問、在給定設備配置中構造設備數據輸入或者輸出
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td?
width
="17%"
>
HostFactory
</
td
>
??????????????????
<
td?
width
="83%"
>
包含?bootstrapping?方法
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td?
width
="17%"
>
Hub
</
td
>
??????????????????
<
td?
width
="83%"
>
提供對?USB?hub?描述符以及一些?hub?
????????????????????操作的訪問
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td?
width
="17%"
>
Interface
</
td
>
??????????????????
<
td?
width
="83%"
>
描述一組端點,并與一個特定設備配置相關聯
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
??????????????????
<
td?
width
="17%"
>
PortIdentifier
</
td
>
??????????????????
<
td?
width
="83%"
>
為?USB?
????????????????????設備提供穩定的字符串標識符,以便在操作和故障診斷時使用
</
td
>
????????????????
</
tr
>
??????????????
</
tbody
>
????????????
</
table
>
????????????
</
span
>
?
<
p
><
span?
class
="f14"
><
br
>
??????????????用?jUSB?API?訪問一臺?USB?設備的正常過程如下:
<
br
>
??????????????
</
span
><
span?
class
="f14"
><
br
>
??????????????·通過從?HostFactory?得到?USB?Host?進行?Bootstrap。
<
br
>
??????????????·從?Host?訪問?USB?Bus,然后從這個?Bus?訪問?USB?root?hub(即?USB?Device)。
<
br
>
??????????????·得到?hub?上可用的?USB?端口數量,遍歷所有端口以找到正確的?Device。
<
br
>
??????????????·訪問附加到特定端口上的?USB?Device。可以用一臺?Device?的?PortIdentifier?直接從?Host?訪問它,也可以通過從?
??????????????root?hub?開始遍歷?USB?Bus?找到它。
<
br
>
??????????????·用?ControlMessage?與該?Device?直接交互,或者從該?Device?的當前?Configuration?中要求一個?
??????????????Interface,并與該?Interface?上可用的?Endpoint?進行?I/O?。
</
span
></
p
>
????????????
<
p
><
span?
class
="f14"
>
清單?1?展示了如何用?jUSB?API?獲得?USB?系統中的內容。這個程序編寫為只是查看?
??????????????root?hub?上可用的?USB?設備,但是很容易將它改為遍歷整個?USB?樹。這里的邏輯對應于上述步驟?1?到步驟?4。
</
span
></
p
>
????????????
<
p
><
span?
class
="f14"
>
清單?1.?用?jUSB?API?獲得?USB?系統的內容
</
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
<
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
<
=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?展示了在應用程序成功地找到了?Device?的條件下,如何與?Interface?
??????????????和?EndPoint?進行批量?I/O。?這個代碼段也可以修改為執行控制或者中斷?I/O。它對應于上述步驟?5。
</
span
>
????????????
<
p
><
span?
class
="f14"
>
?清單?2.?用?jUSB?API?執行批量?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
<
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
<
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?項目在?2000年?6月到?2001年?2月期間非常活躍。該?API?的最新的版本?
??????????????0.4.4發表于?2001年?2月?14日。從那以后只提出了很少的改進,原因可能是?IBM?小組成功地成為了?Java?語言的候選擴展標準。不過,基于?
??????????????jUSB?已經開發出一些第三方應用程序,包括?JPhoto?項目(這是一個用?jUSB?連接到數碼照相機的應用程序)和?jSyncManager?
??????????????項目(這是一個用?jUSB?與使用?Palm?操作系統的?PDA?同步的應用程序)。
</
span
>
?
</
p
>
????????????
<
p
><
span?
class
="f14"
><
b
>
JSR-80?API?(javax.usb)
</
b
></
span
>
????????????
<
p
><
span?
class
="f14"
>
正如前面提到的,JSR-80?項目是由?IBM?的?Dan?Streetman?于?1999年創立的。2001年,這個項目通過?
??????????????Java?規范請求(JSR)過程被接受為?Java?語言的候選擴展標準。這個項目現在稱為?JSR-80?并且被正式分派了?Java?
??????????????包?javax.usb。這個項目使用?Common?Public?License?的許可證形式,并通過?Java?Community?
??????????????Process?進行開發。這個項目的目標是為?Java?平臺開發一個?USB?接口,可以從任何?Java?應用程序中完全訪問?USB?
??????????????系統。JSR-80?API?支持?USB?規范所定義的全部四種傳輸類型。目前,該?API?的?Linux?實現可以在支持?2.4?
??????????????核心的大多數最新?GNU/Linux?版本上工作,如?Red?Hat?7.2?和?9.0。
</
span
>
????????????
<
p
><
span?
class
="f14"
>
?JSR-80?項目包括三個包:javax-usb?(javax.usb?API)、javax-usb-ri?
??????????????(操作系統無關的基準實現的公共部分)以及?javax-usb-ri-linux?(Linux?平臺的基準實現,它將公共基準實現鏈接到?
??????????????Linux?USB?堆棧)。所有這三個部分都是構成?Linux?平臺上?java.usb?API?完整功能所必需的。在該項目的電子郵件列表中可以看到有人正在致力于將這個?
??????????????API?移植到其他操作系統上(主要是?Microsoft?Windows),但是還沒有可以工作的版本發表。
</
span
>
????????????
<
p
><
span?
class
="f14"
>
?盡管?JSR-80?API?的操作系統無關的實現在不同的操作系統上是不同的,但是?Java?
??????????????程序員只需要理解?javax.usb?包就可以開始開發應用程序了。表?2?列出了?javax.usb?中的接口和類,?Java?
??????????????程序員應該熟悉它們:
</
span
>
????????????
<
p
><
span?
class
="f14"
>
?表?2.?JSR-80?API?中的接口和類
</
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%"
>
說明
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
?
??????????????????
<
td?
width
="25%"
>
UsbConfiguration
</
td
>
??????????????????
<
td?
width
="75%"
>
表示?USB?設備的配置
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
?
??????????????????
<
td?
width
="25%"
>
UsbConfigurationDescriptor
</
td
>
??????????????????
<
td?
width
="75%"
>
USB?配置描述符的接口
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
?
??????????????????
<
td?
width
="25%"
>
UsbDevice
</
td
>
??????????????????
<
td?
width
="75%"
>
USB?設備的接口
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
?
??????????????????
<
td?
width
="25%"
>
UsbDeviceDescriptor
</
td
>
??????????????????
<
td?
width
="75%"
>
USB?設備描述符的接口
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
?
??????????????????
<
td?
width
="25%"
>
UsbEndpoint
</
td
>
??????????????????
<
td?
width
="75%"
>
USB?端點的接口
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
?
??????????????????
<
td?
width
="25%"
>
UsbEndpointDescriptor
</
td
>
??????????????????
<
td?
width
="75%"
>
USB?端點描述符的接口
</
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?實現的接口
</
td
>
????????????????
</
tr
>
??????????????
</
tbody
>
????????????
</
table
>
????????????
<
br
>
????????????
<
table?
width
="90%"
?border
="1"
?align
="center"
?cellPadding
="2"
?cellSpacing
="0"
?class
="content"
>
??????????????
<
tbody
>
????????????????
<
tr
>
?
??????????????????
<
td?
width
="25%"
>
類
</
td
>
??????????????????
<
td?
width
="75%"
>
說明
</
td
>
????????????????
</
tr
>
????????????????
<
tr
>
?
??????????????????
<
td?
width
="25%"
>
UsbHostManager
</
td
>
??????????????????
<
td?
width
="75%"
>
javax.usb?的入口點
</
td
>
????????????????
</
tr
>
??????????????
</
tbody
>
????????????
</
table
>
????????????
</
span
>
????????????
<
p
><
span?
class
="f14"
>
用?JSR-80?API?訪問?USB?設備的正常過程如下:
<
br
>
??????????????
<
br
>
??????????????·通過從?UsbHostManager?得到相應的?UsbServices?進行?Bootstrap。
<
br
>
??????????????·通過?UsbServices?訪問?root?hub。在應用程序中?root?hub?就是一個?UsbHub。
<
br
>
??????????????·獲得連接到?root?hub?的?UsbDevices?清單。遍歷所有低級?hub?以找到正確的?UsbDevice。
<
br
>
??????????????·用控制消息(UsbControlIrp)與?UsbDevice?直接交互,或者從?UsbDevice?的相應?UsbConfiguration?
??????????????中要求一個?UsbInterface?并與該?UsbInterface?上可用的?UsbEndpoint?進行?I/O。
<
br
>
??????????????·如果一個?UsbEndpoint?用于進行?I/O,那么打開與它關聯的?UsbPipe。通過這個?UsbPipe?可以同步或者異步提交上行數據(從?
??????????????USB?設備到主計算機)和下行數據(從主計算機到?USB?設備)。
<
br
>
??????????????·當應用程序不再需要訪問該?UsbDevice?時,關閉這個?UsbPipe?并釋放相應的?UsbInterface。
<
br
>
??????????????
<
br
>
??????????????在清單?3?中,我們用?JSR-80?API?獲得?USB?系統的內容。這個程序遞歸地遍歷?USB?系統上的所有?USB?hub?
??????????????并找出連接到主機計算機上的所有?USB?設備。這段代碼對應于上述步驟?1?到步驟?3。
</
span
></
p
>
????????????
<
p
><
span?
class
="f14"
>
?清單?3.?用?JSR-80?API?獲得?USB?系統的內容
</
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
<
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?展示了在應用程序成功地找到?Device?后,如何與?Interface?和?EndPoint?
??????????????進行?I/O。這段代碼還可以修改為進行所有四種數據傳輸類型的?I/O。它對應于上述步驟?4?到步驟?6。
</
span
></
p
>
????????????
<
p
><
span?
class
="f14"
>
?清單?4.?用?JSR-80?API?進行?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
<
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
<
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?項目從一開始就非常活躍。2003年?2月發表了?javax.usb?API、RI?
??????????????和?RI?的?0.10.0?版本。看起來這一版本會提交給?JSR-80?委員會做最終批準。預計正式成為?Java?語言的擴展標準后,其他操作系統上的實現會很快出現。Linux?
??????????????開發者團體看來對?JSR-80?項目的興趣比?jUSB?項目更大,使用?Linux?平臺的?javax.usb?API?的項目數量在不斷地增加。
</
span
></
p
>
????????????
<
p
><
span?
class
="f14"
><
b
>
結束語
</
b
></
span
></
p
>
????????????
<
p
><
span?
class
="f14"
>
?jUSB?API?和?JSR-80?API?都為應用程序提供了從運行?Linux?操作系統的計算機中訪問?
??????????????USB?設備的能力。JSR-80?API?提供了比?jUSB?API?更多的功能,很有可能成為?Java?語言的擴展標準。目前,只有?
??????????????Linux?開發人員可以利用?jUSB?和?JSR-80?API?的功能。不過,有人正在積極地將這兩種?API?移植到其他操作系統上。Java?
??????????????開發人員應該在不久就可以在其他操作系統上訪問?USB?設備。從現在起就熟悉這些?API,當這些項目可以在多個平臺上發揮作用時,您就可以在自己的應用程序中加入?
??????????????USB?功能了。
</
span
></
p
></
td
>
????????
</
tr
>
??????
</
table
>