Last edited 4 months ago

IIO overview

Applicable for STM32MP13x lines, STM32MP15x lines

This article gives information about the Linux® IIO framework.
It explains how to activate the IIO interface and, based on examples, how to use it.

1. Framework purpose[edit | edit source]

IIO (Industrial I/O) is a subsystem for Analog to Digital Converters (ADCs), Digital to Analog Converters (DACs) and various types of sensors. It can be used on high speed, high data rates industrial devices. Until recently, it was mostly focused on user-space abstraction. It also includes in-kernel API for other drivers.

The Industrial I/O Linux® subsystem offers a unified framework to communicate (read and write) with drivers covering many different types of embedded sensors and a few actuators. It also offers a standard interface to user space applications manipulating sensors through sysfs and devfs.

Here are some examples of supported sensor types in IIO:

  • ADC / DAC
  • accelerometers
  • magnetometers
  • gyroscopes
  • pressure
  • humidity
  • temperature
  • light and proximity

IIO can be used in many different use cases, as mentioned in How to use the framework section:

  • Low speed acquisition for slow varying input signal (example: log temperature to a file)
  • High speed acquisition using ADC, DFSDM or external devices (example: audio, power meter)
  • Read the position of a rotary element using TIM or LPTIM quadrature encoder interface
  • Driving an analog source through a DAC
  • External devices connected via SPI or I2C.

2. System overview[edit | edit source]

libiiolibiioUser space interfaceKernel space interfaceKernel space userDAC Linux driverADC OpenSTLinux driversDFSDM Linux driverIIO timers triggerskernel IIO device driverDAC internal peripheralADC internal peripheralDFSDM internal peripheralTimer internal peripheralsI2C or SPI internal peripherals
IIO Implementation architecture

2.1. Components description[edit | edit source]

From client application to hardware

  • Client Application (User Space): An application that configures, read or write data samples to/from IIO device(s) via libiio.
  • iiod server (User Space): It is optional. Applications based on libiio can benefit from a remote access via IIO Daemon server, to IIO "local" backend through a network link.
  • libiio (User Space): libiio is a complete library offering an API for developping an application. It's composed of a high-level API, and two backends:
  1. The “local” backend, interfacing with the Linux kernel through the IIO API
  2. The “network” backend, interfacing with the iiod server through a network link.
  • User Space interface: It is composed of a standard char device, sysfs, configfs and debugfs (see API description).
  • Kernel Space user: It can be any kernel space IIO consumer, like STM32 DFSDM audio driver or IIO hwmon driver (See How to use IIO kernel API).
  • Kernel Space interface: It is composed of a standard API
  • IIO framework (Kernel Space): It's composed of a core. It manages data buffers, userspace events, triggers. It also handles clients (either in kernel or in User Space).
  • STM32 peripherals (Hardware): connected to the external devices through a specific interface (examples: ADC, DAC, DFSDM , TIM, LPTIM, SPI, or I2C)
  • External devices (Hardware): connected to the STM32 front-end through a specific interface. These can be analog devices (such as accelerometers, Inertial Measurement Units...), a Sigma Delta ADC Modulator (for audio record, energy measurements...), IIO devices on SPI or I2C...

2.2. API description[edit | edit source]

Depending on needs and location (Kernel Space or User Space), several APIs are available to control an IIO device.

2.2.1. libiio[edit | edit source]

Libiio provides a user space high-level API for client applications[1]. The library abstracts the low-level details of the hardware, and provides a simple yet complete programming interface that can be used for advanced projects.

It is a wrapper on the user space interface (sysfs and char device) provided by the kernel.

2.2.2. User space interface[edit | edit source]

The IIO framework provides several interfaces:

  • configfs: It allows to configure additional IIO features like software and hrtimer triggers.
    The IIO configfs interface is documented in: Documentation/ABI/testing/configfs-iio[4] and Documentation/iio/iio_configfs.txt[5].
    Note: STM32 already provides hardware triggers (See How to use the IIO timers triggers).
  • Debugfs: May provide some debug conveniences (like direct_reg_access entry to read/write registers) depending on the IIO device driver in use.

