Linux内核驱动学习(七)应用层直接操作GPIO

举报
小麦大叔 发表于 2021/12/30 01:17:59 2021/12/30
【摘要】 文章目录 简介原理图节点设置为输出设置为输入 映射关系debugfspwm demo 简介 前面通过libgpio的方式介绍了内核空间对GPIO进行操作的接口,其做了较好的封装,...

简介

前面通过libgpio的方式介绍了内核空间对GPIO进行操作的接口,其做了较好的封装,同时Linux系统的sysfs机制已经在系统路径下/sys/class/gpio注册了相应的节点,通过读写该节点下的文件就能轻松的完成GPIO输入输出配置以及引脚状态的获取。

原理图

我使用的Rockchippx30,引脚是GPIO3_D0,具体硬件肯定会不同,注意参考socdatasheet和硬件原理图,先定位正确需要操作的GPIO,千里之行始于足下。
Datasheet

节点

/sys/class/gpio路径下有exportunexport这两个文件;GPIO3_D0在这里是120,具体硬件和数字的对应关系后面会继续讲到;

echo 120 > /sys/class/gpio/export

  
 
  • 1

执行以上这条指令后,会在/sys/class/gpio/下生成gpio120节点,简单看一下该路径下都有哪些文件;

$ /sys/class/gpio/gpio120
$ active_low device direction edge power subsystem uevent value

  
 
  • 1
  • 2

设置为输出

$ cd /sys/class/gpio/gpio120
$ echo 0 > active_low
$ echo out > direction
$ echo 1 > value	#输出高
$ echo 0 > value	#输出低

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

另一种情况,设置active_low1,就会出现另一种情况;

$ cd /sys/class/gpio/gpio120
$ echo 1 > active_low
$ echo out > direction
$ echo 1 > value	#输出低
$ echo 0 > value	#输出高

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

由此看出,active_low的作用已经很明显了,后面没有特别指出的情况下,active_low的值默认为0;一表胜过千言万语,简单整理一个表格,如下所示;

active_low value 实际GPIO输出
0 1 high
0 0 low
1 1 low
1 0 high

设置为输入

$ cd /sys/class/gpio/gpio120
$ echo int > direction
$ cat value 	#读取GPIO的电平状态

  
 
  • 1
  • 2
  • 3

映射关系

Rockchip px30平台的GPIO总共分为GPIO0~GPIO3四组,每一组最多有32个GPIO,依次分为ABCD四个小组,每组最多8个,对于硬件上实际没有达到8个的情况下,计算偏移的时候,也按照8来计算。RK平台可以参考dt-bindings/pinctrl/rockchip.h。其他平台的话,如果有源代码可以参考以下厂商给出的具体定义,并结合SOC的原理图和硬件原理图,来计算。
具体计算如下表所示;依次类推;

引脚 计算
GPIO3_D0 3*32 + 3*8 + 0 = 120
GPIO3_D1 3*32 + 3*8 + 1 = 121
GPIO2_A1 2*32 + 0*8 + 1 = 65

在这里插入图片描述

debugfs

debugfs 是 Linux系统下为了方便驱动开发人员对驱动调试的文件系统。

$ cat /sys/kernel/debug/gpio

  
 
  • 1

可以通过debugfs查看gpio-120硬件上的实际输出和软件上是否相符合;
在这里插入图片描述

pwm demo

强迫症的我简单写了一个模拟pwmshell,虽然比较鸡肋,因为是占空比,频率都是不可调的,单纯是为了看一下控制的效果,前提是已经执行echo 120 > export这条指令并且成功生成相应的节点,代码简单如下;

 #!/bin/bash
 GPIO=120
 i=0
 value=0
 while [ 1 -eq 1 ]
 do
     i=$(($i + 1))
     if [ $(( $i % 2 )) -eq 0 ]
     then
         value=0
     else
         value=1
     fi
     echo "current i is $i"
     echo "current value is $value"
     echo $value > /sys/class/gpio/gpio$GPIO/value
     usleep 1000
 done

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

用示波器测量GPIO3_D0引脚的波形,和预期的一样;
在这里插入图片描述

文章来源: great.blog.csdn.net,作者:小麦大叔,版权归原作者所有,如需转载,请联系作者。

原文链接:great.blog.csdn.net/article/details/89814377

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。