触发缓冲区

现在我们了解了缓冲区和触发器是什么,让我们看看它们是如何协同工作的。

IIO 触发缓冲区设置

典型的触发缓冲区设置如下所示

const struct iio_buffer_setup_ops sensor_buffer_setup_ops = {
  .preenable    = sensor_buffer_preenable,
  .postenable   = sensor_buffer_postenable,
  .postdisable  = sensor_buffer_postdisable,
  .predisable   = sensor_buffer_predisable,
};

irqreturn_t sensor_iio_pollfunc(int irq, void *p)
{
    pf->timestamp = iio_get_time_ns((struct indio_dev *)p);
    return IRQ_WAKE_THREAD;
}

irqreturn_t sensor_trigger_handler(int irq, void *p)
{
    u16 buf[8];
    int i = 0;

    /* read data for each active channel */
    for_each_set_bit(bit, active_scan_mask, masklength)
        buf[i++] = sensor_get_data(bit)

    iio_push_to_buffers_with_timestamp(indio_dev, buf, timestamp);

    iio_trigger_notify_done(trigger);
    return IRQ_HANDLED;
}

/* setup triggered buffer, usually in probe function */
iio_triggered_buffer_setup(indio_dev, sensor_iio_polfunc,
                           sensor_trigger_handler,
                           sensor_buffer_setup_ops);

这里需要注意的重点是

  • iio_buffer_setup_ops,在缓冲区配置序列中的预定义点(例如,启用前,禁用后)调用的缓冲区设置函数。如果未指定,IIO 核心将使用默认的 iio_triggered_buffer_setup_ops。

  • sensor_iio_pollfunc,将用作轮询函数上半部分的函数。它应尽可能少地进行处理,因为它在中断上下文中运行。最常见的操作是记录当前时间戳,因此可以使用 IIO 核心定义的 iio_pollfunc_store_time() 函数。

  • sensor_trigger_handler,将用作轮询函数下半部分的函数。它在内核线程的上下文中运行,所有处理都在这里进行。它通常从设备读取数据,并将其与上半部分中记录的时间戳一起存储在内部缓冲区中。

更多细节

int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev, irqreturn_t (*h)(int irq, void *p), irqreturn_t (*thread)(int irq, void *p), enum iio_buffer_direction direction, const struct iio_buffer_setup_ops *setup_ops, const struct iio_dev_attr **buffer_attrs)

设置触发缓冲区和轮询函数

参数

struct iio_dev *indio_dev

IIO 设备结构

irqreturn_t (*h)(int irq, void *p)

将用作轮询函数上半部分的函数

irqreturn_t (*thread)(int irq, void *p)

将用作轮询函数下半部分的函数

enum iio_buffer_direction direction

数据流的方向(输入/输出)。

const struct iio_buffer_setup_ops *setup_ops

用于此设备的缓冲区设置函数。如果为 NULL,将使用触发缓冲区的默认设置函数。

const struct iio_dev_attr **buffer_attrs

此 IIO 缓冲区的额外 sysfs 缓冲区属性

描述

此函数组合了一些通常在设置触发缓冲区时执行的常见任务。它将分配缓冲区和轮询函数。

在调用此函数之前,应已完全初始化 indio_dev 结构,但尚未注册。实际上,这意味着此函数应在 iio_device_register() 之前立即调用。

要释放此函数分配的资源,请调用 iio_triggered_buffer_cleanup()

void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev)

释放 iio_triggered_buffer_setup_ext() 分配的资源

参数

struct iio_dev *indio_dev

IIO 设备结构