Looking for USB

This week a friend of mine was saying how engineers hated reading directions almost as much as they hated asking for directions. Maybe that’s why we invented GPS. Too bad we don’t have the equivalent for product manuals.

Last week I wrote about communicating with a USB device (actually, a special keyboard) using libusb. However, I cheated a little because my software “knew” the keyboard’s vendor ID and its product ID. The code to open the device was:


There are two cases where that might not be enough. First, you can have a case where you don’t know exactly the device you are looking for. The other case arises when you have more than one of the same device connected to your computer.

Of course, libusb has ways to “ask for directions.” You can search through all the USB devices on your system easily. The call libusb_get_device_list will return a list of all the devices in the system. You’ll usually pass a NULL as the first argument, although you can also provide a “context” that is used when you have more than one element of your program using libusb (this is mainly of interest if you are writing a library that will use libusb and you want to avoid conflict with other libraries or the main program). If you care, you need to read the context from the call to libusb_init and pass it as the first argument.

The second argument to libusb_get_device_list is a pointer to the device list. This is effectively an array of libusb_device pointers. These pointers are like an old-fashioned C FILE type; you aren’t supposed to know what’s in them. Instead, you pass them to functions like libusb_get_bus_number or libusb_get_device_address. Often you’ll pass it to libusb_get_device_descriptor. As you might expect, this call returns things like the vendor ID, the product ID, and even a serial number you can use to tell two identical devices apart. There’s other details too (click here for more).

The libusb library uses a reference-counting system on the devices it manages. After you are done with the list, you want to send it to libusb_free_device_list. By setting the last parameter of this call to 1, you can force the reference count to decrement and thus free the whole list that you haven’t otherwise used. Just be sure to open any devices you want to use before you use this call.

Here’s a very simple program that walks through the list and prints out some basic information:

// list USB devices -- Williams
#include <stdio.h>
#include <libusb-1.0/libusb.h>

// main program
int main(int argc, char *argv[])
  struct libusb_device **devs;
  struct libusb_device_descriptor info;
  unsigned count,i;
  int rv=0;
  // init USB lib (this is the 1.0 lib)
  if (libusb_init(NULL)<0) 
      printf("Can't open libusb\n");
      return 1;
  // get list of devices and counts
  if (count<=0)
      printf("Error enumerating devices\n");
      return 2;
  // walk the list, read descriptors, and dump some output from each
  for (i=0;i<count;i++)
      printf("VID=%04x PID=%04x\n",info.idVendor,info.idProduct);
  return rv;

The device descriptor has a lot of other information in it (for example, the type of device which might be useful if you were actually hunting for, say, a USB memory stick) and information about the device’s configurations and protocols. You can use libusb_get_config_descriptor to learn even more. Of course, you can also open the device and work with it, if you choose.

By the way, I know a lot of software people get drawn more and more into hardware through their work on embedded systems since you often deal with sensors, switches, and other hardware issues in this line of work. You might be interested to know that MIT is running a free pilot online course called Circuits and Electronics from March 5 to June 8 of this year. The course covers both analog and some digital logic. From what I have seen, it is very well done. The course itself is a mixture of video and exercises. There is homework, labs (done with an online simulator), and an electronic copy of the actual textbook you’d use if you were on campus. If you complete the course (including the midterm and the final) you get a printable certificate of completion. More importantly, you’ll get a good foundation in electronic design.

Keep in mind, this is a first undergraduate course, so a lot of it will be review if you know things like Kirchoff’s law, op amps, and the like. However, if you don’t have that background, you want a refresher, or you just want to see what might be how your grandkids go to college, you can’t beat the price. Check it out at https://6002x.mitx.mit.edu.