User login

A matter of parsing

Supporting a new piece of hardware in sigrok entails writing a driver for libsigrok. As a bare minimum, the driver consists of a C source file with a struct sr_dev_driver in it. That struct contains the name of the driver and a set of callbacks libsigrok will do when that driver is used — things like initializing the device, starting acquisition and so on. libsigrok provides an internal API which drivers can use to send data across the "session bus" — something which the frontend application listens on.

However, writing code is the last thing you do. When you get started, first make a page on the wiki for that device. Check out the page for a similar device, and copy its source over. This will get the page structure and categories down. Take some pictures of the device, particularly of the insides. It may well help you with the driver later on. Some guidelines for taking good PCB pictures are here.

Next, take a look at the protocol. Generally this involves running a copy of Windows in a VM (Virtualbox or VMware will do nicely) on a Linux host. When you use the device through the vendor-provided Windows software, you can sniff the USB (or whatever) traffic on the Linux host. There are many techniques to reverse engineering protocols, but essentially it involves staring at hexdumps until you understand the connection between what the vendor software sends to the device, and what the device does in response.

Whatever you find out about the protocol, document it! You want to be able to pick up where you left off, even if there's a couple of weeks between working on this. By all means, use the wiki page you created as a working document — it's not just a place to put finished protocol docs. If you get stuck, somebody else might see something in your notes that you missed.

For some devices you might even skip the VM + Windows step. Some low-end multimeters and other measurement devices don't really communicate with the vendor software: they just send data out periodically — usually a few times per second — and don't even have an input channel on which to take commands. These are generally devices with a keypad or similar controls, and a display. By simply listening to what it puts out, verifying this against what you see on the display, and putting the device through its various modes and options with the controls, you have everything you need to grok the protocol.

Once you're satisfied you've got the whole protocol documented, it's time for the driver. Creating the driver's various source files and integrating it into the build is quite a bit of work, and requires a lot of fiddling around with autotools. So to make things easier, we have a tool to do all this for you. It's called, unsurprisingly, "new-driver", and can be found in the sigrok-util repository.

The file api.c contains the struct sr_dev_driver which registers it with libsigrok. An overview of the struct and the callbacks it contains is on the hardware driver API page. All the callbacks have a stub function in api.c, with a TODO comment marking the spot where you come in. Take a look at another driver for a similar device to see how various callbacks might be implemented. The protocol.h file is included from both C files, and contains mostly the device context struct. This is specific to your driver, not shared across libsigrok. The protocol.c file is where you implement the protocol parser for your device. It has a single stub function defined: