一、简介
加速度计、陀螺仪、电流/电压测量芯片、光传感器、压力传感器等都属于IIO 系列设备
IIO模型基于设备和通道架构:
设备代表芯片本身,它位于整个层次结构的顶层
通道表示设备的单个采集线,设备可能有一个或多个通道。例如,加速度计是具有3个通道的设备,每个轴(X、Y和Z)都有一个通道。
用户空间与IIO驱动程序进行交互的两种方式:
/sys/bus/iio/iio:deviceX:代表传感器及其通道
/dev/iio:deviceX:字符设备,用于输出设备事件和数据缓冲区。
IIO API头文件
#include <linux/iio/iio.h> /* mandatory */
#include <linux/iio/sysfs.h> /* mandatory since sysfs is used */
#include <linux/iio/events.h> /* For advanced users, to manage iio events */
#include <linux/iio/buffer.h> /* mandatory to use triggered buffers */
#include <linux/iio/trigger.h>/* Only if you implement trigger in your driver (rarely used)*/
二、IIO数据结构
结构体
</include/linux/iio/iio.h>/* modes选项 */
#define INDIO_DIRECT_MODE 0x01 //设备提供的sysfs接口/*表示设备支持硬件触发器,使用iio_triggered_buffer_setup()函数设 *置触发缓冲区时,此模式会自动添加到设备中.*/
#define INDIO_BUFFER_TRIGGERED 0x02
#define INDIO_BUFFER_SOFTWARE 0x04
#define INDIO_BUFFER_HARDWARE 0x08//设备具有硬件缓冲区
#define INDIO_EVENT_TRIGGERED 0x10
#define INDIO_HARDWARE_TRIGGERED 0x20
struct iio_buffer_setup_ops {
int (*preenable)(struct iio_dev *);
int (*postenable)(struct iio_dev *);
int (*predisable)(struct iio_dev *);
int (*postdisable)(struct iio_dev *);
bool (*validate_scan_mask)(struct iio_dev *indio_dev, const unsigned long *scan_mask);
};
</include/linux/iio/iio.h>
struct iio_dev {
int id;
struct module *driver_module;
int modes;//表示设备支持的不同模式
int currentmode;//设备实际使用的模式
struct device dev;//IIO设备绑定的设备
struct iio_event_interface *event_interface; //数据缓冲区,使用触发缓冲区模式会被推送到用户空间
struct iio_buffer *buffer;
struct list_head buffer_list;
int scan_bytes;//捕获并提供给缓冲区的字节数
struct mutex mlock; //使用触发缓冲器时,可以启用通道捕获并将其馈入IIO缓冲区。 //如果不想允许某些通道启用,则应仅使用允许的通道填充此数组
const unsigned long *available_scan_masks;//可选数组的位掩码
unsigned masklength; /*只有来自这些通道的数据能被推入缓冲区。例如,对于8通道ADC转换器, * 如果只启用第一个(0),第三个(2)和最后一个(7)通道,则位掩码 *将为0b10000101(0x85)。active_scan_mask将设置为0x85。然后,驱动 * 程序可以使用for_each_set_bit宏遍历每个设置位,根据通道获取数据, *并填充缓冲区。*/
const unsigned long *active_scan_mask;//已启用通道的位掩码
bool scan_timestamp;//是否将捕获时间戳推入缓冲区
unsigned scan_index_timestamp;
struct iio_trigger *trig;//当前设备的触发器
bool trig_readonly;
struct iio_poll_func *pollfunc;//在接收的触发器上运行的函数
struct iio_poll_func *pollfunc_event;
struct iio_chan_spec const *channels;
int num_channels;//指定通道数量
struct list_head channel_attr_list;
struct attribute_group chan_attr_group;
const char *name;//设备名称
const struct iio_info *info;//来自驱动程序的回调和常量信息
clockid_t clock_id;
struct mutex info_exist_lock; //启用/禁用缓冲区之前和之后调用的一组回调函数
const struct iio_buffer_setup_ops *setup_ops;
struct cdev chrdev;//IIO内核创建的相关字符设备
#define IIO_MAX_GROUPS 6
const struct attribute_group *groups[IIO_MAX_GROUPS + 1];
int groupcounter;
unsigned long flags;
#if defined(CONFIG_DEBUG_FS)
struct dentry *debugfs_dentry;
unsigned cached_reg_addr;
#endif
};
API函数
</include/linux/iio/iio.h>//为IIO设备分配内存,sizeof_priv是为私有结构分配的内存空间
struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv);
int iio_device_register(struct iio_dev *indio_dev);//向IIO子系统注册设备
void iio_device_unregister(struct iio_dev *indio_dev);
int devm_iio_device_register(struct device *dev, str