记录一下之前做rk3568开发板项目时用到的libgpiod库,主要实现的功能是在Android环境下,调用JNI函数控制led灯的亮灭,而led灯由GPIO的高低电平控制,因此选择使用libgpiod来控制GPIO的高低电平。
参考链接:iMX6ULL 库移植 | Libgpiod 库的交叉编译及使用指南(linux)-CSDN博客
总体的步骤分为两步:
1. 在linux环境下编译libgpiod库
2. 将编译完成的库导入Android studio中
接下来将详细介绍如何实现各个步骤。
一、编译libgpiod库
1. 下载相关编译工具
sudo apt update
sudo apt-get install autoconf-archive
sudo apt-get install autoconf automake libtool
如果在使用sudo apt uadate时出现以下错误
Hit:1 [http://mirrors.ustc.edu.cn/ubuntu](http://mirrors.ustc.edu.cn/ubuntu) bionic InRelease Hit:2 [http://mirrors.ustc.edu.cn/ubuntu](http://mirrors.ustc.edu.cn/ubuntu) bionic-updates InRelease Hit:3 [http://mirrors.ustc.edu.cn/ubuntu](http://mirrors.ustc.edu.cn/ubuntu) bionic-backports InRelease Hit:4 [http://mirrors.ustc.edu.cn/ubuntu](http://mirrors.ustc.edu.cn/ubuntu) bionic-security InRelease Ign:5 [http://ppa.launchpad.net/ferramroberto/java/ubuntu](http://ppa.launchpad.net/ferramroberto/java/ubuntu) bionic InRelease Err:6 [http://ppa.launchpad.net/ferramroberto/java/ubuntu](http://ppa.launchpad.net/ferramroberto/java/ubuntu) bionic Release 404 Not Found [IP: 185.125.190.80 80] Reading package lists... Done W: Target Sources (restricted/source/Sources) is configured multiple times in /etc/apt/sources.list:2 and /etc/apt/sources.list:7 E: The repository '[http://ppa.launchpad.net/ferramroberto/java/ubuntu](http://ppa.launchpad.net/ferramroberto/java/ubuntu) bionic Release' does not have a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details. W: Target Sources (restricted/source/Sources) is configured multiple times in /etc/apt/sources.list:2 and /etc/apt/sources.list:7
出现这个错误的原因是Err:6 [http://ppa.launchpad.net/ferramroberto/java/ubuntu],因此需要检查/etc/apt/sources.list文件中是否包含无效源[http://ppa.launchpad.net/ferramroberto/java/ubuntu](http://ppa.launchpad.net/ferramroberto/java/ubuntu)
sudo vim /etc/apt/sources.list
如果文件中包含无效源,则删除该无效源所在行,如果不存在则查看所有可能包含源的文件,检查每个文件是否包含这个无效源,将无效源所在行删除,如果找的文件为空,则将空文件删除。
ls /etc/apt/sources.list.d
2. 下载源码并解压
源码地址:GitHub - brgl/libgpiod at v1.6.x
git clone https://github.com/brgl/libgpiod/tree/v1.6.x
unzip libgpiod-1.6.x.zip
如果使用git失败,就手动下载源码并解压缩。
3. 运行脚本
cd libgpiod-1.6.x
bash autogen.sh
可能出现错误:
解决方法:安装以下依赖
sudo apt-get install -y autoconf automake libtool
sudo apt-get install autoconf-archive
sudo apt-get install m4
sudo apt install pkg-config
成功执行bash atuogen.sh 后会出现以下文件
在进行编译前,需要先编辑configure,将这个文件中包含"rpl_malloc"的语句删除,否则在运行时就会出现错误“dlopen failed: cannot locate symbol “rpl_malloc””
4. 设置交叉编译环境变量
export NDK=/home/xyuanyuan/Android/Sdk/ndk/26.2.11394342
export TOOLCHAIN=${NDK}/toolchains/llvm/prebuilt/linux-x86_64
export TARGET=aarch64-linux-android
export API=29
export AR=${TOOLCHAIN}/bin/llvm-ar
export CC=${TOOLCHAIN}/bin/${TARGET}${API}-clang
export AS=${CC}
export CXX=${TOOLCHAIN}/bin/${TARGET}${API}-clang++
export LD=${TOOLCHAIN}/bin/ld
export RANLIB=${TOOLCHAIN}/bin/llvm-ranlib
export STRIP=${TOOLCHAIN}/bin/llvm-strip
TARGET=aarch64-linux-android 是我们选择的交叉编译的目标架构,根据需要选择不同的架构。例如TARGET=armv7a-linux-androideabi,TARGET=i686-linux-android,TARGET=x86_64-linux-android。Android studio的虚拟机是x86_64架构
aarch64-linux-android29-clang 是一个基于Clang编译工具的工具链,用于在Android平台上编译armv8架构的代码,主要特点包括:
- 支持使用 LLVM/Clang 编译器进行编译,具有优秀的代码优化能力和兼容性;
- 支持 ARMv8 架构指令集,可以生成针对 ARMv8 架构的优化代码;
- 针对 Android 平台进行了优化,可以使用 Android 平台上的系统库和头文件;
- 适用于 Android 9.0 及以上版本(API level 29)。
- 使用该工具链可以在 Android 平台上编译出高效、稳定、兼容性好的 ARMv8 架构代
码,适用于开发 Android 平台上的应用程序和系统级组件。
5. 在源码目录上运行上一步生成的configure脚本,生成Makefile文件
sudo ./configure CC=${CC} CXX=${CXX} RANLIB=${RANLIB} AR=${AR} STRIP=${STRIP} --prefix=/home/android_libgpiod --host=${TARGET}
# --prefix指定安装目录,更换为自己的目录
使用makefile安装
sudo make
sudo make install
安装完成后,可以在“–prefix指定安装目录”指定的安装目录中找到已经编译完成的文件,在其中我们重点关注gpiod.h和libgpiod.so文件,这两个文件会被拷贝到项目中。
使用file命令查看编译后的文件是否符合架构
二、在Android studio中加载libgpiod
将页面视图切换为Project,将上一步编译成功的gpiod.h和libgpiod.so文件添加到项目中,需要修改的文件包含:
CMakeLists.txt
build.gradle.kts
1. 导入libgpiod
- 在app/src/cpp下新建文件夹include,将gpiod.h文件拷贝到此文件夹中
- 新建JNI文件夹,在新建的JNI文件夹下新建文件夹arm64-v8a,将libgpiod.so文件拷贝到此文件夹中,如下图所示:
2. 修改CMakeLists.txt文件
cmake_minimum_required(VERSION 3.22.1)
project("myapplication")
# 定义 libgpiod 目标并设置为 IMPORTED 类型
add_library(libgpiod SHARED IMPORTED)
# 设置 libgpiod 的 IMPORTED_LOCATION 属性
set_target_properties(libgpiod
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/../jni/${CMAKE_ANDROID_ARCH_ABI}/libgpiod.so)
# 添加你的项目的目标
add_library(${CMAKE_PROJECT_NAME}
SHARED # List C/C++ source files with relative paths to this CMakeLists.txt.
native-lib.cpp)
# 将 libgpiod 链接到你的项目中
target_link_libraries(${CMAKE_PROJECT_NAME}
# List libraries link to the target library
${log-lib}
libgpiod
log)
3. 修改build.gradle.kts文件
在defaultConfig中添加以下语句:
ndk {
abiFilters.add("arm64-v8a")
}
4. 在使用libgpiod的java类中添加System.loadLibrary("gpiod");
package com.example.myapplication;
public class HardCtrl {
public static native void ledOpen();
public static native int ledCtrl(int which, int status);
static{
System.loadLibrary("myapplication");
System.loadLibrary("gpiod");
}
}
同时在JNI函数的实现中包含gpiod头文件,#include "include/gpiod.h"
按照以上步骤添加后就能在Android studio中使用libgpiod库了~