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 some of 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,
.storagebits = 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.
push data and timestamp to buffers
Parameters
Description
Pushes data to the IIO device’s buffers. If timestamps are enabled for the device the function will store the supplied timestamp as the last element in the sample data buffer before pushing it to the device buffers. The sample data buffer needs to be large enough to hold the additional timestamp (usually the buffer should be indio->scan_bytes bytes large).
Returns 0 on success, a negative error code otherwise.
Set buffer specific attributes
Parameters
Validates that exactly one channel is selected
Parameters
Description
Return true if exactly one bit is set in the scan mask, false otherwise. It can be used for devices where only one channel can be active for sampling at a time.
push to a registered buffer.
Parameters
Grab a reference to the buffer
Parameters
Description
Returns the pointer to the buffer that was passed into the function.
Release the reference to the buffer
Parameters
Attach a buffer to a IIO device
Parameters
Description
This function attaches a buffer to a IIO device. The buffer stays attached to the device until the device is freed. The function should only be called at most once per device.