OrangePi通过sysfs控制GPIO接口

OrangePi通过sysfs控制GPIO接口

什么是sysfs

    Sysfs 是 Linux 2.6 所提供的一种虚拟文件系统。这个文件系统不仅可以把设备
    (devices)和驱动程序(drivers) 的信息从内核输出到 用户空间,也可以用来对设备和驱
    动程序做设置。
    sysfs 的目的是把一些原本在 procfs 中的,关于设备的部份,独立出来,以‘设备层次结构
    架构’(device tree)的形式呈现。这个文件系统由 Patrick Mochel 所写,稍后 
    Maneesh Soni 撰写 "sysfs backing store path",以降低在大型系统中对存储器的需求量.
### 使用的硬件
这里使用的是Orange Pi One,有40Pin的扩展接口,类似树莓派,使用方法也类似。
    系统是使用的安卓4.4
    导出Gpio接口:
    echo XX  > /sys/class/gpio/export(其中XX为你要导出的GPIO引脚编号,后面会说到引脚编号计算方法)
    如果成功的话,这一步会在/sys/class/gpio目录下生成 /sys/class/gpio/gpioXX
    设定IO方向:
    echo out > /sys/class/gpio/gpioXX/direction(输出)
    echo in > /sys/class/gpio/gpioXX/direction(输入)

    设定输出值:
    echo 1 > /sys/class/gpio/gpioXX/value
    echo 0 >  /sys/class/gpio/gpioXX/value

    或者:
    echo high > /sys/class/gpio/gpioXX/direction(输出,同时置高)
    echo low >  /sys/class/gpio/gpioXX/direction(输出,同时置低)

    取消导出:
    echo XX  >  /sys/class/gpio/unexport
### 引脚映射计算
Orange Pi One 外设的GPIO如下:

