LKD - #5 Notes on how the iio subsystems work
As part of my classes on Open Source Software (OSS) my whole class is starting to work on Linux Kernel Development. This post is a series of my experiences throughout the class related to kernel development. This post is a follow-up of this previous post and part of this series.
Note: This post is a companion to the The iio_simple_dummy Anatomy and IIO Dummy module Experiment One: Play with iio_dummy tutorials from FLUSP. I recommend following the tutorials first and then coming back here for my notes and troubleshooting tips.
In the last post we discussed how to submit linux patches. In today's post we will investigate and dive deep into the IIO subsystem.
What is the IIO subsystem in linux kernel?
The main purpose of the Industrial I/O subsystem (IIO) is to provide support for devices that in some sense perform either analog-to-digital conversion (ADC) or digital-to-analog conversion (DAC) or both. The aim is to fill the gap between the somewhat similar hwmon and input subsystems. Hwmon is directed at low sample rate sensors used to monitor and control the system itself, like fan speed control or temperature measurement. Input is, as its name suggests, focused on human interaction input devices (keyboard, mouse, touchscreen). In some cases there is considerable overlap between these and IIO.
Devices that fall into this category include:
- analog to digital converters (ADCs)
- accelerometers
- capacitance to digital converters (CDCs)
- digital to analog converters (DACs)
- gyroscopes
- inertial measurement units (IMUs)
- color and light sensors
- magnetometers
- pressure sensors
- proximity sensors
- temperature sensors
Usually these sensors are connected via SPI or I2C. A common use case of the sensors devices is to have combined functionality (e.g. light plus proximity sensor).
This excerpt was extracted from Industrial I/O Introduction.
That's what the IIO subsystem is for, supporting real hardware related to Industrial Input Output devices. This ranges from Raspberry Pi all the way to Linux servers which depend on these services.
On the IIO dummy Anatomy
Following the The iio_simple_dummy Anatomy tutorial, we were able to get a pretty good overview of how the IIO subsystem works by dissecting a toy driver instead of jumping into real hardware.
We were able to see which channels are set up with iio_chan_spec and all its
fields (.type, .indexed, .differential, the info masks that control what
attributes each channel exposes), and then how the read_raw and write_raw
functions use the mask and channel type as a sort of routing mechanism to figure
out which piece of state to access.
We also dove deep into how the probe function works, that's the function
responsible for allocating memory, initializing device fields and register the
device. The highlight for me was the use of kzalloc, the kernel variant
of allocating a memory and setting it to zero, it is similar to calloc, but it
handles under the hood
some kernel magic
(which contains many hard-to-navigate macros). It was also interesting to see how the
error handling works, with "gotos" to the specific error handling scope and
not some fancy throw catch manipulation which is used by more modern languages.
On the creation of a Driver
In the
IIO Dummy module Experiment One: Play with iio_dummy
we created a dummy driver enabled by the nconfig menu and then we compiled,
loaded and unloaded the module (iio_dummy). We were able to also create a new
device and add it to the devices running in IIO. This tutorial was pretty smooth
to navigate having completed the previous ones.
The addition of the channels for a 3-axis compass was very similar to the code in the IIO Dummy channels, but it was weird because, the way the code is setup does not seem like the usual "user space" I thought it was made to.
Conclusion
Both posts were very useful for understanding the IIO structure and during the contribution this deep dive will be very useful for understanding what we are actually changing and to not break anything (mainly user space).
References
[1] The iio_simple_dummy Anatomy, FLUSP, IME-USP
[2] IIO Dummy module Experiment One: Play with iio_dummy, FLUSP, IME-USP
[3] IIO Introduction, The kernel development community