A gpio control demo using modular libgpiod way which is packaged a JNI library, users can calling JNI library using JAVA/Kotlin apis, this demo adapt Kotlin and Jetpack Compose to write front-end part.
SoC | Device Under Test | Target OS | Status |
---|---|---|---|
NXP i.MX8M-Plus | EDM-G-IMX8MP | Android 12 Android 11 |
✔ |
NXP i.MX8M-Mini | PICO-IMX8MM | Android 11 | ✔ |
Broadcom BCM2711 | Raspberry PI 4B | Android 12 | ✔ |
AllWinner H3 | Orange PI PC | Android 12 | ✔ |
Rockchip RK3399 | Orange PI 4 | Android 12 | ✔ |
- Download latest Android-Studio Visit Google Android Developer webpage and download it according your host OS such as Windows or Linux.
- Open Android-Studio after installed, click File -> Open and choose the pahe of kotlin_gpiod_demo folder.
- Waiting upgrade and build Gradle relate packages.
- Click Build -> Select Build Variant, choose debug|release mode and armeabi-v7a(ARM32)|arm64-v8a(ARM64) ABI version.
- Click Build -> Build Bundle(s)/APK(s) to compile apk
- Connect target device using USB OTG cable, wait Android-Studio detect your device, and click arrow icon (Run app) to deploy apk and run. e.g. EDM-G-IMX8MP:
- JNI library structure
- API: open source
- Native library: static library using libgpiod v1.4
- Supported platforms: armeabi-v7a, arm64-v8a
- Add 'cpp' folder inside the app folder on your Android-Studio project.
- Copy all files from 'cpp' folder of kotlin_gpiod_demo to your cpp folder which just created.
- Add cpp relate part including cmake to build.gradle(:app), for example:
defaultConfig {
applicationId "com.example.gpiod"
minSdk 28
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
externalNativeBuild {
cmake {
cppFlags ''
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your app.
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
Skip....
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.18.1'
}
}
- Try to use loadLibrary api to call JNI API in your MainActivity.java or MainActivity.kt
external fun stringFromJNI(): String
external fun getGpioTotalBank(): Int
external fun setGpioInfo(bank: Int, line: Int, value: Int): String
external fun getGpioInfo(bank: Int, line: Int): String
companion object {
// Used to load the 'myapplication' library on application startup.
init {
System.loadLibrary("JNIGpiod")
}
}
Note that if you just deploy apk to target device directly, this apk will be an untrusted_app permission in Android SELinux policy. Even if you got target device key, and sign to this apk, it still as a platform_app permission in Android runtime SELinux policy, although better than untrusted_app but still doesn't works.
-
Quick Solution
- Issue command to Diable SELinux (Permissive mode):
# setenforce 0
-
Best Solution
- Create fully support policy on Android BSP source code, it's not major topic here, but welcome to discuss with me how to fix SELinux policy issue if you need, my mail is onlywig@gmail.com
And don't forget give read/write permission for gpiochip device nodes if Android OS has no avaliable permission:
# chmod 666 /dev/gpiochip*