IIO (Industrial I / O) est un sous-système du noyau Linux pour les convertisseurs analogique-numérique (ADC), les convertisseurs numérique-analogique (DAC) et divers types de capteurs. Peut être utilisé sur des appareils industriels à grande vitesse. Il comprend également une API intégrée pour les autres pilotes.
Industrial I/O Linux ( ) , . , sysfs devfs.
IIO:
- /
IIO :
- (: )
- - , DFSDM (, , )
- , TIM LPTIM
- SPI I2C
IIO , , ...
IIO
/ :
# https://www.kernel.org/doc/Documentation/i2c/dev-interface
open("/dev/i2c-1", O_RDWR);
# https://www.kernel.org/doc/Documentation/spi/spidev.rst
open("/dev/spidev2.0", O_RDWR);
, :
— ?
"" ( ).
IIO - , - poll .
IIO — .
.
IIO
sysfs ( ):
# cat /sys/bus/iio/devices/iio\:device0/in_accel_x_raw
-493
"" , .
read():
#
(cd /sys/bus/iio/devices/iio:device0/scan_elements/ && for file in *_en; do echo 1 > $file; done)
:
int fd = open("/dev/iio:device0");
read(fd, buffer, scan_size);
# scan_size , 1 /sys/bus/iio/devices/iio:device0/scan_elements/*_en
scan_size, "" , , .
IIO struct iio_chan_spec:
BME280
/* https://elixir.bootlin.com/linux/v5.9-rc1/source/drivers/iio/pressure/bmp280-core.c#L132*/
static const struct iio_chan_spec bmp280_channels[] = {
{
.type = IIO_PRESSURE,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
},
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
},
{
.type = IIO_HUMIDITYRELATIVE,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
},
};
, , — .
Linux , .
, kfifo .
, , , .
. , , , , , .
, CLOCK_REALTIME.
"" , user space.
, .
:
# cat /sys/bus/iio/devices/iio\:device0/trigger/current_trigger
icm20608-dev0
# echo > /sys/bus/iio/devices/iio\:device0/trigger/current_trigger
# cat /sys/bus/iio/devices/iio\:device0/trigger/current_trigger
# echo "icm20608-dev0" > /sys/bus/iio/devices/iio\:device0/trigger/current_trigger
Official Trigger Documentation
Industrial IIO configfs support
Triggered buffer support trigger buffer support for IIO subsystem of Linux device driver
Device owned triggers
, device tree:
icm20608: imu@0 {
...
interrupt-parent = <&gpio5>;
interrupts = <11 IRQ_TYPE_EDGE_RISING>;
...
};
:
cat /sys/bus/iio/devices/trigger0/name
icm20608-dev0
gpio, , .
Interrupt triggers (also known as gpio trigger)
, . gpio, .
, maintainer'a IIO Jonathan Cameron, .
— Triggered buffer support trigger buffer support for IIO subsystem of Linux device driver
.
:
[v3,1/6] dt-bindings: iio: introduce trigger providers, consumers
device tree :
trig0: interrupt-trigger0 {
#io-trigger-cells = <0>;
compatible = "interrupt-trigger";
interrupts = <11 0>;
interrupt-parent = <&gpioa>;
};
sysfs trigger
sysfs — , .
:
# echo 10 > /sys/bus/iio/devices/iio_sysfs_trigger/add_trigger
"sysfstrig%d", .
High resolution timer trigger
1 .
# mkdir /sys/kernel/config/iio/triggers/hrtimer/my_trigger_name
# cat /sys/bus/iio/devices/trigger4/name
my_trigger_name
# cat /sys/bus/iio/devices/trigger4/sampling_frequency
100
— "" SoC.
loop trigger
PATCH v1 5/5 iio:pressure:ms5611: continuous sampling support
.
. :
iio:trigger: Experimental kthread tight loop trigger.
DT, , .
Device tree
label , , of_node iio:device — /sys/bus/iio/devices/iio\:device0/of_node/.
— https://elixir.bootlin.com/linux/v5.9-rc1/source/Documentation/devicetree/bindings/iio
, IIO, enum iio_chan_type . iio_event_monitor.
IIO iio-buffer-sysfs-interface.
[be|le]:[s|u]bits/storagebitsXrepeat[>>shift]
icm20608:
# cat /sys/bus/iio/devices/iio\:device0/scan_elements/*_type
be:s16/16>>0
be:s16/16>>0
be:s16/16>>0
be:s16/16>>0
be:s16/16>>0
be:s16/16>>0
le:s64/64>>0
:
- le be c
- — , s u
- / ,
:
be:u4/8>>0
be:u4/8>>4
repeat — 1 .
Scaling and offset
:
/sys/bus/iio/devices/iio:deviceX/in_*_raw
/sys/bus/iio/devices/iio:deviceX/in_*_offset
/sys/bus/iio/devices/iio:deviceX/in_*_scale
(raw + offset)*scale, offset'a .
How to do a simple ADC conversion using the sysfs interface
iio_simple_dummy
iio_simple_dummy — IIO :
- IIO_VOLTAGE
- IIO_ACCEL
- IIO_ACTIVITY
libiio
— libiio Analog Devices.
, / .
/, , Linux, Windows Mac , USB, Ethernet Serial.
iiod:
On remote :
host # iiod
On local :
local $ iio_info -n [host_address]
local $ iio_attr -u ip:[host_address] -d
local $ iio_readdev -u ip:[host_address] -b 256 -s 0 icm20608
Matlab, .
, libiio .
https://github.com/maquefel/icm20608-iio
libiio
sysfs , :
- , /sys/bus/iio/iio:deviceN/name, /sys/bus/iio/iio:deviceN /dev/iio:deviceN
- /sys/bus/iio/iio:deviceN/scan_elements/, , *_en
- /sys/bus/iio/iio:deviceN/enable
.
E libiio.
https://elixir.bootlin.com/linux/v5.9-rc1/source/drivers/iio/industrialio-buffer.c#L574
:
# bytes -
# length -
# offset -
if (bytes % length == 0)
offset = bytes;
else
offset = bytes - bytes % length + length;
bytes = offset + length;
libiio, :
- , (Sign extension)
- offset,
- scale,
input = is_be ? betoh(input) : letoh(input);
input >>= shift;
input &= BIT_MASK(bits);
value = is_signed ? (float)sext(input, bits) : (float)input;
if(with_offset) value += offset;
if(with_scale) value *= scale;
: (Sign extension) . SignExtend.
libiio
:
# uri
# uri = "ip:127.0.0.1"
# uri = "local:"
# uri = "usb:"
ctx = iio_create_context_from_uri(uri);
#
# device = icm20608
dev = iio_context_find_device(ctx, device);
#
nb_channels = iio_device_get_channels_count(dev);
#
for(int i = 0; i < nb_channels; i++)
iio_channel_enable(iio_device_get_channel(dev, i));
# buffer_size = SAMPLES_PER_READ, ( )
buffer = iio_device_create_buffer(dev, buffer_size, false);
#
iio_buffer_set_blocking_mode(buffer, true);
while(true) {
#
iio_buffer_refill(buffer);
# - libiio
# "" ,
#
# ssize_t print_sample(const struct iio_channel *chn, void *buffer, size_t bytes, __notused void *d)
# const struct iio_channel *chn -
# void *buffer -
# size_t bytes -
# __notused void *d - iio_buffer_foreach_sample
iio_buffer_foreach_sample(buffer, print_sample, NULL);
}
#
iio_buffer_destroy(buffer);
#
iio_context_destroy(ctx);
, , Zero-Copy.
.
( ):
—
— DMA + mmap()
- DMA
- mmap()
- ""
High-speed Data Acquisition
using the
Linux Industrial IO framework
SDR.
, , .
https://bootlin.com/pub/conferences/2012/fosdem/iio-a-new-subsystem/iio-a-new-subsystem.pdf
https://archive.fosdem.org/2012/schedule/event/693/127_iio-a-new-subsystem.pdf
https://programmer.group/5cbf67db154ab.html
https://elinux.org/images/b/ba/ELC_2017_-_Industrial_IO_and_You-_Nonsense_Hacks%21.pdf
https://elinux.org/images/8/8d/Clausen--high-speed_data_acquisition_with_the_linux_iio_framework.pdf
https://linux.ime.usp.br/~marcelosc/2019/09/Simple-IIO-driver
P.S.
Je m'excuse pour les liens, je ne pouvais pas les faire ressembler à ce qu'ils devraient en démarque, et je ne sais pas pourquoi.
L'espace a été résolu - merci Exosphère - J'ai mal formaté les liens.