How to Write USB Device Driver
Level of difficulty:
Since the Microsoft Windows Operating System platform remains as the most widely implemented computer environment around the world, majority of USB-based devices are released into the computer market with accompanying device drivers that allow them to be readily used in Windows-based machines. Because of this, this guide focuses on the writing of a USB device driver for the Linux environment which undoubtedly has become the alternative Operating System for those who wish to limit the complexities and costs associated with the Windows platform. The USB subsystem of the Linux platform has evolved from supporting only the mouse and keyboard devices to more than 20 varying device types under its newer kernel with majority of unsupported devices coming from manufacturers that choose to implement vendor-specific device drivers. Since the USB protocol is emerging as the most preferred connection mechanism by majority of manufacturers, it is important that computer systems are able to host these devices by having the corresponding drivers for them to allow the computer user to take advantage of their functionality.
- Linux-based computer system
- scripting language
- computer with USB port
To create a generic USB driver skeleton, use the pci-skeleton.c file as a model. Navigate to the drivers/usb/ source tree and open this file.
The USB protocol specification of the Linux Operating System is slightly different than that of the Microsoft Windows environment. Once the pci-skeleton.c file has been accessed, it is necessary to register the driver to the Linux USB subsystem. This is done by using the usb-driver declaration which provides the name, probe, disconnect, fops, minor, and id_table information necessary to provide support for the USB device.
Once all the necessary information is provided, the USB driver registration is done by issuing the usb_register call under the init function of the driver.
Correspondingly, a deregistering function must also be created using the usb_unregister call in order to unload the driver from system memory when the device is removed from the USB port.
Under the Linux Operating System, creating a MODULE_DEVICE_TABLE that contains the vendor specific product ID will enable the Linux-hotplug system for that specific device only. The codes contained in this table will instruct the hotplug script on how to handle the USB-based device. Any USB device that matches the device ID pattern will invoke the probe function call.
The next step is to create buffers that will serve as temporary storage locations for data that must be sent to and from the device including a USB urb that will cause the writing of data to the initialized device. The device is also registered under the devfs subsystem to allow access to the USB-based component. The devfs subsystem will alert the user if the registration process fails.
Once the USB device is removed from the machine, the disconnect function must be called in order to remove any private data including pending urbs remaining in the USB system. Under this process, the devfs subsystem will also unload the corresponding device driver.
With the binding of the driver to the device, any application can communicate with the hardware via the read and write function calls to transmit and receive data between the device and the calling program. The skel_write_bulk_callback function is used to indicate the completion of the callback and signal that the urb has finished transacting with the USB subsystem.