Tiny4412 led之build JNI实现
来源:互联网 发布:网络销售公司规章制度 编辑:程序博客网 时间:2024/05/14 12:51
PC机平台:ubuntu 12.04.5
硬件平台:Tiny4412标准版+android5.0
上一篇:Tiny4412 led之NDK JNI实现,介绍的是通过NDK工具进行JNI开发,*.so文件是通过NDK工具进行编译生成的,这次就介绍如何通过arm-linux-gcc编译生成对应的*.so文件,深入了解JNI底层的开发流程;
驱动代码、JNI接口、android应用程序都是Tiny4412 led之NDK JNI实现的代码;需要重新编写的只有*.c文件;
新建tiny4412-leds.c
#include <jni.h> #include <stdio.h>#include <android/log.h> #include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <linux/ioctl.h>#define DEVICE_NAME"/dev/tiny4412-leds"#define LED_01#define LED_12#define LED_23#define LED_34//幻数#define LEDS_MAGIC'a'#define LEDS_PGM4_0_ON_IO(LEDS_MAGIC, 1)#define LEDS_PGM4_0_OFF_IO(LEDS_MAGIC, 2)#define LEDS_PGM4_1_ON_IO(LEDS_MAGIC, 3)#define LEDS_PGM4_1_OFF_IO(LEDS_MAGIC, 4)#define LEDS_PGM4_2_ON_IO(LEDS_MAGIC, 5)#define LEDS_PGM4_2_OFF_IO(LEDS_MAGIC, 6)#define LEDS_PGM4_3_ON_IO(LEDS_MAGIC, 7)#define LEDS_PGM4_3_OFF_IO(LEDS_MAGIC, 8)jint JNICALL leds_operation(JNIEnv *env, jobject cls, jint ledsNum, jboolean status){int leds_fd = 0;leds_fd = open(DEVICE_NAME, O_RDWR);if (leds_fd == -1) {__android_log_print(ANDROID_LOG_DEBUG, "tiny4412-leds", "leds_operation fail!");return 1;}__android_log_print(ANDROID_LOG_DEBUG, "tiny4412-leds", "leds_operation ledNum:%d,status:%d", ledsNum, status);switch (ledsNum) {case LED_0:if (status)ioctl(leds_fd, LEDS_PGM4_0_ON);elseioctl(leds_fd, LEDS_PGM4_0_OFF);break;case LED_1:if (status)ioctl(leds_fd, LEDS_PGM4_1_ON);elseioctl(leds_fd, LEDS_PGM4_1_OFF);break;case LED_2:if (status)ioctl(leds_fd, LEDS_PGM4_2_ON);elseioctl(leds_fd, LEDS_PGM4_2_OFF);break;case LED_3:if (status)ioctl(leds_fd, LEDS_PGM4_3_ON);elseioctl(leds_fd, LEDS_PGM4_3_OFF);break;defautl :break;}close(leds_fd);return 0;}static const JNINativeMethod methods[] = { //本地方法列表{"ledsOperation", "(IZ)I", (void *)leds_operation}, //"ledsOperation"为tiny4412Leds.java中的jni接口};/* System.loadLibrary */JNIEXPORT jint JNICALLJNI_OnLoad(JavaVM *jvm, void *reserved) {JNIEnv *env;jclass cls;if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_4)) {return JNI_ERR; /* JNI version not supported */}cls = (*env)->FindClass(env, "com/example/Tiny4412_leds/tiny4412Leds"); //包名+类名,将‘.’换成‘/’if (cls == NULL) {return JNI_ERR;}if ((*env)->RegisterNatives(env, cls, methods, 1) < 0) //注册本地方法return JNI_ERR;return JNI_VERSION_1_4;}
JNI的C代码不算特别复杂,就是简单的将本地方法注册java虚拟机中;当java调用System.loadLibrary("tiny4412-leds");时,就会调用JNI_OnLoad方法,通过JNI_OnLoad方法注册tiny4412Leds类的本地方法到java虚拟机中,就会虚拟机中为tiny4412Leds类中添加本地接口,之后应用程序才能正常使用tiny4412Leds类的本地方法;
编译libtiny4412-leds.so
在ubuntu下将tiny4412-leds.c编译成libtiny4412-leds.so
root@pc:/home/workplace/Tiny4412# arm-linux-gcc -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/-I ./android-5.0.2/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/include/ -fPIC -shared -o libtiny4412-leds.so tiny4412-leds.c -nostdlib android-5.0.2/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/lib/libc.so android-5.0.2/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/lib/liblog.so
选项:-fPIC
-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code), 则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
选项:-nostdlib
-nostdlib作用于编译阶段,告诉编译器不使用标准的lib库;
如果不加上 -I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/ 就会出现找不到jni.h的错误提示;
如果不加上 -I ./android-5.0.2/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/include/ 就会出现找不到log.h的错误提示;
如果不加上 android-5.0.2/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/lib/libc.so 加载libtiny4412-leds.so 就会出现;dlopen("/data/app/com.example.Tiny4412_leds-2/lib/arm/libtiny4412-leds.so", RTLD_LAZY) failed: dlopen failed: could not load library "libc.so.6" needed by "libtiny4412-leds.so"; caused by library "libc.so.6" not found 的错误提示;系统中默认没有libc.so.6库,所以可以直接指定使用libc.so进行代替;
如果不加上 android-5.0.2/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/lib/liblog.so 就会出现java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__android_log_print" referenced by "libtiny4412-leds.so"... 的错误提示;使用打印接口需要使用到liblog.so否则就会出错,该liblog.so可以在android源码中查找得到;
编译完成后在libs目录下创建armeabi目录,并将libtiny4412-leds.so拷贝到armeabi目录下,然后就可以运行程序;
- Tiny4412 led之build JNI实现
- Tiny4412 led之NDK JNI实现
- tiny4412 SDK1312B LED驱动
- tiny4412学习(四)之移植linux-设备树(2)设备树之LED点灯
- 第三十三天:Tiny4412驱动开发之LED驱动和u-boot移植
- tiny4412中JNI层问题
- Tiny4412汇编流水灯代码,Tiny4412裸机LED操作
- Tiny4412-LED小灯裸机程序
- Tiny4412-LED小灯裸机程序
- Tiny4412开发板 LED灯的控制
- tiny4412内核自带led驱动分析
- tiny4412开发板LED灯驱动写法
- tiny4412之环境设置
- Tiny4412学习之--MMU
- mini6410-JNI-led
- tiny4412 裸机程序 二、汇编点亮LED灯
- 基于TINY4412的Andorid开发-------简单的LED灯控制
- 基于TINY4412的Andorid开发-------简单的LED灯控制
- Eclipse 重构
- 如何创建新的FreeRTOS工程
- 10gRAC修改vip,public ip
- jsp分页显示Java代码实现
- marathon参考(3)服务发现和负载均衡
- Tiny4412 led之build JNI实现
- Maven常用命令介绍
- 关于应用性能检查的几个文章
- 关于PDO--数据库抽象层
- 2016 腾讯笔试题 最长回文字串(不连续)(dp)
- POJ2376-Cleaning Shifts
- Spark Streaming + kafka
- [2016-4-4]实验三要求已上传,请提前编写程序
- libwireless 源码解析