?

< 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
&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?展示了在應用程序成功地找到了?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
&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?項目在?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
&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?展示了在應用程序成功地找到?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
&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?項目從一開始就非常活躍。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 >