![20151019002607_51900.jpg](http://upload-images.jianshu.io/upload_images/3088365-143e6e024df32a23.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    计算公式:

    (P后面的字母在字母表中的位置 - 1) * 32 + 后面的数字
    例如:
    PA0计算得到:0    ------>(1-1)*32+0
    PA1计算得到:1       ------->(1-1)*32+1
    PA15计算得到:15   ------->(1-1)*32+15
    PD14计算得到:110  ------->(4-1)*32+14
    PC1计算得到:65   ------->(3-1)*32+1
### 在Java层控制
import com.donute.robot.utils.ShellUtils;

  /**
   * Created by zhouyufei on 2017/1/4.
   */

  public class Gpio {
      public static final int HIGH=1;
      public static final int LOW=0;
      public static final String IN="in";
      public static final String OUT="out";
      public static final String DISABLE="disable";
      private String path;
      private String direction=DISABLE;
      private int number;

      public Gpio(int number) {
          this.number = number;
          ShellUtils.execCommand("echo "+number+" > /sys/class/gpio/export",true);
          path="/sys/class/gpio/gpio"+number;
      }
      public Gpio openAsOut(){
          direction=OUT;
          ShellUtils.execCommand("echo "+direction+" > "+path+"/direction",true);
          return this;
      }
      public Gpio openAsIn(){
          direction=IN;
          ShellUtils.execCommand("echo "+direction+" > "+path+"/direction",true);
          return this;
      }
      public Gpio close(){
          direction=DISABLE;
          ShellUtils.execCommand("echo "+number+" > /sys/class/gpio/unexport",true);
          return this;
      }
      public void write(int value){
          ShellUtils.execCommand("echo "+value+" > "+path+"/value",true);
      }
      public int read(){
          ShellUtils.CommandResult result=ShellUtils.execCommand("cat "+path+"/value",true,true);
          if (result.result==0){
              try{
                  return Integer.parseInt(result.successMsg);
              }catch (Exception e){
                  return -1;
              }
          }else {
              return -1;
          }
      }

      public String getDirection() {
          return direction;
      }

      public int getNumber() {
          return number;
      }

  }
### ShellUtil代码
package com.donute.robot.utils;

    /**
     * Created by zhouyufei on 16/7/31.
     */
    import java.io.BufferedReader;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.List;

    /**
     * ShellUtils
     * <ul>
     * <strong>Check root</strong>
     * <li>{@link ShellUtils#checkRootPermission()}</li>
     * </ul>
     * <ul>
     * <strong>Execte command</strong>
     * <li>{@link ShellUtils#execCommand(String, boolean)}</li>
     * <li>{@link ShellUtils#execCommand(String, boolean, boolean)}</li>
     * <li>{@link ShellUtils#execCommand(List, boolean)}</li>
     * <li>{@link ShellUtils#execCommand(List, boolean, boolean)}</li>
     * <li>{@link ShellUtils#execCommand(String[], boolean)}</li>
     * <li>{@link ShellUtils#execCommand(String[], boolean, boolean)}</li>
     * </ul>
     *
     * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-16
     */
    public class ShellUtils {

        public static final String COMMAND_SU       = "su";
        public static final String COMMAND_SH       = "sh";
        public static final String COMMAND_EXIT     = "exit\n";
        public static final String COMMAND_LINE_END = "\n";

        private ShellUtils() {
            throw new AssertionError();
        }

        /**
         * check whether has root permission
         *
         * @return
         */
        public static boolean checkRootPermission() {
            return execCommand("echo root", true, false).result == 0;
        }

        /**
         * execute shell command, default return result msg
         *
         * @param command command
         * @param isRoot whether need to run with root
         * @return
         * @see ShellUtils#execCommand(String[], boolean, boolean)
         */
        public static CommandResult execCommand(String command, boolean isRoot) {
            return execCommand(new String[] {command}, isRoot, true);
        }

        /**
         * execute shell commands, default return result msg
         *
         * @param commands command list
         * @param isRoot whether need to run with root
         * @return
         * @see ShellUtils#execCommand(String[], boolean, boolean)
         */
        public static CommandResult execCommand(List<String> commands, boolean isRoot) {
            return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, true);
        }

        /**
         * execute shell commands, default return result msg
         *
         * @param commands command array
         * @param isRoot whether need to run with root
         * @return
         * @see ShellUtils#execCommand(String[], boolean, boolean)
         */
        public static CommandResult execCommand(String[] commands, boolean isRoot) {
            return execCommand(commands, isRoot, true);
        }

        /**
         * execute shell command
         *
         * @param command command
         * @param isRoot whether need to run with root
         * @param isNeedResultMsg whether need result msg
         * @return
         * @see ShellUtils#execCommand(String[], boolean, boolean)
         */
        public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
            return execCommand(new String[] {command}, isRoot, isNeedResultMsg);
        }

        /**
         * execute shell commands
         *
         * @param commands command list
         * @param isRoot whether need to run with root
         * @param isNeedResultMsg whether need result msg
         * @return
         * @see ShellUtils#execCommand(String[], boolean, boolean)
         */
        public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
            return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, isNeedResultMsg);
        }

        /**
         * execute shell commands
         *
         * @param commands command array
         * @param isRoot whether need to run with root
         * @param isNeedResultMsg whether need result msg
         * @return <ul>
         *         <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and
         *         {@link CommandResult#errorMsg} is null.</li>
         *         <li>if {@link CommandResult#result} is -1, there maybe some excepiton.</li>
         *         </ul>
         */
        public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {
            int result = -1;
            if (commands == null || commands.length == 0) {
                return new CommandResult(result, null, null);
            }

            Process process = null;
            BufferedReader successResult = null;
            BufferedReader errorResult = null;
            StringBuilder successMsg = null;
            StringBuilder errorMsg = null;

            DataOutputStream os = null;
            try {
                process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
                os = new DataOutputStream(process.getOutputStream());
                for (String command : commands) {
                    if (command == null) {
                        continue;
                    }

                    // donnot use os.writeBytes(commmand), avoid chinese charset error
                    os.write(command.getBytes());
                    os.writeBytes(COMMAND_LINE_END);
                    os.flush();
                }
                os.writeBytes(COMMAND_EXIT);
                os.flush();

                result = process.waitFor();
                // get command result
                if (isNeedResultMsg) {
                    successMsg = new StringBuilder();
                    errorMsg = new StringBuilder();
                    successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
                    errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                    String s;
                    while ((s = successResult.readLine()) != null) {
                        successMsg.append(s);
                    }
                    while ((s = errorResult.readLine()) != null) {
                        errorMsg.append(s);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (os != null) {
                        os.close();
                    }
                    if (successResult != null) {
                        successResult.close();
                    }
                    if (errorResult != null) {
                        errorResult.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

                if (process != null) {
                    process.destroy();
                }
            }
            return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
                    : errorMsg.toString());
        }

        /**
         * result of command
         * <ul>
         * <li>{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in
         * linux shell</li>
         * <li>{@link CommandResult#successMsg} means success message of command result</li>
         * <li>{@link CommandResult#errorMsg} means error message of command result</li>
         * </ul>
         *
         * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-16
         */
        public static class CommandResult {

            /** result of command **/
            public int    result;
            /** success message of command result **/
            public String successMsg;
            /** error message of command result **/
            public String errorMsg;

            public CommandResult(int result) {
                this.result = result;
            }

            public CommandResult(int result, String successMsg, String errorMsg) {
                this.result = result;
                this.successMsg = successMsg;
                this.errorMsg = errorMsg;
            }
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 整体思路ESP8266作为TCP服务器,,手机作为TCP客户端,自己使用Lua直接做到了芯片里面,省了单片机,,节...
    杨奉武阅读 5,699评论 0 5
  • 在这个标题之前,已经换了三个标题,起了四个开头,敲了十个句子,没完成一个段落。本该能组成文章的字词句在眼前、在脑子...
    嘿头羊阅读 420评论 1 2
  • 这个世界上有很多的人, 有的喜欢和自己一样兴趣的人, 有的喜欢和自己一样打扮的人 而有的人, 喜欢和自己一样性别的人。
    叆蓝炘阅读 255评论 0 0