Linux应用编程 - sysfs方式操作GPIO

简介:

        应用层想要对底层硬件进行操控,通常可以通过两种方式                        

  • /dev/目录下的设备文件(设备节点)​​​​​​​
  • /sys/目录下设备的属性文件

        通常情况下,简单地设备会使用 sysfs 方式操控,如 LED、GPIO 等。较复杂的设备通常会使用设备节点的方式,如 LCD、触摸屏、摄像头等。

首先,配置内核启用sysfs GPIO支持

CONFIG_GPIO_SYSFS=y

一、命令操作GPIO

以GPIO1_IO03为例,对应gpio编号为3

1、GPIO输出

$ echo 3 > /sys/class/gpio/export                          //导出编号为3的GPIO,生成gpio3
$ echo out > /sys/class/gpio/gpio3/direction         //设置输出 out:输出 in:输入
$ echo 1 > /sys/class/gpio/gpio3/value                 //输出高电平 1:高电平 0:低电平
$ echo 3 > /sys/class/gpio/unexport                     //删除导出的编号为3的GPIO

2、GPIO输入

配置输入前也要导出gpio,不再赘述

$ echo in > /sys/class/gpio/gpio3/direction           //设置输出 out:输出 in:输入

$ cat /sys/class/gpio/gpio3/value                          //查看输入电平

二、代码操作GPIO

1、设置gpio输出

/*
*****************************************************************************************
*	函 数 名: sysfs_gpio_set
*	功能说明: 设置gpio电平状态
*	形    参: u32GpioNum : gpio编号
*             u32Value   : 1:高电平,0:低电平
*	返 回 值: 0:成功,-1:失败
*****************************************************************************************
*/
s32 sysfs_gpio_set(u32 u32GpioNum, u32 u32Value)
{u8 u8Buf[2]     ={0,};u8 u8Fname[128] = {0,};FILE *fp        = NULL;/* 1.引脚导出, 类似于:echo 3 > /sys/class/gpio/export */sprintf((char *)u8Fname, "/sys/class/gpio/export");    if (NULL == (fp = fopen((char *)u8Fname, "w"))){LOG_ERR("Cannot open %s.\n", u8Fname);return -1;}fprintf(fp, "%d", u32GpioNum);              //gpio编号写入 fp文件fclose(fp);/* 2.设置方向,类似于:echo out > /sys/class/gpio/gpio3/direction */memset(u8Fname, 0x0, sizeof(u8)*128);sprintf(u8Fname, "/sys/class/gpio/gpio%d/direction", u32GpioNum);if (NULL == (fp = fopen(u8Fname, "rb+"))){LOG_ERR("Cannot open %s.\n", u8Fname);return -1;}fprintf(fp, "out");                         //设置方向,"out"写入 fpfclose(fp);/* 3.设置gpio输出电平,类似于:echo 1 > /sys/class/gpio/gpio3/value */memset(u8Fname, 0x0, sizeof(u8)*128);sprintf((char *)u8Fname, "/sys/class/gpio/gpio%d/value", u32GpioNum);if (NULL == (fp=fopen((char *)u8Fname, "rb+"))){LOG_ERR("Cannot open %s.\n", u8Fname);return -1;}u8Buf[0] = u32Value + 0x30;                         //把数字转为ASCII码fwrite(u8Buf, sizeof(u8), sizeof(u8Buf)-1, fp);     //写入gpio电平,fclose(fp);/* 4.取消导出, 类似于:echo 3 > /sys/class/gpio/unexport */sprintf((char *)u8Fname, "/sys/class/gpio/unexport");if (NULL == (fp = fopen((char *)u8Fname, "w"))){LOG_ERR("Cannot open %s.\n", u8Fname);return -1;}fprintf(fp, "%d", u32GpioNum);fclose(fp);return 0;
}

2、获取gpio输入电平状态

/*
*****************************************************************************************
*	函 数 名: sysfs_gpio_get
*	功能说明: 获取gpio电平状态
*	形    参: u32GpioNum : gpio编号
*	返 回 值: 返回1:高电平,返回0:低电平
*****************************************************************************************
*/
s32 sysfs_gpio_get(u32 u32GpioNum)
{u8 u8Buf[8] = {0};u8 u8Fname[128] = {0,};FILE *fp        = NULL;/* 1.引脚导出, 等价于:echo 3 > /sys/class/gpio/export */sprintf((char *)u8Fname, "/sys/class/gpio/export");if (NULL == (fp = fopen((char *)u8Fname, "w"))){LOG_ERR("Cannot open %s.\n", u8Fname);return -1;}fprintf(fp, "%d", u32GpioNum);                  //gpio编号写入 fp文件fclose(fp);/* 2.设置方向,等价于:echo in > /sys/class/gpio/gpio3/direction */memset(u8Fname, 0x0, sizeof(u8)*128);sprintf(u8Fname, "/sys/class/gpio/gpio%d/direction", u32GpioNum);if (NULL == (fp = fopen(u8Fname, "rb+"))){LOG_ERR("Cannot open %s.\n", u8Fname);return -1;}fprintf(fp, "in");                              //设置方向,"in"写入 fpfclose(fp);/* 3.获取gpio电平,类似于:cat /sys/class/gpio/gpio3/value */memset(u8Fname, 0x0, sizeof(u8)*128);sprintf((char *)u8Fname, "/sys/class/gpio/gpio%d/value", u32GpioNum);if (NULL == (fp=fopen((char *)u8Fname, "rb+"))){LOG_ERR("Cannot open %s.\n", u8Fname);return -1;}fread(u8Buf, sizeof(u8), sizeof(u8), fp);       //读到 gpio电平, 字符串格式fclose(fp);/* 4.取消导出, 等价于:echo 3 > /sys/class/gpio/unexport */sprintf((char *)u8Fname, "/sys/class/gpio/unexport");if (NULL == (fp = fopen((char *)u8Fname, "w"))){LOG_ERR("Cannot open %s.\n", u8Fname);return -1;}fprintf(fp, "%d", u32GpioNum);fclose(fp);return atoi((char *)u8Buf);         //返回gpio电平
}

3、应用代码测试

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "hal.h"
#include "hal_gpio.h"/* LED  GPIO1_IO03 gpionum = (1 - 1) * 32 + 3 = 3  */
int main(int argc, char* argv[])
{int i;u32 u32Gpio, u32Io, u32GpioNum;/* GPIO1_IO03 转换num */u32Gpio = 1;u32Io = 3;u32GpioNum = (u32Gpio - 1) * 32 + u32Io;if (argc != 2 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {printf("Usage: %s""0 : off\n""1 : on\n""2 : flip\n""\n", argv[0]);return -1;}switch((int)argv[1]) {case 0:sysfs_gpio_set(u32GpioNum, 0);break;case 1: sysfs_gpio_set(u32GpioNum, 1);break;case 2:for (i = 0; i < 3; i++) {sysfs_gpio_set(u32GpioNum, 1);sleep(1);sysfs_gpio_set(u32GpioNum, 0);sleep(1);}break;default:return -1;}return 0;
}

测试结果:

$ ./gpio_test 0                        //gpio3输出低电平

$ ./gpio_test 1                        //gpio3输出高电平

$ ./gpio_test 2                        //gpio3高低电平翻转

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/750316.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据-基础架构设施演进的过程

一、第一阶段-Hadoop 以Hadoop为代表的离线数据处理基础设施 1.1、围绕HDFS和MR&#xff0c;产生了一系列的组件 面向在线KV操作的HBase面向SQL的Hive面向工作流的PIG 1.2、随着对批处理性能要求越来越高&#xff0c;产生了Tez、Spark、Flink等计算引擎。RM模型也逐步进化成…

发现数据之美:探索数据可视化的艺术与技术

摘要: 数据可视化是将抽象的数据转化为图形化表达的过程,它不仅可以让数据更加直观易懂,还能够揭示数据背后的模式、趋势和关联关系。本文将深入探讨数据可视化的重要性,并通过详细的实例演示如何运用常见的数据可视化工具和库,如Matplotlib、Seaborn和Plotly,为读者呈现…

SpringAI——Java生态接入LLM

最近&#xff0c;Spring官网发布了SpringAI&#xff0c;可点此查看https://spring.io/blog/2024/03/12/spring-ai-0-8-1-released&#xff0c;对于SpringAI的介绍&#xff0c;可看官方文档&#xff1a;https://spring.io/projects/spring-ai#overview。 本文将使用SpringAI配合…

字符函数以及字符串函数

1.strlen的使用和模拟实现 • 字符串以 \0 作为结束标志&#xff0c;strlen函数返回的是在字符串中 \0 前⾯出现的字符个数&#xff08;不包 含 \0 )。 • 参数指向的字符串必须要以 \0 结束。 • 注意函数的返回值为size_t&#xff0c;是⽆符号的&#xff08; 易错 &#xff…

VSCode 远程调试C++程序打开/dev/tty设备失败的问题记录

概述 因为需要协助同事调试rtklib中的rtkrcv程序&#xff0c;一直调试程序都是用了vscode&#xff0c;这次也不例外&#xff0c;但是在调试过程中&#xff0c;发现程序在打开当前终端(/dev/tty)的时候&#xff0c;总是打开失败&#xff0c;返回的错误原因是“No such device o…

Python之requests实现github模拟登录

文章目录 github 模拟登录前言模拟登录流程抓包操作查看登录表单的内容登录操作 模拟登录操作在 main函数的调用获得 auth_token调用/session接口登录处理检测登录是否成功 总结&#xff1a; github 模拟登录 前言 前面学习了requests模块的基础学习后&#xff0c;接下来做一个…

Pytorch学习 day14(模型的验证步骤)

如何利用已经训练好的模型&#xff0c;验证它的结果&#xff0c;步骤如下&#xff1a; 步骤一&#xff1a;加载测试输入并更改为合适尺寸 保存图片到指定文件夹下&#xff0c;注意是否为同级目录注意&#xff1a;返回上一级目录为“…/xxx"有时&#xff0c;我们自己的输…

前端React篇之React的生命周期有哪些?

目录 React的生命周期有哪些&#xff1f;挂载阶段&#xff08;Mounting&#xff09;更新阶段&#xff08;Updating&#xff09;卸载阶段&#xff08;Unmounting&#xff09;错误处理阶段&#xff08;Error Handling&#xff09; React常见的生命周期React主要生命周期 React的生…

每日一练:LeeCode-14、最长公共前缀【字符串+最值判定】

编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例 1&#xff1a; 输入&#xff1a;strs ["flower","flow","flight"] 输出&#xff1a;"fl"示例 2&#xff1a; …

27-Java MVC 模式

Java空对象模式 实现范例 MVC模式代表 Model-View-Controller&#xff08;模型-视图-控制器&#xff09; 模式MVC模式用于应用程序的分层开发 Model&#xff08;模型&#xff09; - 模型代表一个存取数据的对象或 JAVA POJO 它也可以带有逻辑&#xff0c;在数据变化时更新控制…

渔业安全生产综合管理指挥系统-航迹数据优化方案

文章目录 引言I 轨迹数据模型II 轨迹信息索引III 数据同步方案3.1 多服务器多表同步3.2 增量数据同步3.3 执行IV 配置ESV 团队建设5.1 前端(web GIS)5.2 后端(Java)see also引言 背景: 目前系统查询轨迹数据比较慢的原因是没有进行读写分离,轨迹数据的查询和写入都是SQL…

Linux查看mysql安装目录

在Linux系统中&#xff0c;MySQL的安装目录通常位于/usr/local/mysql或/opt/mysql目录下。这些目录是MySQL在Linux系统中默认的安装目录&#xff0c;用户可以在这些目录下找到MySQL的所有文件和配置信息。 要查看MySQL的安装目录&#xff0c;可以使用以下命令&#xff1a; wh…

踏上机器学习的征程:探索基础概念与学习模式

摘要: 机器学习是当今科技领域最具前沿和应用价值的技术之一,它正在改变我们对数据的理解和利用方式。本文将引导读者深入了解机器学习的基本概念,包括监督学习、无监督学习和半监督学习等,并通过生动的例子解释这些概念,帮助读者迈出学习机器学习的第一步。 导言: 随着…

Ubuntu 如何安装 Beyond Compare?

Ubuntu20.04安装Beyond Compare 4.3.7 一、官网下载方式一&#xff1a;方法二&#xff1a;使用 .deb 包安装 二、安装相关依赖和bcompare三、破解常见错误解决方法 ) 文件比较工具Beyond Compare是一套由Scooter Software推出的文件比较工具。主要用途是对比两个文件夹或者文件…

AST解web控制流平坦化

此代码可以解决大部分 while if else 控制流平坦化原理&#xff1a; 先将 if 语句转为 switch 语句&#xff0c;再将 switch 分支合并&#xff0c;最后删除已合并的分支&#xff08;具体看代码&#xff09; 实现效果图 首先安装依赖&#xff1a; npm install babel/parser npm…

指针基础 - golang版

文章目录 1、指针2、基础语法2.1 定义指针2.2 取地址操作符 &2.3 解引用操作符 * 3、实战用法3.1 指针作为函数参数3.2 指针和结构体3.3 指针和接收者 1、指针 变量是存储值的地方&#xff1b;指针的值是一个变量的地址&#xff1b;不是所有的值都有地址&#xff0c;但是所…

【K8s】如何使用Kubernetes Ingress: Contour

使用Kubernetes Ingress: Contour 目录 使用Kubernetes Ingress: Contour没有 Ingress 控制器的情况Ingress 控制器的优势部署 Contour看到 Contour 在运行中总结推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战在处理Kubernetes时会遇到…

Java后端八股-------并发编程

图中的 synchronized方法如果没有锁&#xff0c;那么可能会有超卖&#xff0c;数据错误等情况。 加锁之后会按顺序售卖。 synchronized的底层是monitor。 线程没有竞争关系的时候&#xff0c;引入了轻量级锁&#xff0c;当需要处理竞争关系的时候一定要用到重量级锁(线程的…

数据挖掘与大数据的结合

随着大数据技术的不断发展和普及&#xff0c;数据挖掘在大数据环境下的应用也变得更加广泛和深入。以下将探讨大数据技术对数据挖掘的影响&#xff0c;以及如何利用大数据技术处理海量数据并进行有效的数据挖掘&#xff0c;同时分析大数据环境下的数据挖掘挑战和解决方案。 1.…

【Flutter】IOS运行工程二次启动崩溃问题。

问题 IOS14设备&#xff0c;切后台划掉&#xff0c;二次启动崩溃&#xff0c;看crash日志 一直提示第三方plugin注册问题。 一个一个尝试注掉&#xff0c;发现依然不行&#xff0c;创建了一个原生app&#xff0c;运行复现发现没问题&#xff0c;大概率是flutter的问题。 结论…