什么是/ sys / class / gpio / export和`/ sys / class / gpio / unexport机制?底层sysfs功能是什么?

问题描述

在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特殊文件“导出到用户空间”,然后允许用户应用程序使用指定的GPIO引脚以及到特殊设备文件的文件I / O。

GPIO Sysfs Interface for Userspace

“导出” ...

用户空间可能要求内核将GPIO的控制输出到用户空间 通过将其编号写入此文件。

示例:“ echo 19> export”将为GPIO#19创建一个“ gpio19”节点, 如果内核代码没有要求。

“取消导出” ...

取消导出到用户空间的效果。

示例:“ echo 19> unexport”将删除导出的“ gpio19”节点 使用“导出”文件。

因此,如果我指定echo 938 > /sys/class/gpio/export,则会创建一个包含特殊设备文件/sys/class/gpio/gpio938/sys/class/gpio/gpio938/value的特殊设备文件文件夹/sys/class/gpio/gpio938/direction。当我执行echo 938 > /sys/class/gpio/unexport时,那些特殊的设备文件会被删除吗?

在研究在Android 5.1下将GPIO引脚与DragonBoard 410C结合使用的过程中,我讲了关于此设备的在线课程,我说是在启动初始化脚本中添加以下几行。

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引脚,因此应用程序可以只使用这些引脚,而不必担心exportunexport ?用户应用程序可以只对特殊设备执行读/写操作,而不必先使用sudo echo 938 > /sys/class/gpio/export

由启动初始化脚本创建的这些特殊文件的访问和共享权限是什么,并且多个应用程序可以同时操纵相同的GPIO引脚吗?

解决方法

/sys/class/gpio中的伪文件是内核接口中函数调用的较薄包装。内核文档[1]中有一条有关导入/导出功能用途的线索:

内核驱动程序请求GPIO后,可能仅使其可用 在sysfs界面中通过gpiod_export()。驾驶员可以控制 信号方向是否可能改变。这有助于驾驶员预防 意外破坏重要系统状态的用户空间代码。

这种显式导出可以帮助调试(通过进行某些类型的调试) 实验更容易),或者可以提供始终存在的界面 适合作为董事会支持包的一部分进行记录。

因此,从本质上讲,存在此功能是为了防止用户空间应用程序粗心践踏I / O设备的状态。我不知道它在实践中有多有用。

[1] https://www.kernel.org/doc/html/latest/admin-guide/gpio/sysfs.html

,

注意:从4.8版的Linux内核(https://www.kernel.org/doc/Documentation/gpio/sysfs.txt)开始,不赞成通过此旧版sysfs接口访问GPIO。 它将在2020年从内核中删除。 使用GPIO的新方法是通过“基于描述符”的字符设备ABI(应用程序二进制接口)。您应该对Libgpiod(图书馆通用输入/输出设备)进行研究,并从https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about/

开始 ,

Linux文件系统中有几种目录结构,它们不是实际的磁盘文件目录。相反,这些目录结构及其中的“文件”是伪文件或Linux操作系统服务,以及表示为文件的数据,可以使用文件操作进行访问,但不是存储在诸如硬盘或固态硬盘之类的持久性存储中的实际文件。状态磁盘。

A Study of Modern Linux API Usage and Compatibility: What to Support When You’re Supporting

除了主系统调用表外,Linux还导出许多 通过伪文件系统(例如/ proc,/ dev和 / sys。这些称为伪文件系统,因为它们不支持 通过磁盘,而是将内核数据结构的内容导出到 应用程序或管理员,就好像它们存储在文件中一样。 这些伪文件系统是导出调整的便利位置 参数,统计信息以及其他特定于子系统的设备 特定的API。尽管许多伪文件用于 命令行或管理员脚本中的一些,通常是 由应用程序使用。为了充分了解 Linux内核,还必须考虑伪文件。

伪文件的比喻

从用户角度考虑这些伪文件的一种方法是,它们是Linux内核的一种Remote Procedure Call接口,该接口使用文件系统语义来请求执行某些操作。文件系统语义映射到以下常规操作和行为:

  • 打开伪文件意味着打开用户应用程序与Linux内核中的某些功能之间的连接
  • 读取伪文件表示通过连接读取Linux内核中某些功能提供的数据块
  • 写入伪文件意味着通过连接将请求消息发送到Linux内核中的某些功能(消息可以是带有数据的命令,仅命令或仅数据)
  • 关闭伪文件意味着关闭用户应用程序与Linux内核中某些功能之间的连接

不同的伪文件公开了不同的Linux内核数据和服务,这意味着有关文件操作如何映射到通过伪文件公开的Linux内核功能的接口规范将不仅取决于Linux内核功能或处理器的处理程序,而且会有所不同。伪文件,还有Linux内核版本。

此StackOverFlow帖子Create sysfs entry from kernel module/sys中包含一个伪文件处理程序的简单示例,显示了提供Linux内核为新伪文件钩住处理程序所需的功能接口的基本知识文件放入Linux内核。

此StackOverFlow帖子How to create proc entry under /proc/driver?包含/proc中伪文件处理程序的简单示例。

这两个简单示例均具有与源代码相似的结构。但是,这些特定示例可能正在使用不赞成使用的Linux内核接口,因此我提供这些链接只是为了说明伪文件处理程序的基础功能。

导出和取消导出

通常,运行Linux的基础硬件的GPIO引脚不暴露给用户应用程序。 Linux内核使用设备驱动程序使用这些引脚与设备进行交互。

export的目的是将选定的GPIO引脚作为伪文件暴露给用户空间,从而允许用户应用程序与某些硬件执行自己的交互。并非所有可用的或可能的GPIO引脚都可以暴露。使用export可以暴露哪些引脚,将取决于在Linux内核中插入了哪些/sys处理程序以及这些处理程序允许的操作。

实际上暴露哪些伪文件以及如何使用这些伪文件将取决于GPIO引脚的功能,例如数字引脚与模拟引脚与支持PWM或具有上拉或下拉电阻的引脚。公开哪些文件还取决于/sys/class/gpio/的处理程序提供的功能。 GPIO引脚可能具有可以使用的上拉或下拉电阻,但处理程序可能未提供用于对其进行操作的接口。

export伪文件的请求将创建一个代表所请求GPIO引脚的伪文件目录。这是通过将请求写入export伪文件来完成的,该消息中包含一条消息,其中包含export命令需要的数据,以便正确识别所请求的GPIO引脚。然后,此消息由Linux内核中的GPIO export sysfs处理程序处理,以创建代表GPIO引脚的伪文件文件夹以及为用户指定GPIO提供用户应用程序和sysfs处理程序之间接口的伪文件。销。该处理程序提供物理GPIO引脚和引脚设备驱动程序与伪文件表示或接口之间的层。

unexport伪文件删除了GPIO引脚伪文件,因此不再与用户应用程序中的GPIO引脚进行交互。

有关PWM sysfs支持的说明:正如通过sysfs接口和/sys支持GPIO引脚一样,也支持PWM引脚。根文件夹为/sys/class/pwm,其功能在体系结构上与GPIO引脚相似。有一种类似的exportunexport功能可以使PWM引脚可用,并且通过对与代表PWM引脚的伪文件夹相关联的一组文件进行标准文件操作来使用导出的PWM伪文件。请参阅Using PMIC PWM on Dragonboard410c,其中介绍了“ PWM通过MPP_4引脚(即低速扩展连接器上的引脚28)暴露出来”的基本知识。

启动脚本更改

引导脚本更改使用/sys/class/gpio/export创建请求的GPIO伪文件。但是,创建的伪文件具有一组在创建伪文件时设置的默认访问权限。由于创建是在具有root特权的初始化过程中进行的,因此chmod命令用于允许任何用户应用程序与创建的伪文件进行交互,而不仅仅是创建它们的用户root。

由于export是在引导和初始化期间完成的,目的是创建GPIO引脚伪文件,该文件将在设备加电时保持在原位,并在设备处于打开状态时一直保持在原位在使用中。

DragonBoard 410C的低功率连接器上的每个GPIO引脚均由几个伪文件表示,value用于传达引脚的值(高低)和{{1} },用于传达引脚的方向(无论是输入引脚还是输出引脚)。因此,我们需要对希望用户应用程序访问的每个伪文件执行direction,包括这些伪文件所在的伪文件文件夹,例如,chmod包含{{1} }和/sys/class/gpio/gpio938

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...