Skip to content

Instantly share code, notes, and snippets.

@JeonghunLee
Last active February 1, 2021 08:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JeonghunLee/3aa9ef99f22f567c1afedc58fd8b8e1b to your computer and use it in GitHub Desktop.
Save JeonghunLee/3aa9ef99f22f567c1afedc58fd8b8e1b to your computer and use it in GitHub Desktop.
Android Studio Native (sys file)
// BoardConfig에 Selinux를 Permissive (허용모드) 로 변경
// Selinux 제어
$ vi device/vendor/hardware/BoardConfig.mk
BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
// init.hardware.rc 부분수정 (권한설정부분 변경)
// chmod 변경 및 /sys filesystem 설정
$ vi ./device/fsl/imx8q/mek_8q/init.imx8qxp.rc
on property:sys.boot_completed=1
#jhlee for PWM1/2
#chmod 0755 /sys/class/pwm
chmod 0777 /sys/class/pwm/pwmchip0
chmod 0222 /sys/class/pwm/pwmchip0/export
chmod 0222 /sys/class/pwm/pwmchip0/unexport
chmod 0777 /sys/class/pwm/pwmchip1
chmod 0222 /sys/class/pwm/pwmchip1/export
chmod 0222 /sys/class/pwm/pwmchip1/unexport
# PWM1 50Hz 20ms / 10ms (half)
write /sys/class/pwm/pwmchip0/export 0
write /sys/class/pwm/pwmchip0/pwm0/enable 1
write /sys/class/pwm/pwmchip0/pwm0/period 20000000
write /sys/class/pwm/pwmchip0/pwm0/duty_cycle 10000000
# PWM2 50Hz 20ms / 10ms (half)
write /sys/class/pwm/pwmchip1/export 0
write /sys/class/pwm/pwmchip1/pwm0/enable 1
write /sys/class/pwm/pwmchip1/pwm0/period 20000000
write /sys/class/pwm/pwmchip1/pwm0/duty_cycle 10000000
chmod 0666 /sys/class/pwm/pwmchip0/pwm0/period
chmod 0666 /sys/class/pwm/pwmchip0/pwm0/duty_cycle
chmod 0666 /sys/class/pwm/pwmchip0/pwm0/enable
chmod 0666 /sys/class/pwm/pwmchip1/pwm0/period
chmod 0666 /sys/class/pwm/pwmchip1/pwm0/duty_cycle
chmod 0666 /sys/class/pwm/pwmchip1/pwm0/enable
# GPIO UART1_TX 21
write /sys/class/gpio/export 21
write /sys/class/gpio/gpio21/direction "out"
write /sys/class/gpio/gpio21/value 1
# GPIO UART1_CTS_B 24
write /sys/class/gpio/export 24
write /sys/class/gpio/gpio24/direction "out"
write /sys/class/gpio/gpio24/value 1
chmod 0666 /sys/class/gpio/export
chmod 0666 /sys/class/gpio/unexport
chmod 0666 /sys/class/gpio/gpio21/direction
chmod 0666 /sys/class/gpio/gpio21/value
chmod 0666 /sys/class/gpio/gpio24/direction
chmod 0666 /sys/class/gpio/gpio24/value
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.10.2)
# Declares and names the project.
project("jhlee")
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
GpioCtr
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
GpioCtr.c )
add_library( # Sets the name of the library.
PWMCtr
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
PWMCtr.c )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
GpioCtr
# Links the target library to the log library
# included in the NDK.
${log-lib} )
target_link_libraries( # Specifies the target library.
PWMCtr
# Links the target library to the log library
# included in the NDK.
${log-lib} )
#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 "GpioCtr.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
#define STRING_MAX 50
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_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 %d for writing!\n",gpio);
return -1;
}
len = snprintf(buffer, BUFFER_MAX, "%d", gpio);
LOGE("gpio : %d , len : %d, buffer : %s , sizeof(buffer) : %d", gpio, len, buffer, sizeof(buffer));
if (write(fd, buffer, len) < 0) {
LOGE("failed to export gpio %d\n",gpio);
LOGE("have to unexport this gpio if you already exported gpio %d\n",gpio);
return -2;
}
LOGE("/sys/class/gpio/export %d ok ", gpio);
close(fd);
return 0;
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_setGpioDirection(JNIEnv *env, jobject instance, jint gpio, jint direction)
{
static const char dir_str[] = "in\0out";
char path[STRING_MAX];
int len;
int fd;
len = snprintf(path, STRING_MAX, "/sys/class/gpio/gpio%d/direction", gpio);
LOGE("path : %s(%d)", path,len);
fd = open(path, O_WRONLY);
if (fd < 0) {
LOGE("failed to open gpio direction for writing!\n");
return -1;
}
if (write(fd, &dir_str[direction == IN ? 0 : 3], direction == IN ? 2 : 3) < 0) {
LOGE("failed to set direction!\n");
if(fd > 0) close(fd);
return -2;
}
LOGE("/sys/class/gpio/gpio%d/direction ok ", gpio);
close(fd);
return 0;
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_readGpioValue(JNIEnv *env, jobject instance, jint gpio)
{
char path[STRING_MAX];
char value_str[3];
int fd;
snprintf(path, STRING_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");
if(fd > 0) close(fd);
return -2;
}
LOGE("read /sys/class/gpio/gpio%d/value:%s ok ", gpio, value_str);
close(fd);
return (atoi(value_str));
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_writeGpioValue(JNIEnv *env, jobject instance, jint gpio, jint value)
{
static const char values_str[] = "01";
char path[STRING_MAX];
int fd;
snprintf(path, STRING_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 -1;
}
if (write(fd, &values_str[value == LOW ? 0 : 1], 1) < 0) {
LOGE("failed to write value!\n");
if(fd > 0) close(fd);
return -2;
}
LOGE("write /sys/class/gpio/gpio%d/value:%d ok ", gpio,value);
close(fd);
return 0;
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_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 -1;
}
len = snprintf(buffer, BUFFER_MAX, "%d", gpio);
if (write(fd, buffer, len) < 0) {
LOGE("fail to unexport gpio!");
if(fd > 0) close(fd);
return -2;
}
LOGE("/sys/class/gpio/unexport %d ok ", gpio);
close(fd);
return 0;
}
#include <jni.h>
#ifndef _Included_com_example_jhlee_GpioCtr
#define _Included_com_example_jhlee_GpioCtr
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_exportGpio
(JNIEnv *, jclass, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_setGpioDirection
(JNIEnv *, jclass, jint, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_readGpioValue
(JNIEnv *, jclass, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_writeGpioValue
(JNIEnv *, jclass, jint, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_GpioCtr_unexportGpio
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
package com.example.jhlee;
public class GpioCtr {
static {
System.loadLibrary("GpioCtr");
}
public final static native int exportGpio(int gpio);
public final static native int setGpioDirection(int gpio, int direction);
public final static native int readGpioValue(int gpio);
public final static native int writeGpioValue(int gpio, int value);
public final static native int unexportGpio(int gpio);
}
package com.example.jhlee;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private int ret;
public static final int UART1_TX= 21;
public static final int UART1_CTS_B= 24;
public static final int PWM0= 0;
public static final int PWM1= 1;
public static final int GPIO_IN= 0;
public static final int GPIO_OUT= 1;
public static final int GPIO_LOW= 0;
public static final int GPIO_HIGH= 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText("TEST PWM GPIO JHLEE");
}
@Override
protected void onResume() {
super.onResume();
// PWM 0,1 50Hz
PWMCtr.setPeriod(0,20000000);
PWMCtr.setPeriod(1,20000000);
Log.d("TEST-PWM-GPIO","PWM Set Period OK \n");
//
//GpioCtr.exportGpio(UART1_TX);
//GpioCtr.exportGpio(UART1_CTS_B);
//GpioCtr.setGpioDirection(UART1_TX,GPIO_OUT);
//GpioCtr.setGpioDirection(UART1_CTS_B,GPIO_OUT);
Log.d("TEST-PWM-GPIO","GPIO Set OK \n");
//PWM Power off
GpioCtr.writeGpioValue(UART1_TX,GPIO_LOW);
GpioCtr.writeGpioValue(UART1_CTS_B,GPIO_LOW);
Log.d("TEST-PWM-GPIO","GPIO WRITE LOW OK\n");
// 0 degree
PWMCtr.setDuty(0,5500000);
PWMCtr.setDuty(1,5500000);
Log.d("TEST-PWM-GPIO","PWM 0 degree OK\n");
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
//PWM Power on
GpioCtr.writeGpioValue(UART1_TX,GPIO_HIGH);
GpioCtr.writeGpioValue(UART1_CTS_B,GPIO_HIGH);
Log.d("TEST-PWM-GPIO","GPIO WRITE HIGH OK After 1s\n");
}
}, 1000);
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
//180 degree
PWMCtr.setDuty(0,2400000);
ret = PWMCtr.getDuty(0);
PWMCtr.setDuty(1,2400000);
ret = PWMCtr.getDuty(1);
Log.d("TEST-PWM-GPIO","PWM 180 degree OK After 3s\n");
}
}, 3000);
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
// 0 degree
PWMCtr.setDuty(0,5500000);
ret = PWMCtr.getDuty(0);
PWMCtr.setDuty(1,5500000);
ret = PWMCtr.getDuty(1);
Log.d("TEST-PWM-GPIO","PWM 0 degree OK After 5s \n");
}
}, 5000);
new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
// 30 degree
PWMCtr.setDuty(0,860000);
ret = PWMCtr.getDuty(0);
PWMCtr.setDuty(1,860000);
ret = PWMCtr.getDuty(1);
Log.d("TEST-PWM-GPIO","PWM 30 degree OK After 7s\n");
}
}, 7000);
Log.d("TEST-PWM-GPIO","TEST END OK\n");
}
}
#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 "PWMCtr.h"
#define TAG "JNI_PWM"
#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 STRING_MAX 100
#define BUFFER_MAX 3
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_export(JNIEnv *env, jobject instance, jint pwm)
{
char sys_str[STRING_MAX]={0};
char buffer[BUFFER_MAX]={0};
int len;
int fd;
int val=0;
len = snprintf(sys_str, STRING_MAX, "/sys/class/pwm/pwmchip%d/export", pwm);
LOGE("path : %s(%d) ", sys_str, len);
fd = open(sys_str, O_WRONLY);
if (fd < 0) {
LOGE("Failed to open %s for writing\n",sys_str);
return -1;
}
LOGE("open: %s sizeof(buffer) : %d fd=%d",sys_str,sizeof(sys_str) ,fd);
len = snprintf(buffer, BUFFER_MAX, "%d", val);
LOGE("value : %s(%d)", buffer, len);
if (write(fd, buffer, len) < 0) {
LOGE("Fail to export pwm %d! \n",pwm );
if(fd > 0) close(fd);
return -2;
}
close(fd);
return 0;
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_setEnable(JNIEnv *env, jobject instance, jint pwm, jint value)
{
char sys_str[STRING_MAX]={0};
char buffer[BUFFER_MAX]={0};
int fd;
int len;
len = snprintf(sys_str, STRING_MAX, "/sys/class/pwm/pwmchip%d/pwm0/enable", pwm);
LOGE("path : %s(%d) ", sys_str, len);
fd = open(sys_str, O_WRONLY);
if (fd < 0) {
LOGE("Failed to open %s for writing\n",sys_str);
return -1;
}
len = snprintf(buffer, BUFFER_MAX, "%d", value);
LOGE("value : %s(%d)", buffer, len);
if (write(fd, buffer, len) < 0) {
LOGE("Fail to setEnable pwm %d! \n",pwm );
if(fd > 0) close(fd);
return -2;
}
close(fd);
return 0;
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_setPeriod(JNIEnv *env, jobject instance, jint pwm, jint period)
{
char sys_str[STRING_MAX];
char setvalue_str[STRING_MAX]={0};
int fd;
int len;
len = snprintf(sys_str, STRING_MAX, "/sys/class/pwm/pwmchip%d/pwm0/period", pwm);
LOGE("path : %s(%d) ", sys_str, len);
fd = open(sys_str, O_WRONLY);
if (fd < 0) {
LOGE("Failed to open %s for reading and writing \n",sys_str);
return -1;
}
len = snprintf(setvalue_str, STRING_MAX, "%d", period);
LOGE("Set period : %s(%d)", setvalue_str, len);
if (write(fd, setvalue_str, len) < 0) {
LOGE("Failed to setPeriod pwm %d! \n",pwm );
if(fd > 0) close(fd);
return -2;
}
close(fd);
return 0;
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_setDuty(JNIEnv *env, jobject instance, jint pwm, jint duty)
{
char sys_str[STRING_MAX];
char setvalue_str[STRING_MAX]={0};
int fd;
int len;
len = snprintf(sys_str, STRING_MAX, "/sys/class/pwm/pwmchip%d/pwm0/duty_cycle", pwm);
LOGE("path : %s(%d) ", sys_str, len);
fd = open(sys_str, O_WRONLY);
if (fd < 0) {
LOGE("Failed to open %s for reading and writing \n",sys_str);
return -1;
}
len = snprintf(setvalue_str, STRING_MAX, "%d", duty);
LOGE("Set duty : %s(%d)", setvalue_str, len);
if (write(fd, setvalue_str, len) < 0) {
LOGE("Failed to setduty pwm %d! \n",pwm );
if(fd > 0) close(fd);
return -2;
}
close(fd);
return 0;
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_getPeriod(JNIEnv *env, jobject instance, jint pwm)
{
char sys_str[STRING_MAX];
char getvalue_str[STRING_MAX]={0};
int fd;
int len;
len = snprintf(sys_str, STRING_MAX, "/sys/class/pwm/pwmchip%d/pwm0/period", pwm);
LOGE("path : %s(%d) ", sys_str, len);
fd = open(sys_str, O_RDONLY);
if (fd < 0) {
LOGE("Failed to open %s for reading and writing \n",sys_str);
return -1;
}
if ((len = read(fd, getvalue_str, 10)) < 0) {
LOGE("Failed to getPeriod\n");
if(fd > 0) close(fd);
return -2;
}
LOGE("Get period : %d", getvalue_str);
close(fd);
return (atoi(getvalue_str));
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_getDuty(JNIEnv *env, jobject instance, jint pwm)
{
char sys_str[STRING_MAX];
char getvalue_str[STRING_MAX]={0};
int fd;
int len;
len = snprintf(sys_str, STRING_MAX, "/sys/class/pwm/pwmchip%d/pwm0/duty_cycle", pwm);
LOGE("path : %s(%d) ", sys_str, len);
fd = open(sys_str, O_RDONLY);
if (fd < 0) {
LOGE("Failed to open %s for reading and writing \n",sys_str);
return -1;
}
if ((len = read(fd, getvalue_str, STRING_MAX)) < 0) {
LOGE("Failed to getduty\n");
if(fd > 0) close(fd);
return -2;
}
LOGE("Get duty : %s",getvalue_str);
close(fd);
return (atoi(getvalue_str));
}
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_unexport(JNIEnv *env, jobject instance, jint pwm) {
char sys_str[STRING_MAX];
char buffer[BUFFER_MAX]={0};
int fd;
int len;
int val=0;
len = snprintf(sys_str, STRING_MAX, "/sys/class/pwm/pwmchip%d/unexport", pwm);
LOGE("path : %s (%d) ", sys_str, len);
fd = open(sys_str, O_WRONLY);
if (fd < 0) {
LOGE("Failed to open %s for writing\n",sys_str);
return -1;
}
LOGE("open: %s sizeof(buffer) : %d fd=%d",sys_str,sizeof(sys_str) ,fd);
len = snprintf(buffer, BUFFER_MAX, "%d", val);
LOGE("value : %s (%d)", buffer, len);
if (write(fd, buffer, len) < 0) {
LOGE("Fail to export pwm %d! \n",pwm );
return -2;
}
close(fd);
return 0;
}
#include <jni.h>
#ifndef _Included_com_example_jhlee_PWMCtr
#define _Included_com_example_jhlee_PWMCtr
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_export
(JNIEnv *, jclass, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_setEnable
(JNIEnv *, jclass, jint, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_setPeriod
(JNIEnv *, jclass, jint, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_setDuty
(JNIEnv *, jclass, jint, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_getPeriod
(JNIEnv *, jclass, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_getDuty
(JNIEnv *, jclass, jint);
JNIEXPORT jint JNICALL Java_com_example_jhlee_PWMCtr_unexport
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
package com.example.jhlee;
public class PWMCtr {
static {
System.loadLibrary("PWMCtr");
}
public final static native int export(int pwm);
public final static native int setEnable(int pwm, int value);
public final static native int setPeriod(int pwm, int period);
public final static native int setDuty(int pwm, int duty);
public final static native int getPeriod(int pwm);
public final static native int getDuty(int pwm);
public final static native int unexport(int pwm);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment