在Linux中使用libgpiod获取gpio输出的值



我在嵌入式定制板上使用Linux(内核5.8.17(,并有一个脚本使用libgpiod包执行一些gpioget和gpioset操作。使用gpioset设置输出引脚非常有效,使用gpioget获取输入引脚的值也是如此。但是,当我需要知道输出引脚的当前值时,使用gpioget会更改引脚值和方向。

这里有一个例子:

~# gpioinfo |grep MB_AC_ON
line 230:   "MB_AC_ON"       unused  output  active-high
~# gpioset $(gpiofind "MB_AC_ON")=1
~# gpioget $(gpiofind "MB_AC_ON")
0
~# gpioinfo |grep MB_AC_ON
line 230:   "MB_AC_ON"       unused   input  active-high

将引脚设置为"1"有效。但随后使用gpioget检查同一引脚的当前值,值将更改为"0",方向将更改为输入。是否可以使用libgpiod获取gpio输出的值?

当我通过gpioset -h检查详细信息时有一张纸条:我想这就是你问题的答案。

注意:通过字符设备控制的GPIO线的状态当最后一个进程引用该文件时恢复为默认值表示设备文件的描述符退出。这意味着运行gpioset是错误的,让它退出并期望行继续被驱动为高或低。如果给定的引脚是浮动的,则可能会发生这种情况,但它必须被解释为未定义的行为。

如果我们更详细地查看代码(gpioset: ../libgpiod/tools/gpioset.c(。我们可以看到下面的这些代码块,这导致行获得默认值(您无法保留您使用gpioset设置的值(。

gpiod_line_release_bulk(lines);
gpiod_chip_unref(chip);
gpiod_line_bulk_free(lines);
free(offsets);
free(values);

事实上,接受的答案只包含问题的一个方面。是的,gpioset不保证在退出后保持GPIO状态。可以使用mode参数来保持文件描述符打开,直到它接收到信号为止。[1]

gpioset --mode=signal $(gpiofind "MB_AC_ON")=1

对于libgpiod v2,gpioset的行为不同,默认情况下不会退出,除非它收到信号。对于通过标签直接指定行的其他简化,上面的等效命令在v2中可以归结为以下内容:

gpioset MB_AC_ON=1

尽管对于一些GPIO控制器来说,即使在gpioset退出后,状态实际上也是持久的,但OP似乎也是如此。在这些情况下,即使您只想获得输出的当前状态,您仍然会遇到使用gpioget之后将输出方向改回输入的问题。

在这种情况下,libgpiod的v2具有新的参数--as-is以保持方向[2]:

gpioget --as-is MB_AC_ON

[1]https://manpages.debian.org/testing/gpiod/gpioset.1.en.html
[2]https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/commit/tools/gpioget.c?h=v2.0&id=3a912fbc1e2697f4479396fd11557b943b31d217

最新更新