Linux IIO框架采样就绪时如何通知其他内核驱动获取数据
问题背景
- 当前基于意法半导体(ST)官方LSM6DSOX传感器驱动开发,驱动已配置为硬件中断模式完成数据读取,IIO接口已正常向用户空间暴露。
- 需求为在内核态其他驱动中直接获取传感器采样数据,最初参考iio_hwmon的实现逻辑,通过查找GYRO通道调用
iio_read_channel_processed()接口读取采样,但该方案需要主动调用接口轮询,无法匹配采样就绪的准确时机。 - 核心诉求:确认IIO子系统是否支持采样就绪主动通知能力,允许内核驱动注册回调,在IIO缓冲区收到驱动上报的新采样时自动触发处理逻辑。
结论
该需求可以直接通过IIO子系统原生提供的内核态API实现,完全不需要主动轮询读取接口。
具体实现路径
推荐方案:基于IIO硬件触发器的缓冲区回调(适配LSM6DSOX硬件中断模式)
ST的LSM6DSOX驱动在硬件中断模式下,会默认注册对应的数据就绪IIO触发器(iio_trigger),硬件采样完成触发中断后,驱动会通过该触发器通知IIO核心处理新采样数据,你可以直接基于这个机制注册内核侧的缓冲区消费回调:
- 和iio_hwmon的实现逻辑一致,先通过
iio_channel_get()获取需要的GYRO等通道的引用,同时拿到LSM6DSOX对应的IIO设备实例。 - 调用
devm_iio_kfifo_buffer_setup()为你的驱动分配专属的IIO内核缓冲区,在配置参数中传入你自定义的采样处理回调,同时配置你需要监听的通道扫描掩码。 - 调用
iio_trigger_attach_buffer()将你注册的缓冲区,绑定到LSM6DSOX的硬件数据就绪触发器上。
完成以上配置后,每次硬件中断触发采样完成、驱动把新采样数据推入IIO核心时,核心会自动把数据写入你注册的kfifo缓冲区,紧接着调用你绑定的处理回调,你可以在回调中直接从缓冲区取出最新的采样值解析使用,不需要主动调用iio_read_channel_processed()轮询。
注意回调运行在IIO工作队列或者硬中断上下文,不要在里面做耗时操作,如果有复杂处理逻辑,建议把采样数据拷贝到本地缓存后,调度自定义工作队列延迟处理。
轻量方案:IIO事件通知块
如果不需要读取全量扫描的缓冲区数据,只需要拿到采样就绪的时机,可以直接给LSM6DSOX对应的IIO设备注册事件通知块:
调用iio_device_register_event_notifier()注册notifier,监听设备的数据就绪事件,事件触发时再调用iio_read_channel_processed()读取最新采样值即可。
该方案代码量更小,但需要确认当前使用的LSM6DSOX驱动版本已经开启了数据就绪事件上报,ST上游驱动默认支持该能力,适配成本很低。
不建议基于iio_hwmon的轮询逻辑改内核态采样:hwmon本身定位就是面向硬件监控场景的轮询式读取接口,从设计上就没有做事件驱动适配,主动轮询不仅会增加无意义的CPU开销,也无法保证采样时序和硬件中断严格对齐。
内容的提问来源于stack exchange,提问作者grzesiekrc

