Hello once again. It has been a while since I updated any thing on the blog. It was not because there is nothing for me to update on the blog, but because I have very less time to work on the blog articles lately. This post, as the topic implies, will consider about one of the trivial technique that Embedded programmers should understand nowadays. That is how to connect the device using USB.
Even though there are millions of standalone embedded devices, there are tens of millions of embedded devices which eventually will come across a state where it should be connected with a PC. There are various ways to perform this, for example using WiFi, Bluetooth, Serial, Parellel, etc.. But among all these technologies most popular and most effective communication method would be through USB. Nowadays there are plethora of devices which implement USB communication.
In order to understand USB, I recommend reading following two websites,
With that introduction let me move into the area of interest, LibUSB.
‘libusb’ WAS a very popular open source library which has all the routines required to communicate to devices through USB.Originally this was developed for Linux environment. But currently it has evolved into many platforms, such as Wndows, MAC OS, etc.. I would be targeting this article towards Windows O/S.
In order to communicate with any USB device you need a driver. In a nutshell, the driver is the software component which will send whatever the data in between the device and the PC (this definition is not always correct). There are many specific complexities in drivers and I will not go into details of those. The driver will expose a set of commands called IOCTLs (Input Output Controls) to allow any user to talk with the driver. So if an application developer wants to call these IOCTLs the developer should know all the commands and will have to create them and send them to the device. Which is easier said than done. Because a simple action might be broken down into several IOCTLs. But this is highly flexible.
In order to make the life of the Application (PC side) developer easy, it is always better to have some sort of a library/API which wraps up all the complex IOCTLs and provide us with a set of very simple functions to do general read, write and control operations without removing much of the flexibility. This is exactly what LibUSB is capable of.
There are many versions of LibUSB which has various types of functionalities. Let’s consider some, I will only talk about libsub in Windows context because I don’t have experience in Linux context. Following are the main libusb projects that are available,
libusb-win32: official page http://sourceforge.net/apps/trac/libusb-win32/wiki
libusbK: official page http://libusbk.sourceforge.net/UsbK3/index.html
libusb: official page http://libusb.info/
You can learn about these three libraries through above links, but I will try to give some general information about them.
In Windows operating systems you can use a Windows library called WinUSB to communicate with USB devices. But WinUSB does not provide support for ‘isochronous’ transfers for operating systems up-to Windows 7. Also, since it’s Windows proprietary you will not have much flexibility. But if it did not work, you will be able to blame Windows and ease your self.
libusb-win32 can communicate to devices using it’s own driver called ‘libsub0.sys’ which is an open source WDM driver. The application side source code needs to be linked against ‘libsub0.dll’ to be able to communicate with the driver and then the device. But the libusb0.dll cannot be statically linked with the application you create. So if you want to distribute it the dll should also be provided.
libusbK is the next generation of libusb-win32. It has more functions and more flexibility in terms of usage. The library can use either libusbK.sys, libusb0.sys or WinUSB.sys to communicate with the device. The application should be linked against the libusbK.dll to provide these functionalities. LibusbK can be statically linked with your application. If you want to replace WinUSB libraries, liibusbK is a great option. Note that libusbK.sys is a KMDF driver which is robust.
Note that libusb-win32 and libusbK can only be used in Windows environments.
libusb is a cross platform USB library which is under active development. Which is the best of all libusb libraries. The specialty of this version is that it has the same API for all the OS platforms. So the same code can be compiled to work for Windows as well as Linux, which is really is if you wish the application to be cross platform. It even supports USB 1.0 to USB 3.0. This library can use libsub0.sys, libusbK.sys, WinUSB.sys and HID drivers for it’s operation. This uses libusbk.dll for both lisbusbK.sys and libusb0.sys accesses.
These are the basic things you need to know. Please note that these drivers are not for VCP USB class. That is what we know as COM ports. There what it does is as soon as firmware presents itself as a VCP then windows connects a usbser.sys driver to enable serial communication with that device, which is not actually USB. But if you want to provide USB communication to you custom device libusb should be you first option as a driver and a library.
Let’s say you developed a firmware which will enumerate you USB device as a vendor specific unknown device in the OS. Since you have the VID and PID of your own device using the tools available in the libusb websites you can easily install the required USB driver for the device. Then you need to open the code editor of your choice and link against the relevant ‘dll’ file. After that you can directly access the device through the exposed API functions which are very clearly documented in the libusb websites.