2.2.3. Kernel space interface[edit | edit source]

Useful kernel API for users:

  • devm_iio_channel_get_all() or iio_channel_get_all() / iio_channel_release_all(): Used to lookup, get, then release IIO channels.
  • iio_get_channel_type(): get the type of a channel, such as IIO_VOLTAGE, IIO_TEMP...
  • iio_read_channel_processed(): read channel processed value, e.g. like in micro-volts for voltage, milli-degree for temperature...
  • ...

Available routines can be found in kernel header file: include/linux/iio/consumer.h[6].

3. Configuration[edit | edit source]

3.1. Kernel configuration[edit | edit source]

IIO is activated by default in ST deliveries. Nevertheless, if a specific configuration is needed, this section indicates how IIO can be activated/deactivated in the kernel.

Activate IIO in kernel configuration with Linux Menuconfig tool: Menuconfig or how to configure kernel

Device Drivers  --->
  <*> Industrial I/O support  --->
    [*]   Enable buffer support within IIO
     < >     IIO callback buffer used for push in-kernel interfaces
     <*>     Industrial I/O HW buffering
     <*>     Industrial I/O buffering based on kfifo
     < >   Enable IIO configuration via configfs                        
     [*]   Enable triggered sampling support
     (2)     Maximum number of consumers per trigger                    
     < >   Enable software triggers support                             
           Accelerometers  --->                                         
           Analog to digital converters  --->                          
           Amplifiers  --->                                             
           Chemical Sensors  --->                                       
           Hid Sensor IIO Common  ----                                  
           SSP Sensor Common  --->                                      
           Digital to analog converters  --->                           
           IIO dummy driver  --->                                       
           Frequency Synthesizers DDS/PLL  --->                         
           Digital gyroscope sensors  --->                              
           Health Sensors  --->                                         
           Humidity sensors  --->                                       
           Inertial measurement units  --->                             
           Light sensors  --->                                          
           Magnetometer sensors  --->                                   
           Inclinometer sensors  ----                                   
           Triggers - standalone  --->                                  
           Digital potentiometers  --->                                 
           Pressure sensors  --->                                       
           Lightning sensors  --->                                      
           Proximity sensors  --->                                      
           Temperature sensors  ---> 

IIO supports several types of sensors and devices. User can select from there any driver among the supported devices.

Please refer to ADC OpenSTLinux drivers, DAC Linux driver, DFSDM Linux driver, TIM Linux driver, LPTIM Linux driver articles for each peripheral.

3.2. Device tree configuration[edit | edit source]

IIO bindings [7] documentation deals with all required or optional IIO generic DT properties.

It also introduces IIO providers and IIO consumers [8].
Example with STM32 ADC:

