【问题标题】:linux inter driver communicationlinux驱动间通信
【发布时间】:2018-03-29 10:21:52
【问题描述】:

在树莓派上,我希望能够使用旋转编码器作为音量控制。 我能看到的最好方法是使用rotation_encoder模块来读取编码器,将其设置为相对轴(因此会得到+1或-1事件),然后让驱动程序解释它以增加音量或降低音量键。

但是我正在努力理解中断和驱动程序,因此我的驱动程序必须将自己注册为能够提供 EV_KEY 事件,我认为我已经处理了这些事件,但我不确定如何才能捕捉到并对来自其他司机的事件采取行动?

我想我必须轮询由其他驱动程序创建的 /dev/input/event 对象,但我似乎找不到有关如何执行此操作的指南?

这是最好的方法吗?有没有办法我可以真正捕捉到由其他驱动程序向输入系统提供事件创建的中断?

【问题讨论】:

  • 所有驱动程序都在内核模式下运行,在同一个地址空间中。如果您正在编写两个驱动程序,那么您可以使用EXPORT_SYMBOL_GPL(...) 或类似方法从另一个模块调用一个模块上的函数。
  • @rodrigo 我正在尝试使用现有的驱动程序,如果可以避免的话,我宁愿不更改它。我总是可以将我想要的位复制到我的驱动程序中,但如果我能提供帮助,我宁愿不复制任何功能。
  • 我明白了...看看int input_register_handler(struct input_handler *handler)函数。也许它可以满足您的需求。
  • 看起来它会做我想做的事,但很难找到如何使用它的好例子。

标签: c linux driver linux-device-driver


【解决方案1】:

您似乎想从不相关的模块接收输入事件。但是你不能从内核空间读取/dev/input/event*,所以你必须选择:

  1. 编写一个用户模式守护程序,它读取/dev/input/event* 并转发给您的驱动程序,可能带有一个字符设备或一个 sysfs 参数。
  2. 挂钩来自驱动程序的输入驱动程序事件。

选项 1 应该简单明了。我将详细说明选项 2。

要从内核中挂钩输入设备,您可以使用模块初始化函数中的函数input_register_handler()(当然还有退出函数中的input_unregister_handler())。

这个函数接受struct input_handler作为参数,它有很多成员,但你可能只需要填写nameid_tableconnectdisconnectevent

然后,在您的connect 回调中调用input_register_handle()(注意handlehandler 名称)和input_open_device(),您将在event 回调中获得输入事件。

当然,不要忘记在您的 disconnect 回调中撤消该工作。

在内核中有几个使用这种 API 的实例,但到目前为止更容易阅读的是evbug 驱动程序:它只是将所有输入事件转储到内核日志中。

【讨论】:

  • 这正是我正在寻找的例子,谢谢!
  • 您是否知道任何文档可以帮助我弄清楚如何将事件过滤到仅我感兴趣的设备? id_table 看起来像一个开始,但我找不到任何关于有效值的文档?
  • @JamesKent:是的,id_table 对于大多数情况应该足够了,filter 回调对于高级情况来说已经足够了。如果您需要特定的设备,您可以指定bustypevendorproduct。如果您想要任何特定类型的设备或任何具有 EV_BTN... 的设备,那么您填充其他成员。啊,不要忘记flags 告诉使用哪些成员(INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)。
猜你喜欢
  • 2012-07-22
  • 1970-01-01
  • 2013-11-13
  • 1970-01-01
  • 2013-10-02
  • 2021-04-30
  • 2012-03-01
  • 2017-03-09
  • 1970-01-01
相关资源
最近更新 更多