Select Page

Industrial I/O under Linux

Integration of sensors and actuators with Industrial I/O in Linux

Author: Andreas Klinger, IT-Klinger

Contribution – Embedded Software Engineering Congress 2017

Since 2011, the Linux kernel has included the Industrial Input/Output Subsystem, or IIO for short. The rather active community around the linux-iio mailing list has since released almost 248 IIO drivers (stable v4.13, without variations or staging) into the mainline. Examples include AD and DA converters, accelerometers, and sensors for light, humidity, air pressure, temperature, and more. What are the special features of IIO drivers, and how can I use them in my project? This article addresses precisely that. To make the explanation more practical and less theoretical, a specific project has been chosen as an example, presented in a somewhat simplified form.

What is Industrial I/O in Linux?

The Industrial I/O subsystem in the Linux kernel serves to standardize access to sensors and actuators. With traditional character devices, a separate driver with its own functions and often quite individual userspace interface (e.g., ioctl(), sysfs attributes, use of timers) is implemented for each device. This often means that access to different drivers has to be implemented separately. Even with drivers of the same type, such as temperature sensors, it is unlikely that two drivers will offer the same interface. If a sensor is replaced by another, the application must be adapted to the new driver.

This is where Industrial-IO comes in, with the aim of standardizing both the interface for drivers that supply data and for the use of the data in userspace.

Application example: Bee scales

The project chosen for this topic aims to measure the weight of beehives. Several use cases exist for this. The mass is recorded to answer the following questions:

  • Measurement of feed consumption (honey) during wintering with identification of starving colonies
  • Tracking the nectar flow and thus the accumulated honey in order to extract it.
  • Recognition of swarms as a natural division of the population, with the possibility of capturing them in time and founding a new population.
  • Environmental data is collected at the apiary with the aim of:
  • Ambient temperatures above 12°C lead to significant flight activity.
  • Bees are often more likely to sting when air pressure drops.

The sketch in Figure 1 (see PDF) explains the information flow from the load cell on which the beehive stands, via the AD converter (hx711) to the IIO sensor in the Linux kernel, connected via GPIO bit-banging.

Temperature, air pressure and humidity can be measured with the BME280 sensor, as shown in Figure 2 (see PDF) shown. This in turn can be addressed via I2C or SPI and evaluated by an IIO sensor.

Hardware interfaces

directly supported by the framework

  • I2C
  • SPI
  • GPIO

Implementing drivers for these interfaces is particularly easy, as a whole range of helper functions are available. Other hardware interfaces are not excluded and can also be used. In some cases, slightly more implementation may be required.

Data exchange can also occur via DMA without any telegram communication. In this case, the data is written directly from the device to a memory area without the need for explicit telegram communication. Notification of written data then occurs via an interrupt.

The relationships both downwards to the hardware and upwards to the userspace are shown in Figure 3 (see PDF) shown as an example.

Interfaces to the userspace

From within userspace, the sensors can be queried and configured via a unified interface. A dedicated bus system called iio exists for this purpose. Accordingly, the registered devices can be found in subdirectories of /sys/bus/iio/devices.

