![Linux 4.8+ 中惯用的 GPIO 控制](https://linux22.com/image/194810/Linux%204.8%2B%20%E4%B8%AD%E6%83%AF%E7%94%A8%E7%9A%84%20GPIO%20%E6%8E%A7%E5%88%B6.png)
GPIO 的用户空间接口是改变了在 Linux 4.8 中,弃用旧的 sysfs 接口,转而使用字符设备。我正在努力了解如何将这个新模型转化为对我的用例有意义的东西。
我有一个外围设备,可以使用 GPIO 从 ARM CPU 进行控制。它有一个我必须遵循的启动顺序 - 首先打开 5v 稳压器(一个单独的设备),然后打开外设电源,最后在至少 5 毫秒过去后释放复位。所以我有 3 个 GPIO,5v_en、power_on 和 reset_n。外围设备从通电到运行大约需要一分钟,因此不能有不必要的重新启动。其他要求是我切换重置以完成固件/配置更新,并且我有一个低功耗模式,其中外设和调节器关闭。
我看到了三种选择,但没有一个是理想的。
对于这些示例,假设 gpio0=5v_en、gpio1=power_on 且 gpio2=reset_n
选项#1:Sysfs(已弃用)
cd /sys/class/gpio
echo 0 > export
echo 1 > export
echo 2 > export
echo out > gpio0/direction
echo out > gpio1/direction
echo out > gpio2/direction
echo 1 > gpio0/value
echo 1 > gpio1/value
sleep 1
echo 1 > gpio2/value
将以上内容放在 init 脚本中。当我需要更改引脚的值时,只需将open
值文件写入新值即可。这对我来说最有意义。不幸的是,它现在已被弃用。
选项#2:gpioset
gpioset -m signal -b 1 0=1
gpioset -m signal -b 1 1=1
sleep 1
gpioset -m signal -b 1 2=1
将以上内容放在 init 脚本中。当我需要更改引脚的值时,确定gpioset
进程的 PID、kill
进程并使用新值重新启动。当 gpioset 未运行时,引脚的状态在技术上是“未定义的”。似乎不是一条路。
选项#3:守护进程
编写我自己的自定义守护程序,而不是运行 gpioset,其唯一目的是为 /dev 中的 gpio 字符设备保留打开的文件描述符。该程序必须简单且最小化,因为如果它崩溃,它正在管理的所有 GPIO 的状态将变得不确定。然而,它还必须维护某种 IPC 来与其他想要控制 GPIO 的程序进行通信。本质上,我们设置了一个间接层,以防止想要使用 GPIO 的事物直接使用它们。
这感觉完全是过度设计的,与让每个人随心所欲地使用 /sys/gpio 相比,起草、实现和记录 IPC 协议确实很烦人。
我有一种感觉,选项 #3 是 Linux 打算让我们管理未来 GPIO 的方式,但它会增加大量额外的工作,在这个特定的用例中没有任何好处。带着这个问题,希望能够理解
- 还有其他我没有考虑过的更有意义的策略吗?
- 如何降低程序崩溃导致未定义 GPIO 状态的风险?