Lets talks about drivers! Drivers exist to create a high-level interface for low-level hardware. Drivers are the intermediaries between hardware and applications. When they work well, you probably don’t notice them very much. And when they don’t, it can be a challenge to to figure out what went wrong.
Recently, we have seen the addition of the LMS7002M dual transceiver to the Lime Microsystems product family, and an accompanying addition to the open-source lms-suite software package. In this post, I will discuss the current state of the lms-suite drivers and purposed improvements to the suite. And then we will open this discussion to the community forum to encourage feedback and the sharing of ideas.
Current LMS-Suite
The lms-suite is an open-source C++ driver and GUI application for the LMS6002D and LMS7002M RFIC transceivers. The driver provides an abstraction for the registers and higher level calls like calibration and tuning the frontend. In addition, there is a control panel GUI which provides detailed and well organized access to the various capabilities of the RFIC. The suite was flexible enough to be adapted into a stand-alone driver for the Novena RF board. That said, I have some criticisms of the software suite that I would like to bring-up to encourage a productive discussion, and possible restructuring of the driver to improve its utility for other developers.
- The code for the lms-suite is not organized into a stand-alone library. Instead, its more or less a part of larger GUI control panel. However, it was easy enough to separate out the relevant sources and compile them into the Novena RF driver.
- There is an abstraction for supporting arbitrary hardware. However, there is a bit of code that selects between several board-specific implementations. I felt that extending this to new hardware was either invasive and more challenging that it should be.
- The abstraction for hardware relies on a packet-like protocol and some specific state machines in an adjoining FPGA connected to the RFIC. I think this makes an assumption about the board design and how the RFIC is connected to the host.
Driver design goals
I have worked on drivers for hardware in the SDR realm for many years now. And from that perspective, here are some basic requirements that I would look for in a RFIC or similar support library:
- Low level language: A reusable driver library should always be written in a low level language like C or C++. The runtime-overhead, the size of the binaries, and the additional dependencies are all minimal. This gives the maximum flexibility to embed this into a hardware driver or end-use application.
- Minimal dependencies: Much like the above requirement, additional library dependencies (like a thread library) can be a burden. Those dependencies carry all the way over the end-use application and can make it potentially difficult to deploy on some systems.
- Hardware independent: The RFICs are configured with SPI and GPIO, but how the host can access to SPI and GPIO is potentially limitless. One device might use spidev on embedded linux machine, on another — a memory mapped FPGA core. The library doesn’t know how my hardware works, so I need a way to customize how the communication takes place.
- Open source code: Users will need to compile, embed, debug, modify, and hopefully upstream changes to the driver. And open driver is a necessity for development — and a requirement for some open-source licensing models.
- Good API abstraction: The vast majority of uses should be wrapped up in simple and straightforward API calls. We will always need low level access to registers for more complicated situations. But the idea is that most developers should be able to immediately access and test the functionality of the hardware without diving deep into the intricacies of register maps and multi-step configuration.
Suite restructuring
Given those design goals, and taking into account the issues I experienced with the current lms-suite, I would like to propose some changes to the suite. Hopefully, these changes are not drastic, but more of a guided-restructuring to streamline a developer’s experience to make the most out of code-reuse.
- Stand-alone library: I would take all of the core driver code, without the hardware specific parts, and without the GUI control panel, and stick it into its own clearly separable stand-alone library (lms-driver). Because this library will be the bare minimum, it will be easier to version control, create pre-built packages for it like debs, rpms, exes. Developers will be able to choose to use it as a library, or to simply embed the code wholesale into their application.
- Communication abstraction: This purposed communication abstraction is the place for all hardware-specific knowledge. It will be based around register and GPIO access, and possibly cover other misc niche cases. A developer will create an overloaded communication class for their specific hardware, and hand this object to the lms driver instance. All the driver instance understands is this interface to registers and GPIO. Several pre-existing overloads of this board communication class will stand as examples — like for the evaluation hardware.
- Very high level API calls: Without precluding advanced uses, I would like to see overly simplified high level access controls added to the driver API. Examples: initialization with automatic calibration, setting gains, filter bandwidths, clock rates, tuning the frontend. Even if the settings are sub-optimal, the goal is to give the developer the confidence that the hardware is working properly before getting deeper into the configuration.
- GUI control panel library: The graphical control panel application used with the eval boards is a really useful general purpose testing tool. We would like to make sure that anyone designing new hardware based on Lime RFICs would be able to make use of this GUI to test and validate their creation. I purpose that most of the GUI code gets moved into another hardware-independent library.
- Glueing it all together: The developer links together the lms-driver, a custom communication interface, and the GUI library into an executable graphical application. This means that the software for Lime-based evaluation board like EVB7 and a custom design can reuse 99% of the code without modification and only differs in the hardware-specific glue logic.
Embedded kernel/firmware
Another interesting use case that’s not covered here is embedding the driver into firmware or a linux kernel for example. Certainly, this poses an issue for the larger lms-suite which is C++, requires on an OS with a MMU, and uses floating point math. This firmware/kenel use case is basically asking for another driver based on C and fixed point math. Fortunately, I’m also working on a C-based driver for the LMS7002M. After additional host-based testing, parts of it will be re-written in fixed point for use within the linux kernel. I’m not sure how to work this in with the rest of the lms-suite, but I’m sure it will be a valuable asset for hardware developers that are looking to very tightly integrate the hardware.
Poll and further discussion
We’ve created a poll and would really appreciate it if you could take the time to complete this:
https://www.surveymonkey.com/s/lmssuite
Should you be interested in contributing to the discussion further please post to the LMS Driver category on Discourse: