Host side USB programming using libusb

May 30, 2013

These notes pertain to the development of host side software to run on linux.

Some links

You may not need libusb

Some devices will be fully supported by an existing linux device driver. When these attach to the USB bus, the linux udev rules find a driver and these sorts of devices will usually appear as /dev/ttyUSB0, /dev/ttyACM0, or some other file in the /dev directory. You can then write software than opens these files and treats them like good old serial ports, or parallel ports, or whatever.

Other USB devices (in particular homebrew USB projects), will not be served by any existing driver. It is for these sorts of devices that you will be wanting to use libusb in one of its forms.

So many choices

It is easy to get tripped up by the various forms of libusb on linux systems.

First of all there is libusb-0.1, which you should just ignore if at all possible. You may (as I did) trip over example code online that uses the libusb-0.1 API. Here is how to tell: If it includes the file "usb.h" and the function calls all begin with "usb_" you are dealing with libusb-0.1.

If you are (like me) wanting to develop new software, you should be using libusb-1.0 (or perhaps something newer if things have moved along since I wrote this). You can recognize libusb-1.0 code because it includes the file "libusb.h" and the function calls all begin with "libusb_".

You still have some choices and issues though. Apparently after a couple of years with not activity on libusb-1.0 (and developers clamoring for things to be done), most of the original libusb developers created a fork of libusb they called libusbx and now work continues on the new fork. My impression is that you want to be using libusbx these days.

libusb on Fedora

I am (as of this writing) running Fedora 18. After I did:
yum install libusbx libusbx-devel
I got the following errors when I tried linking before I explicitly added the -lusb-1.0 line:
cc -o zapper zapper.o -lusb
/usr/bin/ld: zapper.o: undefined reference to symbol 'libusb_open_device_with_vid_pid'
/usr/bin/ld: note: 'libusb_open_device_with_vid_pid' is defined in DSO /lib64/libusb-1.0.so.0 so try adding it to the linker command line
/lib64/libusb-1.0.so.0: could not read symbols: Invalid operation
And the compiler was unable to find libusb.h before I added a -I switch. A working Makefile looks like this:
# Makefile for zapper

zapper:	zapper.o
	cc -o zapper zapper.o -lusb-1.0

zapper.o:	zapper.c
	cc -c -I/usr/include/libusb-1.0 zapper.c 

New things with USB

I include the source for the Teensy CLI loader as an example of libusb programming (although it is libusb-0.1). This was the first code I encountered that communicated with a USB device without a special file like /dev/ttyACM0.

How fast can we go?

AVR controllers that use an FTDI chip, or other serial to USB converter are limited by the slowest link (the serial port). The fastest I have seen is 115200 baud (bits/second). The USB side can send data in bursts at usb "full speed" (12 Mbits/second), but quickly runs out of data to send.

The AVR chips with native USB open up new possibilities. None of them (at least at this point in time) can do high speed, but full speed is still 100 times faster than 115200. It will be interesting to see what can be done with these devices, and libusb programming may be the way to unlock this potential.


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org