In the healthcare industry, operating systems in human-machine interfaces often adjust the brightness and color of different LED light bars based on the patient’s condition. This section will share a complete LightBar solution based on the Android system. It covers the implementation of functionalities from the low-level stage driver porting to application layer, followed by the development of the JNI library and the integration with the APK. Through this, we aim to provide insights into how to implement special peripheral devices in the Android Open Source Project (AOSP).
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
Implementing a LED LightBar solution on Android system
1. Implementing a LED Light Bar
Solution on Android System
LC Wang, Wig Cheng
30 July 2023
2. OUTLINE
• PART I. System Part (Presented by Wig Cheng)
Implementing JNI function in system
• PART II. APK Part (Presented by LC Wang)
Implementing a demo APK using JNI library
3. PART I.
• Me
• Motivation
• System architecture
• AOSP Kernel driver tweaking
• LIBUBOOTENV porting
• JNI implementation
• Summary
4. ME
• Name: Wig
• Job: IEIWorld - Android OS team
• Work
#> Embedded Linux platforms
#> Industrial Android BSP
• GITHUB: https://github.com/wigcheng
7. MOTIVATION
• In healthcare use case which need LED color for a patient’s
health status. In this case, we'll show you a LED light-bar
solution using Android OS.
8. MOTIVATION (CONT'D)
Power on APP Sleep (Suspend) Power off
System Status Power on Power on Sleep Power off
Power LED Off Off
Color Blinking
default: Blue
On/off (Red)
default: On
User LED Off
1. LED control
2. Wave/Breath mode
3. Sleep/Power off setting
Off Off
blinking
blinking
Specifications
9. MOTIVATION (CONT'D)
Specifications
LED light bar
LED light bar
Power LED
User LED User LED
Power LED
Platform:
- NXP ARM Cortex-A53 IMX8MM
Supported OS:
- Android 12, Kernel 5.10.72
- Android 13, Kernel 5.15.74
10. SYSTEM ARCHITECTURE
Hardware
U-boot
AOSP Kernel
ART
JNI Layer
APP Layer
1. Enabling LightBar driver with device tree
2. Tweaking driver
AOSP
1. libubootenv library porting
2. Checking LED nodes
3. SELINUX
1. Add LightBar related boot argument
1. DesignAPIs for APK
1. Design demo APK
11. TI TLC59116 LED driver IC
16 channels
via I2C bus
PWM control method
Linux upstream driver
Enable driver in defconfig
Add to device tree
Tweaking driver (later)
AOSP KERNEL DRIVER
• Normal defconfig
<source>/vendor/nxp-opensource /kernel_imx /arch
/arm64/configs/iei_imx_android_defconfig
• GKI (Google Kernel Image) defconfig
<source>/vendor/nxp-opensource
/kernel_imx /arch /arm64/configs/imx8mm_gki.fragment
CONFIG_LEDS_TLC591XX=m (build as kernel module)
master SDA
SCL
slave 1 slave 2
13. AOSP KERNEL DRIVER (CONT.D)
CONFIG_LEDS_TLC591XX → drivers/leds/leds-tlc591xx.c
static struct i2c_driver tlc591xx_driver = {
.driver = {
.name = "tlc591xx",
.of_match_table = of_match_ptr(of_tlc591xx_leds_match),
.pm = &tlc591xx_pm_ops,
},
.probe = tlc591xx_probe,
.shutdown = tlc591xx_shutdown,
.id_table = tlc591xx_id,
};
Add to driver for suspend/resume function
add LED blinking behavior to suspend function
add clear LED state behavior to resume function
static SIMPLE_DEV_PM_OPS(tlc591xx_pm_ops,
tlc591xx_suspend, tlc591xx_resume);
Add to driver for power-off function
add turn on red color for LED to shutdown function
Modify driver
14. LIBUBOOTENV PORTING
New tool in 2021 (DENX)
Feature – modify bootargs in rootfs of Linux OS
Port to AOSP
Source path: <source>/external/libubootenv
Add Android.bp (Makefile)
Output file
/vendor/lib64/libubootenv.so (library)
/vendor/bin/fw_printenv (utility)
/vendor/bin/fw_setenv (utility)
/vendor/etc/fw_env.config (config)
eMMC address:
/dev/block/mmcblk2 0x400000 0x4000
device name offset address env size
Tracing U-boot defconfig
<u-boot source>/configs/xxx_android_defconfig
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_OFFSET=0x400000
15. JNI IMPLEMENTATION
Implement via C/C++ -> LightBar.cpp
Bridge using CMAKE configuration
API definition
setLightBarUserLED
clearLightBarLED
setLightBarBreathMode
setLightBarWaveMode
setLightBarPowerLedSuspendColor
setLightBarPowerLedPoweroffState
getLightBarPowerLedStatus
JAVA Base
Kotlin Base
LightBar.cpp
JniMethod.java
MainActivity.java
JniMethod.kt
MainActivity.kt
16. JNI IMPLEMENTATION (CONT.D)
Implementation flow
User LED controlling
Power LED controlling
Open specific LED
brightness node
/sys/bus/i2c/drivers/tlc591xx/1-0060/leds/i2c<bus>_led_<color>_<number>/brightness
/sys/bus/i2c/drivers/tlc591xx/3-0060/leds/i2c<bus>_led_<color>_<number>/brightness
read/write brightness node close brightness node
Adapt fw_setenv command
popenAPI pclose
Adapt fw_printenv command
Suspend argument: leds.suspend_color="<color>"
support color list: red, green, blue (default), yellow, cyan, magenta, white
Power-off argument: leds.poweroff_state="<status>"
support state list: on, off
17. U-boot environment arguments
1. Save to eMMC specific
address
2. Add power LED relate
argument
SUMMARY
Kernel driver (as a module)
1. Load power LED arguemnt
from u-boot arguments
2. Initial drivers with specific
functions
libubootenv
1. Load power LED arguemnt
from u-boot arguments in
ART stage
2. Set power LED argument to
u-boot environment (need
reboot)
Implement JNIAPI to APK
development
18. PART II.
Me
App architecture
App java design
App JNI design
SELinux
Troubleshooting