什么是 /sys/class/gpio/export 和 `/sys/class/gpio/unexport 机制以及底层 sysfs 功能是什么?
what is the /sys/class/gpio/export and `/sys/class/gpio/unexport mechanism and what is the underlying sysfs functionality?
在 Android 和 Linux 下使用旧版 sysfs GPIO 该过程的第一步是 export
您要使用的特定 GPIO 引脚。当你完成 GPIO 引脚到 unexport
它。
我一直在寻找 export
命令实际作用的解释,但是我发现的所有内容都是关于内置 bash
命令的,它与 GPIO 无关。
然后我意识到来自命令行的实际命令是 echo 938 > /sys/class/gpio/export
而 /sys/class/gpio/export
是文件夹 /sys/class/gpio
.
中的一个特殊设备文件
我发现的唯一评论表明将 GPIO 引脚编号写入 /sys/class/gpio/export
会导致与该 GPIO 引脚关联的 GPIO 特殊文件“导出到用户 space”,然后允许用户应用程序将指定的 GPIO 引脚与文件 I/O 一起使用到特殊设备文件。
GPIO Sysfs Interface for Userspace
“export” …
Userspace may ask the kernel to export control of a GPIO to userspace
by writing its number to this file.
Example: “echo 19 > export” will create a “gpio19” node for GPIO #19,
if that’s not requested by kernel code.
“unexport” …
Reverses the effect of exporting to userspace.
Example: “echo 19 > unexport” will remove a “gpio19” node exported
using the “export” file.
因此,如果我指定 echo 938 > /sys/class/gpio/export
,则会创建一个包含特殊设备文件 /sys/class/gpio/gpio938/value
和 /sys/class/gpio/gpio938/direction
的特殊设备文件夹 /sys/class/gpio/gpio938
。当我执行 echo 938 > /sys/class/gpio/unexport
时,那些特殊的设备文件会被删除吗?
在研究如何使用 DragonBoard 410C 的 GPIO 引脚 Android 5.1 关于此设备的在线课程我正在学习据说将以下行添加到引导初始化脚本中。
set -A pins 938 915 1017 926 937 930 914 971 901 936 935
for i in 0 1 2 3 4 5 6 7 8 9 10
do
echo ${pins[i]} > /sys/class/gpio/export;
chmod 777 /sys/class/gpio/gpio${pins[i]};
chmod 777 /sys/class/gpio/gpio${pins[i]}/value;
chmod 777 /sys/class/gpio/gpio${pins[i]}/direction;
done
我的理解是这些命令为 GPIO 引脚 938、915、1017、926、937、914、901、936、935 创建了特殊的设备文件,以便应用程序可以读取和写入这些 GPIO 引脚以执行操作例如通过向 /sys/class/gpio/gpio938/value
.
写入值来打开和关闭 LED
我对这个引导初始化脚本的理解是,这消除了用户在每个 shell 命令行中使用 sudo
命令来执行这些命令的需要在 运行 之前使用 sysfs
访问 GPIO 引脚的应用程序。是真的吗?
我的问题
这些特殊设备文件 /sys/class/gpio/export
和 /sys/class/gpio/unexport
是什么,它们如何连接到 Linux 内核中的某种功能,这些功能在 /sys/class/gpio
文件夹?
对于引导初始化脚本的建议更改是代表 GPIO 引脚的特殊设备文件,任何人都可以访问这些文件,这样应用程序就可以只使用这些引脚而不必理会 export
或 unexport
?用户应用程序可以只对特殊设备执行 read/write 而无需先使用 sudo echo 938 > /sys/class/gpio/export
?
启动初始化脚本创建的这些特殊文件的访问和共享权限是多少?多个应用程序可以同时操作相同的 GPIO 引脚吗?
/sys/class/gpio
中的 pseudo-files 是内核接口中函数调用的相当薄的包装器。内核文档 [1] 中有关于 import/export 功能目的的线索:
After a kernel driver requests a GPIO, it may only be made available
in the sysfs interface by gpiod_export(). The driver can control
whether the signal direction may change. This helps drivers prevent
userspace code from accidentally clobbering important system state.
This explicit exporting can help with debugging (by making some kinds
of experiments easier), or can provide an always-there interface
that’s suitable for documenting as part of a board support package.
因此,从本质上讲,此功能的存在是为了防止 user-space 应用程序不小心破坏 I/O 设备的状态。在实践中有多大用处,我不知道。
[1] https://www.kernel.org/doc/html/latest/admin-guide/gpio/sysfs.html
Linux 文件系统中有几个目录结构不是实际的磁盘文件目录。相反,这些目录结构和其中的“文件”是伪文件或 Linux 操作系统服务和数据,它们以文件形式呈现,可以使用文件操作访问,但不是存储在持久存储中的实际文件,例如硬盘或固态硬盘。
A Study of Modern Linux API Usage and Compatibility: What to Support When You’re Supporting
In addition to the main system call table, Linux exports many
additional APIs through pseudo-file systems, such as /proc, /dev, and
/sys. These are called pseudo-file systems because they are not backed
by disk, but rather export the contents of kernel data structures to
an application or administrator as if they were stored in a file.
These pseudofile systems are a convenient location to export tuning
parameters, statistics, and other subsystem-specific or device
specific APIs. Although many of these pseudo-files are used on the
command line or in scripts by an administrator, a few are routinely
used by applications. In order to fully understand usage patterns of
the Linux kernel, pseudo-files must also be considered.
伪文件类比
从用户角度考虑这些伪文件的一种方法是,它们是 Linux 内核的一种 Remote Procedure Call 接口,使用文件系统语义来请求完成某些操作。文件系统语义映射到以下通用操作和行为:
- 打开伪文件意味着打开用户应用程序和 Linux 内核中的某些功能之间的连接
- 读取伪文件是指通过连接
读取Linux内核中某些功能提供的数据块
- 写伪文件是指通过连接向Linux内核中的某些功能发送请求消息(消息可能是带数据的命令,也可能是命令,也可能只有数据)
- 关闭伪文件意味着关闭用户应用程序和 Linux 内核中的某些功能之间的连接
不同的伪文件公开不同的 Linux 内核数据和服务,这意味着关于文件操作如何映射到通过伪文件公开的 Linux 内核功能的接口规范将有所不同,具体取决于仅针对伪文件的 Linux 内核功能或处理程序以及 Linux 内核版本。
这篇 Whosebug 帖子 Create sysfs entry from kernel module 包含 /sys
中伪文件处理程序的一个简单示例,展示了 Linux 内核需要挂钩的提供函数接口的基础知识新伪文件的处理程序进入 Linux 内核。
此 Whosebug 帖子 How to create proc entry under /proc/driver? 包含 /proc
.
中伪文件的处理程序的简单示例
这两个简单示例的结构都与源代码相似。然而,这些具体示例可能使用了已弃用的 Linux 内核接口,因此我提供这些链接只是为了说明伪文件处理程序的基础功能。
导出和取消导出
通常 Linux 为 运行 的底层硬件的 GPIO 引脚不会暴露给用户应用程序。 Linux 内核使用这些引脚使用设备驱动程序与设备进行交互。
export
的目的是将选定的 GPIO 引脚作为伪文件公开给用户 space,允许用户应用程序执行自己与某些硬件的交互。并非所有可用或可能的 GPIO 引脚都可能暴露。使用 export
可以公开哪些引脚将取决于 /sys
处理程序已插入 Linux 内核以及这些处理程序允许的内容。
实际上公开了哪些伪文件以及如何使用这些伪文件将取决于 GPIO 引脚的功能,例如数字引脚与模拟引脚与支持 PWM 或具有上拉或下拉电阻的引脚。公开哪些文件还取决于 /sys/class/gpio/
的处理程序提供的功能。 GPIO 引脚可能有一个可以使用的上拉或下拉电阻,但处理程序可能不提供操作它的接口。
对 export
伪文件的请求将创建一个代表请求的 GPIO 引脚的伪文件目录。这是通过向 export
伪文件写入请求以及包含 export
命令正确识别所请求的 GPIO 引脚所需的数据的消息来完成的。然后,Linux 内核中的 GPIO export
sysfs 处理程序处理此消息,以创建代表 GPIO 引脚的伪文件夹以及提供用户应用程序和 sysfs 处理程序之间接口的伪文件对于指定的 GPIO 引脚。处理程序提供物理 GPIO 引脚和引脚设备驱动程序与伪文件表示或接口之间的层。
unexport
伪文件删除了 GPIO 引脚伪文件,因此不再可以从用户应用程序与代表的 GPIO 引脚进行交互。
关于 PWM sysfs 支持的注意事项: 正如通过 sysfs 接口支持 GPIO 引脚,/sys
也支持 PWM 引脚。根文件夹是 /sys/class/pwm
,其功能在架构上与 GPIO 引脚的功能相似。有一个类似的 export
和 unexport
功能可以使 PWM 引脚可用,并且使用导出的 PWM 伪文件是通过对与表示 PWM 引脚的伪文件夹关联的一组文件进行标准文件操作。请参阅 Using PMIC PWM on Dragonboard410c,其中描述了“PWM 通过 MPP_4 引脚暴露的基础知识,whih 是低速扩展连接器上的引脚 28。"
引导脚本更改
引导脚本更改使用 /sys/class/gpio/export
创建请求的 GPIO 伪文件。但是,创建的伪文件具有一组默认访问权限,这些权限是在创建伪文件时设置的。由于创建是在具有 root 权限的初始化期间进行的,因此 chmod
命令用于允许任何用户应用程序与创建的伪文件进行交互,而不仅仅是创建它们的用户 root。
由于 export
是在启动和初始化期间完成的,目的是创建 GPIO 引脚伪文件,这些文件将在设备通电时保留在原位,并且只要设备正在使用中。
DragonBoard 410C 低功耗连接器上的每个 GPIO 引脚都由几个伪文件表示,value
用于传递引脚的值(无论是高电平还是低电平)和 direction
用于传达引脚的方向(无论是输入引脚还是输出引脚)。因此,我们需要对每个我们希望用户应用程序访问的伪文件执行 chmod
,包括这些伪文件所在的伪文件夹,例如 /sys/class/gpio/gpio938
其中包含 /sys/class/gpio/gpio938/value
和 /sys/class/gpio/gpio938/direction
.
在 Android 和 Linux 下使用旧版 sysfs GPIO 该过程的第一步是 export
您要使用的特定 GPIO 引脚。当你完成 GPIO 引脚到 unexport
它。
我一直在寻找 export
命令实际作用的解释,但是我发现的所有内容都是关于内置 bash
命令的,它与 GPIO 无关。
然后我意识到来自命令行的实际命令是 echo 938 > /sys/class/gpio/export
而 /sys/class/gpio/export
是文件夹 /sys/class/gpio
.
我发现的唯一评论表明将 GPIO 引脚编号写入 /sys/class/gpio/export
会导致与该 GPIO 引脚关联的 GPIO 特殊文件“导出到用户 space”,然后允许用户应用程序将指定的 GPIO 引脚与文件 I/O 一起使用到特殊设备文件。
GPIO Sysfs Interface for Userspace
“export” …
Userspace may ask the kernel to export control of a GPIO to userspace by writing its number to this file.
Example: “echo 19 > export” will create a “gpio19” node for GPIO #19, if that’s not requested by kernel code.
“unexport” …
Reverses the effect of exporting to userspace.
Example: “echo 19 > unexport” will remove a “gpio19” node exported using the “export” file.
因此,如果我指定 echo 938 > /sys/class/gpio/export
,则会创建一个包含特殊设备文件 /sys/class/gpio/gpio938/value
和 /sys/class/gpio/gpio938/direction
的特殊设备文件夹 /sys/class/gpio/gpio938
。当我执行 echo 938 > /sys/class/gpio/unexport
时,那些特殊的设备文件会被删除吗?
在研究如何使用 DragonBoard 410C 的 GPIO 引脚 Android 5.1 关于此设备的在线课程我正在学习据说将以下行添加到引导初始化脚本中。
set -A pins 938 915 1017 926 937 930 914 971 901 936 935
for i in 0 1 2 3 4 5 6 7 8 9 10
do
echo ${pins[i]} > /sys/class/gpio/export;
chmod 777 /sys/class/gpio/gpio${pins[i]};
chmod 777 /sys/class/gpio/gpio${pins[i]}/value;
chmod 777 /sys/class/gpio/gpio${pins[i]}/direction;
done
我的理解是这些命令为 GPIO 引脚 938、915、1017、926、937、914、901、936、935 创建了特殊的设备文件,以便应用程序可以读取和写入这些 GPIO 引脚以执行操作例如通过向 /sys/class/gpio/gpio938/value
.
我对这个引导初始化脚本的理解是,这消除了用户在每个 shell 命令行中使用 sudo
命令来执行这些命令的需要在 运行 之前使用 sysfs
访问 GPIO 引脚的应用程序。是真的吗?
我的问题
这些特殊设备文件 /sys/class/gpio/export
和 /sys/class/gpio/unexport
是什么,它们如何连接到 Linux 内核中的某种功能,这些功能在 /sys/class/gpio
文件夹?
对于引导初始化脚本的建议更改是代表 GPIO 引脚的特殊设备文件,任何人都可以访问这些文件,这样应用程序就可以只使用这些引脚而不必理会 export
或 unexport
?用户应用程序可以只对特殊设备执行 read/write 而无需先使用 sudo echo 938 > /sys/class/gpio/export
?
启动初始化脚本创建的这些特殊文件的访问和共享权限是多少?多个应用程序可以同时操作相同的 GPIO 引脚吗?
/sys/class/gpio
中的 pseudo-files 是内核接口中函数调用的相当薄的包装器。内核文档 [1] 中有关于 import/export 功能目的的线索:
After a kernel driver requests a GPIO, it may only be made available in the sysfs interface by gpiod_export(). The driver can control whether the signal direction may change. This helps drivers prevent userspace code from accidentally clobbering important system state.
This explicit exporting can help with debugging (by making some kinds of experiments easier), or can provide an always-there interface that’s suitable for documenting as part of a board support package.
因此,从本质上讲,此功能的存在是为了防止 user-space 应用程序不小心破坏 I/O 设备的状态。在实践中有多大用处,我不知道。
[1] https://www.kernel.org/doc/html/latest/admin-guide/gpio/sysfs.html
Linux 文件系统中有几个目录结构不是实际的磁盘文件目录。相反,这些目录结构和其中的“文件”是伪文件或 Linux 操作系统服务和数据,它们以文件形式呈现,可以使用文件操作访问,但不是存储在持久存储中的实际文件,例如硬盘或固态硬盘。
A Study of Modern Linux API Usage and Compatibility: What to Support When You’re Supporting
In addition to the main system call table, Linux exports many additional APIs through pseudo-file systems, such as /proc, /dev, and /sys. These are called pseudo-file systems because they are not backed by disk, but rather export the contents of kernel data structures to an application or administrator as if they were stored in a file. These pseudofile systems are a convenient location to export tuning parameters, statistics, and other subsystem-specific or device specific APIs. Although many of these pseudo-files are used on the command line or in scripts by an administrator, a few are routinely used by applications. In order to fully understand usage patterns of the Linux kernel, pseudo-files must also be considered.
伪文件类比
从用户角度考虑这些伪文件的一种方法是,它们是 Linux 内核的一种 Remote Procedure Call 接口,使用文件系统语义来请求完成某些操作。文件系统语义映射到以下通用操作和行为:
- 打开伪文件意味着打开用户应用程序和 Linux 内核中的某些功能之间的连接
- 读取伪文件是指通过连接 读取Linux内核中某些功能提供的数据块
- 写伪文件是指通过连接向Linux内核中的某些功能发送请求消息(消息可能是带数据的命令,也可能是命令,也可能只有数据)
- 关闭伪文件意味着关闭用户应用程序和 Linux 内核中的某些功能之间的连接
不同的伪文件公开不同的 Linux 内核数据和服务,这意味着关于文件操作如何映射到通过伪文件公开的 Linux 内核功能的接口规范将有所不同,具体取决于仅针对伪文件的 Linux 内核功能或处理程序以及 Linux 内核版本。
这篇 Whosebug 帖子 Create sysfs entry from kernel module 包含 /sys
中伪文件处理程序的一个简单示例,展示了 Linux 内核需要挂钩的提供函数接口的基础知识新伪文件的处理程序进入 Linux 内核。
此 Whosebug 帖子 How to create proc entry under /proc/driver? 包含 /proc
.
这两个简单示例的结构都与源代码相似。然而,这些具体示例可能使用了已弃用的 Linux 内核接口,因此我提供这些链接只是为了说明伪文件处理程序的基础功能。
导出和取消导出
通常 Linux 为 运行 的底层硬件的 GPIO 引脚不会暴露给用户应用程序。 Linux 内核使用这些引脚使用设备驱动程序与设备进行交互。
export
的目的是将选定的 GPIO 引脚作为伪文件公开给用户 space,允许用户应用程序执行自己与某些硬件的交互。并非所有可用或可能的 GPIO 引脚都可能暴露。使用 export
可以公开哪些引脚将取决于 /sys
处理程序已插入 Linux 内核以及这些处理程序允许的内容。
实际上公开了哪些伪文件以及如何使用这些伪文件将取决于 GPIO 引脚的功能,例如数字引脚与模拟引脚与支持 PWM 或具有上拉或下拉电阻的引脚。公开哪些文件还取决于 /sys/class/gpio/
的处理程序提供的功能。 GPIO 引脚可能有一个可以使用的上拉或下拉电阻,但处理程序可能不提供操作它的接口。
对 export
伪文件的请求将创建一个代表请求的 GPIO 引脚的伪文件目录。这是通过向 export
伪文件写入请求以及包含 export
命令正确识别所请求的 GPIO 引脚所需的数据的消息来完成的。然后,Linux 内核中的 GPIO export
sysfs 处理程序处理此消息,以创建代表 GPIO 引脚的伪文件夹以及提供用户应用程序和 sysfs 处理程序之间接口的伪文件对于指定的 GPIO 引脚。处理程序提供物理 GPIO 引脚和引脚设备驱动程序与伪文件表示或接口之间的层。
unexport
伪文件删除了 GPIO 引脚伪文件,因此不再可以从用户应用程序与代表的 GPIO 引脚进行交互。
关于 PWM sysfs 支持的注意事项: 正如通过 sysfs 接口支持 GPIO 引脚,/sys
也支持 PWM 引脚。根文件夹是 /sys/class/pwm
,其功能在架构上与 GPIO 引脚的功能相似。有一个类似的 export
和 unexport
功能可以使 PWM 引脚可用,并且使用导出的 PWM 伪文件是通过对与表示 PWM 引脚的伪文件夹关联的一组文件进行标准文件操作。请参阅 Using PMIC PWM on Dragonboard410c,其中描述了“PWM 通过 MPP_4 引脚暴露的基础知识,whih 是低速扩展连接器上的引脚 28。"
引导脚本更改
引导脚本更改使用 /sys/class/gpio/export
创建请求的 GPIO 伪文件。但是,创建的伪文件具有一组默认访问权限,这些权限是在创建伪文件时设置的。由于创建是在具有 root 权限的初始化期间进行的,因此 chmod
命令用于允许任何用户应用程序与创建的伪文件进行交互,而不仅仅是创建它们的用户 root。
由于 export
是在启动和初始化期间完成的,目的是创建 GPIO 引脚伪文件,这些文件将在设备通电时保留在原位,并且只要设备正在使用中。
DragonBoard 410C 低功耗连接器上的每个 GPIO 引脚都由几个伪文件表示,value
用于传递引脚的值(无论是高电平还是低电平)和 direction
用于传达引脚的方向(无论是输入引脚还是输出引脚)。因此,我们需要对每个我们希望用户应用程序访问的伪文件执行 chmod
,包括这些伪文件所在的伪文件夹,例如 /sys/class/gpio/gpio938
其中包含 /sys/class/gpio/gpio938/value
和 /sys/class/gpio/gpio938/direction
.