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

如何解决什么是/ 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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-