&adc {
	adc2: adc@100 {                        /* IIO provider example */
		...
		#io-channel-cells = <1>;
		channel@12 {
			reg = <12>;            /* channel 12 in use */
		};
	};
};
/ {
	consumer_device {                      /* IIO consumer example */
		io-channels = <&adc2 12>;
		io-channel-names = "example";  /* IIO consumer driver side: devm_iio_channel_get(&dev, "example"); */
	};

	iio-hwmon {                            /* iio_hwmon[9] is another consumer example (See SENSORS_IIO_HWMON in kernel configuration) */
		compatible = "iio-hwmon";      /* See Documentation/devicetree/bindings/iio/iio-bindings.txt[7]
		io-channels = <&adc2 12>;
	};
};

Detailed DT configuration for STM32 internal peripherals:

Linux kernel provides many other supported devices[10] in Documentation/devicetree/bindings/iio directory.

4. How to use the framework[edit | edit source]

This section describes how to use the IIO framework from:

4.1. How to use the IIO user space interface[edit | edit source]

Please see examples based on the following use cases:

4.2. How to use IIO kernel API[edit | edit source]

Several in-kernel drivers use kernel IIO API. See HWMON client example for IIO devices, and STM32 DFSDM audio ALSA IIO client:

$ cat /sys/class/hwmon/hwmon0/in1_input
1809                                       # iio_hwmon calls iio_read_channel_processed(): ADC result is in mV.

5. How to trace and debug the framework[edit | edit source]

5.1. How to trace with dynamic debug[edit | edit source]

By default there is no kernel log that shows activity on IIO. However the user could enable dynamic debug for the IIO core and the IIO drivers.

 dmesg -n8
 echo "file drivers/iio/* +p" > /sys/kernel/debug/dynamic_debug/control
 echo "file drivers/iio/adc/* +p" > /sys/kernel/debug/dynamic_debug/control
 echo "file drivers/iio/dac/* +p" > /sys/kernel/debug/dynamic_debug/control

See dynamic debug for more details.

5.2. How to debug with debugfs[edit | edit source]

IIO proposes an optional debugfs entry to access registers. It is up to the IIO device driver to implement it (e.g. debugfs_reg_access()). When it is available:

$ cd /sys/kernel/debug/iio/iio:deviceX

To read a register from the device:

$ echo [register offset] > direct_reg_access
$ cat direct_reg_access
0xhhhh                                          # Register content

To write a register:

$ echo [register offset] [register value] > direct_reg_access

6. To go further[edit | edit source]

6.1. How to write a kernel IIO device driver[edit | edit source]

The Linux Kernel community provides all the documents needed to develop an IIO device driver :

  • The Linux driver implementer’s API guide - Industrial I/O[11]: This guide provides the API provided by kernel IIO core components.
  • IIO staging documentation[12], included in the Kernel sources (drivers/staging/iio/Documentation).
  • Linux Kernel IIO dummy driver example source code[13]: Dummy driver source code, included in the kernel sources (drivers/iio/dummy/iio_simple_dummy.c).

6.2. Trainings documents[edit | edit source]

  • IIO a new subsystem[14] : Presentation of Kernel IIO subsystem
  • Industrial I/O Subsystem: The Home of Linux Sensors[15]: Why IIO? What is it? Sensor types...
  • Software Defined Radio using the Linux Industrial IO framework[16] : User Guide describing how to implement an application by using Linux Industrial IO framework
  • Linux Device Drivers, Third Edition[17] : Reference book for linux device drivers development, for IIO see Chapter 3, Char Drivers.

7. References[edit | edit source]

  1. libiio High-Level API, libiio API Documentation (Library for interfacing with IIO devices)
  2. sysfs-bus-iio ABI, Linux standard sysfs IIO interface
  3. character device interface, Linux Kernel and Driver Development training document, see Character drivers and Kernel frameworks for device drivers chapter
  4. configfs-iio ABI, Linux standard configfs IIO interface
  5. iio_configfs interface, Linux standard configfs interface
  6. include/linux/iio/consumer.h , IIO 'inkern' API
  7. 7.0 7.1 https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/iio/iio.yaml, Linux Foundation, IIO Generic DT bindings
  8. https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/iio/iio-consumer.yaml, Linux Foundation, IIO Consumer DT bindings
  9. 9.0 9.1 drivers/hwmon/iio_hwmon.c IIO HWMON, consumer driver example (kernel space)
  10. Kernel DT documentation IIO bindings , Linux Foundation, IIO DT bindings documents included in the Kernel sources
  11. Industrial I/O, The Linux driver implementer’s API guide
  12. IIO staging documentation , Linux Foundation, IIO documents included in the Kernel sources
  13. drivers/iio/dummy/iio_simple_dummy.c , Linux Foundation, IIO dummy driver example source code
  14. IIO a new subsystem, Free Electrons, Presentation of Kernel IIO subsystem
  15. Industrial I/O Subsystem: The Home of Linux Sensors, Linux Foundation, IIO training
  16. Software Defined Radio using the Linux Industrial IO framework, Linux Foundation, User Guide describing how to implement an application by using Linux Industrial IO framework
  17. Linux Device Drivers, Third Edition, Pdf book, Authors Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman