触发器

在许多情况下,驱动程序能够根据某些外部事件(触发器)捕获数据,而不是定期轮询数据,这很有用。IIO 触发器可以由也具有基于硬件生成事件(例如数据就绪或超出阈值)的 IIO 设备的设备驱动程序提供,或者由来自独立中断源(例如连接到某些外部系统的 GPIO 线、定时器中断或用户空间在 sysfs 中写入特定文件)的单独驱动程序提供。一个触发器可以启动多个传感器的数据捕获,并且它可能与传感器本身完全无关。

IIO 触发器 sysfs 接口

sysfs 中有两个与触发器相关的位置

  • /sys/bus/iio/devices/triggerY/*,一旦 IIO 触发器在 IIO 核心中注册,就会创建此文件,并对应于索引为 Y 的触发器。由于触发器类型差异很大,我们在这里只能描述一些标准属性

    • name,触发器名称,稍后可用于与设备关联。

    • sampling_frequency,某些基于定时器的触发器使用此属性来指定触发器调用的频率。

  • /sys/bus/iio/devices/iio:deviceX/trigger/*,一旦设备支持触发缓冲区,就会创建此目录。我们可以通过在 current_trigger 文件中写入触发器的名称来将触发器与我们的设备关联起来。

IIO 触发器设置

让我们看一个简单的示例,了解如何设置供驱动程序使用的触发器

struct iio_trigger_ops trigger_ops = {
    .set_trigger_state = sample_trigger_state,
    .validate_device = sample_validate_device,
}

struct iio_trigger *trig;

/* first, allocate memory for our trigger */
trig = iio_trigger_alloc(dev, "trig-%s-%d", name, idx);

/* setup trigger operations field */
trig->ops = &trigger_ops;

/* now register the trigger with the IIO core */
iio_trigger_register(trig);

IIO 触发器操作

请注意,触发器附加了一组操作

  • set_trigger_state,按需打开/关闭触发器。

  • validate_device,当当前触发器发生更改时,用于验证设备的函数。

更多细节

struct iio_trigger_ops

iio_trigger 的操作结构。

定义:

struct iio_trigger_ops {
    int (*set_trigger_state)(struct iio_trigger *trig, bool state);
    void (*reenable)(struct iio_trigger *trig);
    int (*validate_device)(struct iio_trigger *trig, struct iio_dev *indio_dev);
};

成员

set_trigger_state

按需打开/关闭触发器

reenable

当使用计数为零时重新启用触发器的函数(可能为 NULL)

validate_device

当当前触发器发生更改时,用于验证设备的函数。

描述

这通常是驱动程序中的静态常量,由给定设备的实例共享。

struct iio_trigger

工业 I/O 触发设备

定义:

struct iio_trigger {
    const struct iio_trigger_ops    *ops;
    struct module                   *owner;
    int id;
    const char                      *name;
    struct device                   dev;
    struct list_head                list;
    struct list_head                alloc_list;
    atomic_t use_count;
    struct irq_chip                 subirq_chip;
    int subirq_base;
    struct iio_subirq subirqs[CONFIG_IIO_CONSUMERS_PER_TRIGGER];
    unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)];
    struct mutex                    pool_lock;
    bool attached_own_device;
    struct work_struct              reenable_work;
};

成员

ops

[DRIVER] 操作结构

owner

[INTERN] 此驱动程序模块的所有者

id

[INTERN] 唯一的 ID 号

name

[DRIVER] 唯一的名称

dev

[DRIVER] 关联的设备(如果相关)

list

[INTERN] 用于维护全局触发器列表

alloc_list

[DRIVER] 用于特定于驱动程序的触发器列表

use_count

[INTERN] 触发器的使用计数。

subirq_chip

[INTERN] 关联“虚拟” irq 芯片。

subirq_base

[INTERN] 由触发器提供的 irq 的基本编号。

subirqs

[INTERN] 有关“子” irq 的信息。

pool

[INTERN] 当前使用的 irq 的位图。

pool_lock

[INTERN] irq 池的保护。

attached_own_device

[INTERN] 如果我们使用自己的设备作为触发器,即如果我们将轮询函数注册到与提供触发器的设备相同的设备。

reenable_work

[INTERN] 用于确保重新启用可以休眠的工作项。

void iio_trigger_set_drvdata(struct iio_trigger *trig, void *data)

