The Industrial I/O core offers a way for continuous data capture
based on a trigger source. Multiple data channels can be read at once
from /dev/iio:deviceX
character device node,
thus reducing the CPU load.
An IIO buffer has an associated attributes directory under
/sys/bus/iio/iio:deviceX/buffer/
. Here are the existing
attributes:
The meta information associated with a channel reading
placed in a buffer is called a scan element .
The important bits configuring scan elements are exposed to
userspace applications via the
/sys/bus/iio/iio:deviceX/scan_elements/
directory. This
file contains attributes of the following form:
For example, a driver for a 3-axis accelerometer with 12 bit resolution where data is stored in two 8-bits registers as follows:
7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ |D3 |D2 |D1 |D0 | X | X | X | X | (LOW byte, address 0x06) +---+---+---+---+---+---+---+---+ 7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+ |D11|D10|D9 |D8 |D7 |D6 |D5 |D4 | (HIGH byte, address 0x07) +---+---+---+---+---+---+---+---+
will have the following scan element type for each axis:
$ cat /sys/bus/iio/devices/iio:device0/scan_elements/in_accel_y_type le:s12/16>>4
A user space application will interpret data samples read from the buffer as two byte little endian signed data, that needs a 4 bits right shift before masking out the 12 valid bits of data.
For implementing buffer support a driver should initialize the following fields in iio_chan_spec definition:
struct iio_chan_spec { /* other members */ int scan_index struct { char sign; u8 realbits; u8 storagebits; u8 shift; u8 repeat; enum iio_endian endianness; } scan_type; };
The driver implementing the accelerometer described above will have the following channel definition:
struct struct iio_chan_spec accel_channels[] = { { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, /* other stuff here */ .scan_index = 0, .scan_type = { .sign = 's', .realbits = 12, .storgebits = 16, .shift = 4, .endianness = IIO_LE, }, } /* similar for Y (with channel2 = IIO_MOD_Y, scan_index = 1) * and Z (with channel2 = IIO_MOD_Z, scan_index = 2) axis */ }
Here scan_index defines the order in which the enabled channels are placed inside the buffer. Channels with a lower scan_index will be placed before channels with a higher index. Each channel needs to have a unique scan_index.
Setting scan_index to -1 can be used to indicate that the specific channel does not support buffered capture. In this case no entries will be created for the channel in the scan_elements directory.