This section refers to the code available in Linux-3.1. Previously, I
studied and commented on version 2.6.39, but the code has significantly
improved since that release.
The IIO documentation is available in the kernel staging tree at
iio/Documentation/. The documentation provides an overview of the main
features and a quick indication of the functions to use for a rapid
Documentation does not provides a full guide to writing an IIO driver;
for further information you need to read the drivers already developed
for IIO and use them as examples. Another source of information are the
dummy files developed to understand how to write an IIO driver.
Documentation does not provide an exhaustive description of the
mechanisms implement in the IIO core, buffers and triggers; again, for a
deeper knowledge you need to see all the code which is not always well
IIO is organized as two levels: device and channels.
device is the top level of the hierarchy and it represents the
acquisition chip. A device is described by the structures iio_info
channel is part of device; it represents a single acquisition
source of the device. A channel is described by the
IIO allocates a char device region of 256 minors; IIO assigns a minor
for each device registered, so there is only one char special file for
each device, so you can register a maximum of 256 devices.
The char device management use a single char device file for each
device. The main purpose of this file is accessing the buffer from user
space; another use is delivering events.
Aim and Features
The main purpose of IIO is providing support for analogue input devices,
typically connected through I2C or SPI; there is no support at all for
output signals. In this release there are no specific functionality to
handle digital signals, but it is not forbidden.
Channels specificity is the focus of the IIO hierarchy and the core.
Channels must have a specified type which can be only one that IIO has
defined: accelerometers, inclinometers, temperature sensors, and similar
well-defined use classes. These devices are usually based on SPI or I2C,
and this is the main IIO target. Again, IIO builds the sysfs name with
these devices in mind, so it provides modifiers for the three axis of an
accelerometers or a gyroscope, or for the light of a light sensor.
I think that IIO target is not the industrial sector intended as a
serious industrial setup with a complex sensors network, but only basic
acquisition systems for small industrial applications or personal
equipments, as well as the sensors included in atypical PC.
The functionality provided by IIO framework is aimed to create a
standard interface for driver development for acquisition chips; part of
this interface are triggers, buffers, events and sysfs. Events and sysfs
management is integrated within the IIO core, which exports utility
functions towards low-level drivers. Buffers and triggers follow the
modular approach so each developer can implement his/her buffers or
triggers and use them with IIO. Some buffer and trigger implementations
are already developed and are available in the kernel configuration;
developers with no special needs can use them.
In a context where data transfers are several mega-samples per second,
it's important to have meta-information about samples. Meta-information
allows a delayed analysis of the streams, and a logging activity about
the acquisitions. IIO does not provide this important feature; the only
meta-information exported to user space is in the so-called events
which are not really useful for logging or delayed analysis.
IIO sometimes suffers from over-engineering. Four examples are:
IIO sysfs attributes accept floating point numbers in input; then
kernel can handle only integer values so IIO must convert
a float number ASCII string into two integer variables: the integral
part and the fractional part. All this conversion is useless because
the kernel can not handle floating point values. Only integer values
should be allowed, using very fine granularity (e.g., micro-volts).
The sysfs attribute system is centralized into IIO, it creates and
destroys attributes and calculates a name for each of them. The name
is calculated from the channel features by the concatenation of some
suffixes and prefixes, thus can create very long names. A sysfs name
should be small and it should not describe the channel features.
each channel has 2 different indexes; one is the scan_index which
is used to order channels in scans within a buffer (a scan is a
set of channels to acquire); the other one, channel, is the
channel index on device, but if the indexed flag is false, then
channel is just a numerical name. Using two indexes is generally
not needed: a single index should be enough for both purposes; if a
device scans its channels in a different order from channel indexes,
then you should change channel indexes to meet the scan order, which
is more important than channel order.
IIO channels provide different precision formats and a function to
query the device about this; format precision is applied to the
fractional part. In my opinion, a framework should not handle these
details because it is a needless overhead for low-level drivers, the
framework itself and user-space. The precision may change among
devices, so each part of the acquisition system must handle this
possibility. With a fixed precision format, the meaning of each data
item in each part of the acquisition system is well known, so it is
easy to handle; if a different precision format is absolutely
low-level drivers or user-space can change it, but not the
IIO Buffer Interface
The IIO buffer interface has three main structures:
*iio_buffer_setup_ops*. They are used when a buffer instance is
enabled or disabled.
*iio_buffer_access_funcs*. It contains the buffer operations used
to gain access to the buffer.
*iio_buffer*. It is the general descriptor of a buffer. It
contains the information about the buffer status, about
channels scan and the pointers to the buffer functions, both setup
and access. Developers can also add here buffer specific sysfs
The IIO buffer interface provides the file operations for all the
buffers, and does not allow developers to define their own. The file
operations provided by IIO are really simple; for data transfer only
read() function is available, and it is just a wrap function around
the buffer operation read_first_n(), so developers when implement this
buffer operation must bear in mind that is a file operation.
read_first_n() is effectively the read() file operations but with a
subset of parameters, so limiting functionality and making it difficult
to recognize without reading the IIO core.
IIO does not handle buffer reference counting; it asks to the buffer
developers to implement an use counter of the buffer. IIO uses
mark_in_use() and unmark_in_use() from iio_buffer_access_funcs
functions to check if buffer is in use or not. IIO buffer interface does
not handle any concurrency issue and leaves them to developers of each
individual buffer implementation.
IIO does not allow users to change the buffer implementation in use; a
low-level driver chooses which implementation uses and can not be
The IIO buffer interface handles an individual sample or a group of
samples from different channels; such group is called a scan. The
buffer operation store_to() accepts a single scan to store in the
buffer; the read operations read_last() and read_first_n() return a single scan and n scans, respectively.
For our purpose this buffer interface is not good. In our main case
buffer handles millions of samples for second and we can not waste time
on the single sample, but we need to move large amount of samples
between user space and devices. Again, it is useful to have flexibility
in choosing the buffer type. IIO does not currently provide such
IIO Trigger Interface
IIO trigger interface has two main structures:
* *iio_trigger_ops*. It is the container for the triggers functions
which are handled by IIO.
* *iio_trigger*. It is the general descriptor of a trigger. It
contains information about trigger and a pointer to the trigger
functions. In IIO triggers are devices, so trigger implementations can
use device functionality; for example to define trigger specific sysfs
attributes. These sysfs attributes can not be declared in iio_trigger
but developers must use device by adding new attribute to
* *iio_poll_func*. It is a structure which contains the functions to
run on trigger fire.
A specific trigger can be associated to an IIO device by registering a
new trigger and set it in iio_device->trig. A generic trigger suitable
for different IIO device should be declared as separate module; but the
IIO mechanism to associate a trigger to a device it is no intuitive, and
it can discourage developers to create independent modules for triggers.
IIO takes track of all the registered triggers to allow users to change
the current trigger through sysfs by naming it. This operation is
possible only if the IIO device has the INDIO_BUFFER_TRIGGERED mode
enable. When the trigger implementation is an independent module, it
must provides the functions to add and remove instances of itself. A
trigger instance is the only object that an IIO device can use. The
instance management take place on user space side, so it is the user
that creates an instance and associates it to the device.
When an user tries to associate a trigger instance to an IIO device, IIO
makes a double check: it verifies if trigger is compatible with the
device in use, and it verifies if the device is compatible with the
requested trigger; if both trigger and device are compatible, framework
assigns the trigger to device.
It is not explicit, but events can be used to configure a trigger value.
Event attributes have their own methods to read and write; these methods
access to the value used as reference to generate the event. For
example, for the threshold event the value is the threshold limit for
In the last release IIO creates the common attributes but lefts to
developers the freedom to add their own; the IIO sysfs interface is
built on device which creates the sysfs tree prepared by IIO.
In IIO Developers can declare their attributes for event, buffer,
trigger and device, but not for channels. This can works for small chip,
but acquisition boards can have many register for each channel and it is
desirable that a framework allows developers to add attributes on
The attributes provided by IIO have an address field which should be
used to set up the device register addresses correspondent to the
attributes; IIO uses the field to store the bit flag which generate the
sysfs attribute and don't allow developer to specify a valid address.
Developers are free to use address to store a valid address, but only
for their own attributes.
IIO base its sysfs attributes interface on device interface, so it is
not semaphored. Concurrent processes can try to change the same
attribute at the same time with unpredictable result.
The events interface aim is to provide events notification to user
space. They are typically used to notify when trigger fires or when
hardware interrupt occurs. IIO defines a few kind of events; developers
can add their own.
IIO manage the events with a list. The iio_push_event() function add a
new occurred event to the list; the function is used
by the low-level drivers. The read()file_operations extracts an
event from the event list with FIFO policy and copy it to user space.
The file_operations to gain access to events are hide behind the
ioctl(); ioctl() calls anon_inode_get_fd() which create a file
without an inode, so without consume minors. This choice forces users to
use specific programs to read the events.
IIO allows the driver to push events although char device file is not
open; when char device file is open and it is going to be closed, IIO
flush the detected events list. This is incorrect because this procedure
deletes events which are not returned to user space. IIO applies two
opposite policies: it allows to enqueue events when file is closed; but
it flush the events list on close.
Use IIO From User Space
IIO communicate with user-space via char device and SYSFS interface. The
main purpose of SYSFS interface is to configure driver options; it is
also used to acquire a single sample from a device channel without
buffer. Char devices are used to fetch data from a buffer and from the
There is not an official user-space library for IIO programs
Developing a Driver
The aim of this paragraph it is not to provide a full guide to develop a
driver within IIO, because each device has different features and
requires different driver implementation. This is a rapid introduction
for a fast test of IIO.
The minimum lines of code to get work a low-level driver with IIO,
requires to implement the IIO functions in iio_info and an array of
iio_chan_spec, respectively to implement the device operations and to
describe the device channels; then register the device in IIO.
For example, for a simple acquisition chip the read_raw()
implementation can be enough; this operation acquires a value from
device, so it implements the low-level communication between kernel and
device; the value can be both a configuration value or a sample, the
mask parameter specifies which value acquire. You can implement the
other operations if your driver need them. Driver specific sysfs
attributes can be also defined within iio_info->attrs.
The IIO targets are the SPI and I2C devices, so you have to create the
driver for the bus in use and then register it. The driver method
probe() must be used for IIO initialization and registration, and the
driver method remove() to un-register from IIO and free data.
To register a device in IIO you have to follow the following steps in
the exact order:
* allocate an iio_device with iio_allocate_device().
* fill the iio_device fields and private date if it is needed.
* configure an iio_buffer with one of the available implementations
or your own one.
* register the configured iio_buffer with iio_buffer_register()
* register the iio_device with iio_device_register()
The registrations iio_buffer_register() and iio_device_register()
must be executed in this exact order, otherwise the sysfs creation is
wrong; there is not error or message to warn you about this.
Compare with Requirements
The following table shows how the Requirements list
items are supported by COMEDI.
There is no output, only analogue signals are explicit support.
TDC and DTC
There is no explicit support.
One-shot, burst, and streaming support
The layer structure is thought for small chips, so it provides only two level: device and channels
No hard limits on the number of bits or channels
The numer of devices is limited to 256
High-data rate, little storage overhead
IIO buffer interface handles data sample by sample, we need to handle very large amout of samples
Easy and general configuration
Only IIO specific applications can handle events; manage trigger instanse it is not clear
Offset, gain, number of bits, ...
A different set is considered "common" and does not have always the same name in each devices
Little code overhead
IIO handle semaphores only for internal use and for standard syfs attribute. Each implementations (driver, buffer, trigger) must handle with semaphores.
Flexible buffer management
IIO buffer interface handles data sample by sample, we need to handle very large amout of samples
Device-driven data transfers
Hardware time stamps
IIO make assumption on timestamp; it is a 64bit signed integer which represent nanoseconds