Java 通过GPIO控制LED灯的亮灭(Firefly-RK3399)(二)

Java 通过GPIO控制LED灯的亮灭(Firefly-RK3399)(二)

Note: 为Android 开发,开发工具AndroidStudio

上篇简要介绍了GPIO在Linux 下的操作,这篇主要描述在Java下的应用

1.JNI 方式

2.Java 运行Linux命令

JNI

JNI要通过调用C文件,来读写操作GPIO,而且

对于相关的目录文件还需要权限才能执行,搞得一脸懵

jni 操作gpio需要权限 (AS中Terminal窗口):

chmod -R 777 /sys/class/gpio/gpio1157/

将当前目录下所有文件都给予777权限,777就是高权限(读、写、执行)

如果还是读写失败,需要每一步进行授予权限,详情参考:

android通过JNI控制GPIO
Android NDK开发中jni配置及调用GPIO

c文件如下(仅供参考):


//
// Created by K_EJ on 2019/3/20.
//
#include <jni.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <android/log.h>

#include <errno.h>
#include "com_ejior_platform_led_GPIOControl.h"

#define TAG "jni_gpio"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__)

#define IN              0
#define OUT             1
#define LOW             0
#define HIGH            1

#define BUFFER_MAX    5   //3    1157 为5
#define DIRECTION_MAX 66


#include "com_ejior_platform_led_GPIOControl.h"
JNIEXPORT jint JNICALL Java_com_ejior_platform_led_GPIOControl_exportGpio
  (JNIEnv *env, jobject jclass, jint gpio){
    char buffer[BUFFER_MAX];
    int len;
    int fd;

    fd = open("/sys/class/gpio/export", O_WRONLY);
    if (fd < 0) {
        LOGE("Failed to open export for writing!\n");
        return fd;
    }
    len = snprintf(buffer, BUFFER_MAX, "%d", gpio);
    return len;
    if (write(fd, buffer, len) < 0) {
        LOGE("Fail to export gpio!\n");
        return (0);
    }

    close(fd);
    return 1;

  };

/*
 * Class:     com_ejior_platform_led_GPIOControl
 * Method:    setGpioDirection
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_ejior_platform_led_GPIOControl_setGpioDirection
  (JNIEnv *env,jobject jclass, jint gpio, jint direction)
    {
    static const char dir_str[]  = "in\0out";
    char path[DIRECTION_MAX];
    int fd;
    snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", gpio);
    //path
    fd = open(path, O_WRONLY);
    if (fd < 0) {
        LOGE("failed to open gpio direction for writing!\n");
        return 0;
    }

    if (write(fd, &dir_str[direction == IN ? 0 : 3], direction == IN ? 2 : 3) < 0) {
        LOGE("failed to set direction!\n");
        return 0;
    }
    close(fd);
    return 1;
    };

/*
 * Class:     com_ejior_platform_led_GPIOControl
 * Method:    readGpioDirection
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_ejior_platform_led_GPIOControl_readGpioStatus
  (JNIEnv *env,jobject jclass , jint gpio)
  {
  char path[DIRECTION_MAX];
      char value_str[3];
      int fd;
      snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", gpio);
     fd = open(path, O_RDONLY);
if (fd < 0) {
        LOGE("failed to open gpio value for reading!\n");
        return -1;
    }

    if (read(fd, value_str, 3) < 0) {
        LOGE("failed to read value!\n");
        return -1;
    }

    close(fd);
    return (atoi(value_str));
  };

/*
 * Class:     com_ejior_platform_led_GPIOControl
 * Method:    writeGpioStatus
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_ejior_platform_led_GPIOControl_writeGpioStatus
  (JNIEnv *env, jobject jclass, jint gpio, jint value)
  {
    static const char values_str[] = "01";

    char path[DIRECTION_MAX];
     int fd;
     snprintf(path,DIRECTION_MAX,"/sys/class/gpio/gpio%d/value",gpio);
     fd = open(path,O_WRONLY);//path
     if(fd<0){
     LOGE("failed to open gpio value for writing!\n");
     return 0;
     }

     if(write(fd,&values_str[value == LOW? 0:1],1) < 0){
     LOGE("failed to write value!\n");
     return 0;
     }
       close(fd);
       return 1;

  };

/*
 * Class:     com_ejior_platform_led_GPIOControl
 * Method:    unexportGpio
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_ejior_platform_led_GPIOControl_unexportGpio
  (JNIEnv *env, jobject jclass, jint gpio)
 {
      char buffer[BUFFER_MAX];
      int len;
      int fd;

      fd = open("/sys/class/gpio/unexport",O_WRONLY);
      if(fd <0){
      LOGE("Failed to open unexport for writing!\n");
      }
    len = snprintf(buffer, BUFFER_MAX, "%d", gpio);
    if (write(fd, buffer, len) < 0) {
        LOGE("Fail to unexport gpio!");
        return 0;
    }
    close(fd);
        return 1;

  };

Note:需要配置NDK环境 >++<

Java 方式

也就是用java通过输出流写入Linux 命令

**Note:**设备需要root,如果不root,2种方式,1.系统签名(需要编译源码) 2. 放在系统目录下/system(Note,引用的第三方so库,需要放入/system/lib下,在rk3399开发板上遇到系统打不开,定格在Recovery页面,需要重新烧录固定。。。)

root 设备

详情:

【android工具篇】Firefly-RK系列

里面介绍的方法有的并不能达到获取权限的目的,工具类反而用的到

需要用到工具类ShellUtils,来写入Linux命令,如下:

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();
        }
        /**
         * 查看是否有了root权限
         *
         * @return
         */
        public static boolean checkRootPermission() {
            return execCommand("echo root", true, false).result == 0;
        }


        /**
         * 执行shell命令,默认返回结果
         *
         * @param command command
         * @return
         * @see ShellUtils#execCommand(String[], boolean, boolean)
         */
        public static CommandResult execCommand(String command, boolean isRoot) {
            return execCommand(new String[]{command}, isRoot, true);
        }


        /**
         * 执行shell命令,默认返回结果
         *
         * @param commands command list
         * @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);
        }


        /**
         * 执行shell命令,默认返回结果
         *
         * @param commands command array
         * @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 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
         * @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
         */
        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.flu
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值