zoukankan      html  css  js  c++  java
  • Linux内核驱动学习(七)应用层直接操作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
    

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

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

    设置为输出

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

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

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

    由此看出,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的电平状态
    

    映射关系

    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
    

    可以通过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
    

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

  • 相关阅读:
    管道通讯
    C++类型转换
    自定义数组容器MyArray框架
    vue 转场动画
    身份证信息 获取年龄性别生日
    element ui +vue 输入 身份证号获取 性别 年龄 籍贯
    获取地理位置
    post 下载二进制pdf文件
    post 文件下载二进制流
    遍历对象的几中方法
  • 原文地址:https://www.cnblogs.com/unclemac/p/12783393.html
Copyright © 2011-2022 走看看