需求描述

上层APK操作GPIO的diretction、value节点,实现点亮和熄灭灯,使用JNI方式,使用以下方式无效

extern "C"
JNIEXPORT jint JNICALL
Java_com_example_administrator_jni_Gpio_setOpenLed(JNIEnv *env, jclass instance) {int sd;system("echo 9 > /sys/class/gpio/export");system("echo out > /sys/class/gpio/gpio9/direction");system("echo 1 > /sys/class/gpio/gpio9/value");system("echo 9 > /sys/class/gpio/unexport");return 0;
}

实现方案

  • GPIOControl.c:JNI调用接口
#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>#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    3
#define DIRECTION_MAX 48/** Class:     com_example_jnigpio_GPIOControl* Method:    exportGpio* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_example_jnigpio_GPIOControl_exportGpio(JNIEnv *env, jobject instance, 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(0);}len = snprintf(buffer, BUFFER_MAX, "%d", gpio);if (write(fd, buffer, len) < 0) {LOGE("Fail to export gpio!\n");return 0;}close(fd);return 1;
}/** Class:     com_example_jnigpio_GPIOControl* Method:    setGpioDirection* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_example_jnigpio_GPIOControl_setGpioDirection(JNIEnv *env, jobject instance, 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);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_example_jnigpio_GPIOControl* Method:    readGpioStatus* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_example_jnigpio_GPIOControl_readGpioStatus(JNIEnv *env, jobject instance, 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_example_jnigpio_GPIOControl* Method:    writeGpioStatus* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_example_jnigpio_GPIOControl_writeGpioStatus(JNIEnv *env, jobject instance, 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);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_example_jnigpio_GPIOControl* Method:    unexportGpio* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_example_jnigpio_GPIOControl_unexportGpio(JNIEnv *env, jobject instance, 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");return 0;}len = snprintf(buffer, BUFFER_MAX, "%d", gpio);if (write(fd, buffer, len) < 0) {LOGE("Fail to unexport gpio!");return 0;}close(fd);return 1;
}
  • Android.mk:编译出libGPIOControl.so
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)
LOCAL_MODULE    := GPIOControl
LOCAL_SRC_FILES := GPIOControl.c
LOCAL_LDLIBS    := -lloginclude $(BUILD_SHARED_LIBRARY)
  • 添加节点读写权限
device/qcom/common/rootdir/etc/init.qcom.rc on boot
+    chmod 0777 /sys/class/gpio/export
+    chmod 0777 /sys/class/gpio/unexport
  • 添加实际节点的读写权限:ls -al sys/class/gpio/查看实际节点
device/qcom/common/rootdir/etc/ueventd.qcom.rc+/sys/devices/soc/1000000.pinctrl/gpio/gpio* direction 0777 system system
+/sys/devices/soc/1000000.pinctrl/gpio/gpio* value 0777 system system
  • 添加节点的SELinux权限
device/qcom/sepolicy/common/system_app.te+allow system_app sysfs:file rw_file_perms;
  • APK调用
  1. Android应用修改AndroidManifest.xml文件,在manifest节点中添加android:sharedUserId="android.uid.system,修改Android.mk文件,添加LOCAL_CERTIFICATE := platform设置系统签名。
  2. Android APK调用JNI加载so动态库:
    https://blog.csdn.net/weixin_44008788/article/details/114393087

相关拓展

  • 节点读写
//读节点
private static String readSys(String path) {String prop = "waiting";// 默认值try {BufferedReader reader = new BufferedReader(new FileReader(path));prop = reader.readLine();} catch (IOException e) {e.printStackTrace();}return prop;
}
//调用方法readSys("/sys/class/demo/version")
//写节点
private static String writeSys(String path) {try {BufferedWriter bufWriter = null;bufWriter = new BufferedWriter(new FileWriter(path));bufWriter.write("1");  // 写操作bufWriter.close();} catch (IOException e) {e.printStackTrace();}
}
//调用方法
writeSys("/sys/class/demo/version")
//以FileOutputStream写节点
void IOCtrl(int pin, int level) {String path;path = "/sys/class/gpio/gpio" + pin + "/value";try {FileOutputStream out = new FileOutputStream(path);out.write(level);out.flush();out.close();} catch (IOException e) {e.printStackTrace();return;}
}
  • 添加设备文件节点权限

/sys/class/leds/green/brightness //快捷方式
/sys/devices/soc.0/gpio-leds.66/leds/green/brightness //实际节点

操作LED灯的设备文件节点为APP层system app进程开放该节点访问权限(读或写),权限配置主要修改/device/qcom/sepolicy/common目录下的file.te、file_contexts和system_app.te三个文件

file.te修改如下

# GPIO accessed by system app
type sysfs_gpio, fs_type, sysfs_type;

file_contexts修改如下

/sys/devices/soc/1010000.pinctrl/gpio/gpio62/value           u:object_r:sysfs_gpio:s0
/sys/devices/soc/1010000.pinctrl/gpio/gpio63/value           u:object_r:sysfs_gpio:s0

system_app.te修改如下

allow system_app sysfs_gpio:file rw_file_perms;  

如果通过以上添加SELinux之后,仍没有权限读写sys或proc节点,需要到init.rc里面配置如下

chown system system 文件结点
chmod 777 文件结点

相关参考

https://blog.csdn.net/wds1181977/article/details/54967110
https://blog.csdn.net/liangtianmeng/article/details/84698568
https://blog.csdn.net/d38825/article/details/81240851
https://blog.csdn.net/K_Hello/article/details/90038078
android 查看gpio状态_Android应用层操作GPIO
Android app如何正确读写系统sys设备节点

Android系统APK操作GPIO读写及添加权限相关推荐

  1. android系统APK签名生成大全

    最近要做一个重复开关机的专项测试,发现需要系统权限才能实现 1.需要SYSTEM USER       1> android:sharedUserId="android.uid.sys ...

  2. android代码图片编辑,怎样修改android系统apk软件里面的代码和图片?

    你好,你的问题我算是看明白了,从你的问题可以设计三个方面,apk反编译.apk回编译以及apk签名,看来,我得从头说起了. 首先,我在这里提供下反编译Android所需的软件,当然是全套,刚刚收集整理 ...

  3. android 系统(155)---如何自己添加号码归属地数据库?

    如何自己添加号码归属地数据库? 如何自己添加号码归属地数据库? 并完成 InCallScreen 和 CallLog 界面显示自己添加的号码归属地信息. 以添加一个英文版的国内手机号码归属地举例说明. ...

  4. cm-14.1 Android系统定制(一):添加以太网上网功能

    声明 本文使用的是代码是Nexus5的cm-14.1(要下载cm-14.1代码可参考此文:[日更-2019.3.31]如何下载Nexus5的LineageOS14.1(cm-14.1)系统源码并编译. ...

  5. android 图片读写,Android系统中图片的读写

    读取手机图片: Bitmap bmp=BitmapFactroy.decodeFile("/sdcard/xxx.png"); imageview.setImageBitmap(b ...

  6. golang 文件操作 创建 读写 复制移动 权限 删除

    目录 介绍 基本操作 创建空文件 Truncate文件 得到文件信息 重命名和移动 删除文件 打开和关闭文件 检查文件是否存在 检查读写权限 改变权限.拥有者.时间戳 硬链接和软链接 读写 复制文件 ...

  7. linux+gpio+嵌入式,嵌入式Linux系统中对GPIO操作的方法总结

    在Linux系统里操作GPIO的方法有以下几个: 1. 写驱动的方式 需要自己编写linux驱动,在驱动里操控GPIO,应用通过驱动提供的节点来控制GPIO.优点是结构清晰,可扩展性强,比较灵活.缺点 ...

  8. 在Android系统中添加组合键快捷启动功能

    启动系统特定功能的组合键的判断应该在系统分发按键消息前处理, 这样从系统运行 的角度来说成本最低. 添加组合键处理需要先搞清楚按键消息在framework中采集 和分发子系统的工作流程, 虽然有and ...

  9. android系统下替换so库等操作

    在工作过程中由于android 系统过大编译起来太过费时,所以需要小编来进行验证修改. 下面的是小编TV android 系统的操作. 小编替换android模块步骤 1,编译出.so文件 andro ...

最新文章

  1. 最新Ceph L版与openstack Pike对接
  2. 错误 SQL TOP子句中的行数必须是整数
  3. 【python】xsspider零碎知识点
  4. 2048小游戏主要算法实现
  5. 猎鹰spacex_我如何重新创建SpaceX仪表板UI
  6. 可能是最好的单例模式
  7. 32位与64位、单精度(single-precision)与双精度(double-precision)
  8. TCPClient、TCPListener的用法
  9. Autojs实现图片转字符串(简易ocr预备步骤)
  10. Atitit q2016 qa doc list on home ntpc.docx
  11. 香槟分校计算机研究生专业,伊利诺伊大学香槟分校计算机科学专业各大方向介绍...
  12. WPF使用Blend
  13. 蓝桥杯之《人民币金额大写》
  14. html购物页面产品展示,html5 3D交互式房间购物商品展示特效
  15. css 实现随风摆动
  16. 【BZOJ1211】【HNOI2004】树的计数(prufer序,组合数)
  17. 一个简单的C语言代码段,逻辑题
  18. Python 绘画excel分组柱状图(懒人学习)
  19. 全选与反选 (转)
  20. javaweb技术及应用QST

热门文章

  1. 18B20,search rom命令,遍历搜索
  2. 分享几款常用远程连接工具
  3. 客户体验的重要性和企业发展的紧密联系
  4. 90套Axure原型模板源文件Rp高保真ui产品经理app web 网站案例模板(Axure9制作)
  5. js(es7-es10)特性
  6. 自动驾驶「时过境迁」,这家头部出行服务平台再出发
  7. UML类图几种关系的总结
  8. org.apache.jasper.JasperException: 未能加载或实例化TagLibraryValidator类
  9. mysql 单表2000多万条数据,模糊查询如何秒回
  10. 关于python实现CRC32Mpeg2的应用和总结