设置触发器驱动程序数据

参数

struct iio_trigger *trig

IIO 触发器结构

void *data

特定于驱动程序的数据

描述

允许将任意指针附加到 IIO 触发器,稍后可以使用 iio_trigger_get_drvdata() 检索该指针。

void *iio_trigger_get_drvdata(struct iio_trigger *trig)

获取触发器驱动程序数据

参数

struct iio_trigger *trig

IIO 触发器结构

描述

返回先前使用 iio_trigger_set_drvdata() 设置的数据

int iio_trigger_register(struct iio_trigger *trig_info)

向 IIO 核心注册触发器

参数

struct iio_trigger *trig_info

要注册的触发器

void iio_trigger_unregister(struct iio_trigger *trig_info)

从核心取消注册触发器

参数

struct iio_trigger *trig_info

要取消注册的触发器

int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *trig)

在目标设备上设置一个不可变的触发器

参数

struct iio_dev *indio_dev

包含设备的 IIO 设备结构

struct iio_trigger *trig

要分配给设备的触发器

bool iio_trigger_using_own(struct iio_dev *indio_dev)

告知我们是否使用自己的硬件触发器

参数

struct iio_dev *indio_dev

要检查的设备

void iio_trigger_poll(struct iio_trigger *trig)

调用消费者的 IRQ 触发处理程序

参数

struct iio_trigger *trig

发生的触发器

描述

此函数只能从硬 IRQ 上下文调用。

void iio_trigger_poll_nested(struct iio_trigger *trig)

调用消费者的线程触发处理程序

参数

struct iio_trigger *trig

发生的触发器

描述

此函数只能从内核线程上下文调用。

struct iio_trigger *__iio_trigger_alloc(struct device *parent, struct module *this_mod, const char *fmt, ...)

分配一个触发器

参数

struct device *parent

为其分配 iio_trigger 的设备

struct module *this_mod

分配触发器的模块

const char *fmt

触发器名称格式。如果它包含格式说明符,则格式后面的附加参数将被格式化并插入到结果字符串中,替换它们各自的说明符。

...

可变参数

返回

成功时指向分配的 iio_trigger 的指针,失败时为 NULL。

struct iio_trigger *__devm_iio_trigger_alloc(struct device *parent, struct module *this_mod, const char *fmt, ...)

资源管理的 iio_trigger_alloc()。使用此函数分配的 iio_trigger 会在驱动程序分离时自动释放。

参数

struct device *parent

为其分配 iio_trigger 的设备

struct module *this_mod

分配触发器的模块

const char *fmt

触发器名称格式。如果它包含格式说明符,则格式后面的附加参数将被格式化并插入到结果字符串中,替换它们各自的说明符。

...

可变参数

返回

成功时指向分配的 iio_trigger 的指针,失败时为 NULL。

int devm_iio_trigger_register(struct device *dev, struct iio_trigger *trig_info)

资源管理的 iio_trigger_register()

参数

struct device *dev

为此触发器分配的设备

struct iio_trigger *trig_info

要注册的触发器

描述

管理的 iio_trigger_register()。使用此函数注册的 IIO 触发器会在驱动程序分离时自动取消注册。此函数在内部调用 iio_trigger_register()。有关详细信息,请参阅该函数。

返回

成功时返回 0,失败时返回负错误号。

int iio_validate_own_trigger(struct iio_dev *idev, struct iio_trigger *trig)

检查触发器和 IIO 设备是否属于同一设备

参数

struct iio_dev *idev

要检查的 IIO 设备

struct iio_trigger *trig

要检查的 IIO 触发器

描述

此函数可用作仅可附加到其自身设备的触发器的 validate_trigger 回调。

返回

如果触发器和 IIO 设备都属于同一设备,则返回 0,否则返回 -EINVAL。

int iio_trigger_validate_own_device(struct iio_trigger *trig, struct iio_dev *indio_dev)

检查触发器和 IIO 设备是否属于同一设备

参数

struct iio_trigger *trig

要检查的 IIO 触发器

struct iio_dev *indio_dev

要检查的 IIO 设备

描述

此函数可用作只能附加到其自身设备的触发器的 validate_device 回调。

返回

如果触发器和 IIO 设备都属于同一设备,则返回 0,否则返回 -EINVAL。