Access USB devices from Java applicationsAn introduction to USB, jUSB, and JSR-80 |
Level: Introductory Qingye Jiang (qjiang@ieee.org), Research Scientist, HappyFox Engineering Solutions 02 Sep 2003 The Java platform has traditionally prided itself on its platform independence. While that independence has many benefits, it makes the process of writing Java applications that interact with hardware quite tricky. In this article, research scientist Qingye Jiang examines two projects that are making the process easier by providing APIs through which Java applications can make use of USB devices. While both projects are still in embryo form, both show promise and are already serving as the foundations of some real-world applications.<script language="JavaScript" type="text/javascript"> </script> The first version of the Universal Serial Bus (USB) specification was released in January 1996. Because of its low cost, high data-transfer rate, ease of use, and flexibility, USB has gained wide acceptance in the computer industry. Today, many peripherals and devices connect to computers through USB interfaces. Currently, most general-purpose operating systems provide support for USB devices, and it is relatively easy to develop applications in C or C++ that access such peripherals. However, the Java programming language by design provides very little support for hardware access, so writing Java applications that interact with USB devices has proved quite difficult. Efforts to provide access to USB devices in the Java language were initiated in 1999 by Dan Streetman at IBM. In 2001, his project was accepted as a candidate extended standard of the Java language through the Java Specification Request (JSR) process. The project is now called JSR-80 and has been officially assigned the Java package In this article, you'll get a brief introduction to the jUSB and JSR-80 projects; first, however, we'll take a look at the nuts and bolts of the USB protocol, so that you can understand how both of those projects interact with USB devices. We'll also offer code snippets to show how you'd use both projects' APIs to access USB devices. In 1994, an alliance of four industrial partners (Compaq, Intel, Microsoft, and NEC) started specifying the USB protocol. The original goal of the protocol was to connect the PC to the telephone and to provide I/O interfaces that were easy to expand and reconfigure. In January 1996, the first version of the USB specification was released, and a subsequent revision (version 1.1) was released in September 1998. The specification allowed 127 devices to be connected together at the same time, with the total communication bandwidth limited to 12 Mbps. Later on, three more members (Hewlett-Packard, Lucent, and Philips) joined the alliance. In April 2000, version 2.0 of the USB specification, which supports transfer rates up to 480 Mbps, was released. Today, USB plays a key role in high-speed (video, imaging, storage) and full-speed (audio, broadband, microphone) data-transfer applications. It also connects a variety of low-speed devices (keyboards, mice, game peripherals, virtual reality peripherals) to the PC. The USB protocol is strictly hierarchical. In any USB system there is only a single host, and the USB interface to the host computer is referred to as the host controller. There are two standards for host controllers -- the Open Host Controller Interface (OHCI, by Compaq) and the Universal Host Controller Interface (UHCI, by Intel). Both standards provide the same capabilities and work with all USB devices; the hardware implementation of a UHCI is simpler, but requires a more complex device driver (and thus puts more load onto the CPU). The USB physical interconnect is a tiered star topology, with up to seven tiers. A hub is at the center of each star, and the USB host is considered the root hub. Each wired segment is a point-to-point connection between a hub and USB device; the latter can be either another hub that provides additional attachment points to the system, or a device of some sort that provides functional capabilities. The host uses a master/subordinate protocol to communicate with the USB devices. This approach solves the problem of packet collision but also prevents the attached devices from establishing direct communication with each other. All the data transfers are initiated by the host controller. Data directed from the host to a device is called downstream or out transfer; data directed from a device to the host is called upstream or in transfer. Data transfer occurs between the host and a particular endpoint on the USB device, and the data link between the host and the endpoint is called a pipe. A given USB device may have many endpoints, and the number of data pipes between the host and the device is the same as the number of endpoints on the device. A pipe may be uni-directional or bi-directional, and the data flow in one pipe is independent of the data flow in any other pipes. Communication on the USB network can use any one of four different data transfer types:
Like a serial port, each USB port on a computer is assigned a unique identification number (port ID) by the USB controller. When a USB device is attached to a USB port, this unique port ID is assigned to the device and the device descriptor is read by the USB controller The device descriptor includes information that applies globally to the device, as well as information on the configuration of the device. A configuration defines the functionality and I/O behavior of a USB device. A USB device may have one or more configurations, which are described by their corresponding configuration descriptors. Each configuration has one or more interfaces, which can be considered as a physical communication channel; each interface has zero or more endpoints, which can be either data providers or data consumers, or both. Interfaces are described by interface descriptors, and endpoints are described by end-point descriptors. Furthermore, a USB device might also have string descriptors to provide additional information such as vendor name, device name, or serial numbers. As you can see, a protocol like USB offers challenges to developers who use the Java language, which strives for platform- and hardware-independence. Let's now take a look at two projects that have tried to bridge the gap. The jUSB project was created by Mojo Jojo and David Brownell in June 2000. Its objective was to provide a set of free software Java APIs to access USB devices on Linux platforms. The API is distributed under the Lesser GPL (LGPL), which means that you can use it in proprietary as well as free software projects. The API provides multithreaded access to multiple physical USB devices, and supports both native and remote devices. Devices with multiple interfaces can be accessed by multiple applications (or device drivers) simultaneously, with each application (or device driver) claiming a different interface. The API supports control transfers, bulk transfers, and interrupt transfers; isochronous transfers are not supported because these are used for media data (such as audio and video) that are already well supported by the JMF API (see Resources) over other standardized device drivers. Currently, the API works on GNU/Linux distributions with either the Linux 2.4 kernel or a back port into 2.2.18 kernel. Thus, most recent distributions are supported; for example, the API works on Red Hat 7.2 and 9.0 without any patches or other upgrades. The jUSB API includes the following packages:
Although the implementation of the Table 1. Interfaces and classes in jUSB
The normal procedure to access a USB device with the jUSB API is as follows:
Listing 1 illustrates how to obtain the content of a USB system with the jUSB API. The program as written simply looks at the root hub for available USB devices, but it would be easy to improve it to traverse the whole USB tree. The logic here corresponds to steps 1 through 4 above. Listing 1. Obtaining the content of a USB system with the jUSB API
Listing 2 illustrates how to perform bulk I/O with Listing 2. Performing bulk I/O with the jUSB API
The jUSB project was very active from June 2000 to February 2001. The most recent release of the API, version 0.4.4, was made available on February 14, 2001. Only some minor progress has been reported since that time, probably due to the success of the IBM group in becoming a candidate extended standard of the Java language. However, several third-party applications have been developed based on jUSB, including the JPhoto project (an application using jUSB to connect to digital cameras) and the jSyncManager project (an application using jUSB to synchronize with a Palm OS-based PDA). As noted earlier, the JSR-80 project was created by Dan Streetman at IBM in 1999. In 2001, the project was accepted as a candidate extended standard of the Java language through the Java Specification Request (JSR) process. The project is now called JSR-80 and has been officially assigned the Java package The JSR-80 project includes three packages: Although the OS-dependent implementation of the JSR-80 APIs varies from operating system to operating system, a Java programmer needs to understand only the Table 2. Interfaces and classes in the JSR-80 APIs
The normal procedure for accessing a USB device with the JSR-80 API is as follows:
In Listing 3, we obtain the content of the USB system with the JSR-80 API. The program recursively traverses through all the USB hubs on the USB system and locates all the USB devices connected to the host computer. The code corresponds to steps 1 through 3 above. Listing 3. Obtaining the content of the USB system with the JSR-80 API
Listing 4 illustrates how to perform I/O with Listing 4. Performing I/O with the JSR-80 API
The JSR-80 project has been very active from its very beginning. Version 0.10.0 of the Both the jUSB API and the JSR-80 API provide Java applications with the capability to access USB devices from a machine running the Linux operating system. The JSR-80 API provides more functionality than the jUSB API, and has the potential of becoming an extended standard of the Java language. Currently, only Linux developers can take advantage of the jUSB and JSR-80 APIs. However, active efforts to port both APIs to other operating systems have been reported. Java developers should be able to access USB devices on other operating systems in the near future. By familiarizing yourself with these APIs now, you can be ready to add USB functionality to your applications when these projects are ready for prime time on multiple platforms.
|