【问题标题】:What is the best way to sample periodicaly gpio-pins in Linux?在 Linux 中定期采样 gpio-pin 的最佳方法是什么?
【发布时间】:2017-06-18 05:44:19
【问题描述】:

我喜欢对 Raspberry Pi 的引脚生成的信号进行采样。我体验到高采样率是难以实现的。

首先我用 Python 做了一个快速的方法(超级慢)。然后我更改为 ANSI C + bcm2835.h 库。我获得了显着的性能提升。

现在我问自己一个问题:如何在 Linux 下进行最佳采样?

我的尝试是在用户空间中进行的。但是,切换到内核空间是怎么回事?我可以编写一个简单的字符设备内核模块。在这个模块中,引脚会定期检查。如果状态发生变化,一些信息将被放入缓冲区。此 i/o 缓冲区由为用户空间中的应用程序读取的同步文件轮询。对我来说最好的解决方案是,如果可以使用固定频率进行引脚检查(信号处理的采样周期应该是恒定的)。

对此的设置可能是:

@kernel:字符模块 + 内核线程 + gpio 设备树接口 + DSP 恒定采样时间

@user space: i/o app 从字符模块同步读取

想法/提示?

【问题讨论】:

  • 如果您可以在 GPIO 更改时使用某种中断,那么在内核中执行此操作将是一个优势。如果您要编写内核模式线程,那么在用户空间中使用实时线程可能会更好。
  • 如果您想在用户空间执行此操作,您需要确保您拥有最新的内核并安装了libgpiod
  • libgpiod 正在使用“gpio.h”内核接口。字符模块正在像文件一样读取引脚。 ppoll + timeout 用于验证是否发生了更改。 lib bcm2845 使用内存映射来访问 GPIO 寄存器。我认为这是最快的方法,因为 mmu 只将逻辑地址转换为物理地址。使用 mmap 是在检查引脚时避开设备层。循环读取部分内存的 mmap + 线程组合是什么?
  • @StefanJaritz 如果你想拍脚,你可能会找到更简单的方法来做到这一点,而不是在 MMIO 空间中快速戳一些地址。
  • @0andriy 这是真的。就我而言,我在引脚上附加了一些自定义硬件。认为没有必要使用额外的接口来访问引脚。据我所见,'kernel/gpio.h' 似乎是读取引脚的一个很好的折衷方案。定期检查它们是怎么回事?什么是更好的选择:内核线程还是用户空间中的线程?

标签: linux kernel-module gpio sample-data


【解决方案1】:

我有一个解决方案。

我写过这样一个模块:

https://github.com/Appyx/gpio-reflect

您可以从 GPIO 引脚同步读取任何信号。

您可以使用输出并以您的采样率计算信号。 只需划分句点。

【讨论】:

  • 此代码正在检测引脚的变化。这是基于事件的。我要问的问题是要在恒定时基上对引脚进行采样(例如每 100 毫秒读取引脚 1,56 和 96)。尽管将引脚(文件源)与中断连接似乎是最先进的解决方案。 @Appyx 解决方案基于derekmolloy.ie/kernel-gpio-programming-buttons-and-leds
  • 是的,我知道,但是您可以以发送示例为例,只需替换 gpio 功能。最好的解决方案是使用 hr_timer 进行恒定采样,然后将值写入读取缓冲区。
  • 有什么更好的 - 使用 hrtimer 而不是内核线程来定期读/写 pin?可以在这里找到一个很好的 hrtimer 示例:gist.github.com/maggocnx/5946907
  • hrtimer 更好,因为使用线程可以获得轮询解决方案。使用计时器,您可以获得非常精确的计时,同时仍然采用基于事件的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多