In Figure 4 (see PDFThe following is an example of a voltage value read from an analog-to-digital converter (ADC). The individual name components are systematically assembled and are therefore well-suited for use with an algorithm. The `lsiio` tool from the `tools/iio/` directory of the kernel sources can be used to query which I/O devices were detected and what number they were assigned.

root@waage: lsiio -v

Device 000: bme280
in_temp_input
in_humidityrelative_input
in_pressure_input

Device 001: hx711
in_voltage0_raw
in_voltage1_raw

In this example, there are two I/O devices. I/O device 000 implements the BME280 temperature, air pressure, and humidity sensor with its three measured variables. The hx711 analog-to-digital converter outputs the raw values from both available channels as voltage values. The conversion to weight is performed by the userspace application.

Triggering by hrtimer event

The IIO framework provides support for reading sensor data when an event occurs, such as an interrupt. The values read can then be stored in a memory area and queried asynchronously using a device node.

The most frequently used trigger is the hrtimer event. Here, the hardware timer is programmed by the hrtimer framework to a future time. When this time occurs, the hardware timer generates an interrupt, which is available as an hrtimer event. A callback function in the industrial I/O driver is then called, and the sensor is queried.

The data can be stored in a buffer. This buffer must be configured in the driver and serves to temporarily store the data until it is processed using the Device node (/dev/iio:device). The IIO framework ensures that the timer is reprogrammed. This results in a cyclic timer with a constant sampling frequency.

A utility called iio_generic_buffer exists in the tools/iio directory of the Linux source code for querying the data. This utility is instructed which device, with which trigger, which data should be queried, and how frequently.

The following example shows how to use hrtimer events from within userspace:

root@silo: cd /sys/kernel/config/iio/triggers/hrtimer
root@silo: mkdir mytmr
root@silo: cd /sys/bus/iio/devices/trigger0
root@silo: echo 1 > sampling_frequency
root@silo: iio_generic_buffer -a -c3 -N0 -T0

[…]

/sys/bus/iio/devices/iio:device0 mytmr

0.080000 1502965687594511120
0.230000 1502965688594510720
0.240000 1502965689594510840

First, the hrtimer trigger is generated. This is done in the configfs file by creating a new directory. In this example, the name chosen is mytmr. If this is the first trigger created, it will have the number 0. A new device directory named trigger is created in the sysfs file. This was created, where T is the trigger number. The trigger can be parameterized in this directory. In the example above, the frequency is set to 1 Hz.

The data query is performed using the program iio_generic_buffer. All channels (-a) are queried 3 times (-c3) from device number 0 (-N0) using trigger number 0 (-T0).

Userspace libraries

As explained above, the IIO subsystem is structured very systematically according to known and documented rules. Reviewers and the maintainer ensure that this remains the case. Before new definitions are used, attempts are made to integrate new drivers into the existing interfaces.

I/O devices registered with the framework are numbered sequentially in the order of registration. This requires the userspace developer to be able to establish the connection between the device number and the desired driver. They must iterate through the devices in sysfs and identify the relevant driver based on the `name` attribute. Trigger event detection works analogously.

This is tedious routine work and, due to the systematic nature of IIO, can be easily outsourced to a library. libiio was created precisely for this purpose. It allows for effective automation of the following:

  • Connection to a local or remote IIO subsystem on which the iiod daemon is running.
  • Query of available devices
  • Iterate through channels and attributes
  • Reading and writing attributes

References

Sources of the drivers used in the article:

  • linux-stable/drivers/iio/adc/hx711.c
  • linux-stable/drivers/iio/pressure/bmp280*.c

author

Andreas Klinger is a freelance trainer and developer. Since graduating with a degree in electrical engineering in 1998, he has worked in the field of low-level software development, specializing in driver development, embedded Linux, and real-time applications. As a Linux specialist, he focuses on the internal structure of the kernel, system mechanisms, and, above all, their application in embedded systems.

Download the article as a PDF


Open Source – our training & coaching

Do you want to bring yourself up to date with the latest technology?

Then find out more here MircoConsult offers training courses/seminars/workshops and individual coaching on the topic of Open Source / Embedded Software Engineering.

Training & coaching on the other topics in our portfolio can be found here. here.


Open Source – Expertise

Valuable expertise in the field of Open Source / Embedded Software Engineering is available. here Available for you to download free of charge.

To the specialist information

You can find expertise on other topics in our portfolio here. here.

MicroConsult Newsletter

With the MicroConsult newsletter, you'll stay on the pulse of the embedded world. Look forward to proven practical knowledge, real professional tips, and current events – directly from our experts for your project success.

Subscribe now!

Published by

weissblau media

weissblau media