tiny4412led之buildjni实现(代码片段)

冷冻的彩虹 冷冻的彩虹     2023-02-03     793

关键词:

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_0		1
#define LED_1		2
#define LED_2		3
#define LED_3		4

//幻数
#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);
		else
			ioctl(leds_fd, LEDS_PGM4_0_OFF);
		break;
	case LED_1:
		if (status)
			ioctl(leds_fd, LEDS_PGM4_1_ON);
		else
			ioctl(leds_fd, LEDS_PGM4_1_OFF);
		break;
	case LED_2:
		if (status)
			ioctl(leds_fd, LEDS_PGM4_2_ON);
		else
			ioctl(leds_fd, LEDS_PGM4_2_OFF);
		break;
	case LED_3:
		if (status)
			ioctl(leds_fd, LEDS_PGM4_3_ON);
		else
			ioctl(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 JNICALL
JNI_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目录下,然后就可以运行程序




tiny4412led之ndkjni实现(代码片段)

PC机平台:ubuntu12.04.5硬件平台:Tiny4412标准版+android5.0Tiny4412硬件电路从电路原理图可以知道LED灯连接到处理器的GPM4的0-3端口,且LED被上拉到3.3V的源,只有GPIO口输出低电平时就能点亮LED灯;GPM4寄存器只要把... 查看详情

基于tiny4412的andorid开发-------简单的led灯控制

阅读目录(Content)一、编写驱动程序二、编写代码测试驱动程序三、编写HAL代码四、编写Framework代码五、编写JNI代码六、编写App参考资料:《Andriod系统源代码情景分析》《嵌入式Linux系统开发完全手册_基于4412_上册》  作者... 查看详情

tiny4412字符设备的上层测试程序(底层驱动为/dev/leds)

leds#include<linux/kernel.h>#include<linux/module.h>#include<linux/miscdevice.h>#include<linux/fs.h>#include<linux/types.h>#include<linux/moduleparam.h>#include< 查看详情

友善之臂tiny4412linux系统怎么跑qt

参考技术A试试在shell中输入:alsamixer,里面有调节系统音量大小的选项。。。 查看详情

tiny4412--uboot移植时钟(代码片段)

开发环境:win1064位 +VMware12+Ubuntu14.0432位工具链:linaro提供的gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi要移植的u-boot版本:u-boot-2016-11Tiny4412开发板硬件版本为:  底板:  Tiny4412SDK1312B  核心板:Tiny4412-1306 ... 查看详情

tiny4412--uboot移植串口(代码片段)

...TATn寄存器(UARTFIFOSTATUS) 3、使用Tiny4412Debug 串口uart0代码设置diff--gita/arch/arm/dts/exynos4412-tiny44 查看详情

tiny4412-1312__uboot移植(代码片段)

开发环境:win1064位 +VMware12+Ubuntu14.0432位工具链:linaro提供的gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi要移植的u-boot版本:u-boot-2016-11Tiny4412开发板硬件版本为:  底板:  Tiny4412SDK1312B  核心板:Tiny4412-1306 ... 查看详情

lcd驱动端与设备端名称匹配过程分析(tiny4412)

...屏点亮,​这是怎么回事的呢?下面我们来分析这是如何实现的。​硬件平台​Cpu:exynos4412​板子:tiny4412​Linux内核:linux-3.5​21.6.1lcd平台驱动层相关代码构架​Lcd平台驱动层在S3c-fb.c(linux-3.5\\drivers\\vid 查看详情

tiny4412开机动画开机界面的定制原创

关键词:Android linux开机logo开机动画 平台信息:内核:linux3.0.68 系统:android/android5.1平台:tiny4412作者:庄泽彬(欢迎转载,请注明作者)邮箱:[email protected]摘要:最近晚上回到宿舍有点无聊,搞一下打发时间,如有... 查看详情

tiny6410之led裸机驱动

操作步骤:第一步:查看开发板电路原理图  找到LED的管脚所对应的寄存器  nLED_1-GPK4  nLED_2-GPK5  nLED_3-GPK6  nLED_4-GPK7  由原理图可知LED对应的寄存器为GPK寄存器,由二极管的特性可知当LED_n为低电平时LED灯亮第二... 查看详情

tiny4412学习杂记

1.Android挂载NFS使用busyboxmount来替代mount命令2.修改Uboot中fastboot最大buff 使用U-boot烧写Android5.0的时候出现remote:datatoolarge将 include/configs/tiny4412.h 改大一点3.tiny4412内核中trustzone配置开关tiny4412 trust 查看详情

tiny4412uboot

1.Builduboota)安装好toolchain(arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz)并设置好环境变量PATH,保证可以正常使用。b)解压uboot_tiny4412-20130729.tgz并进入相应的目录tarxzfuboot_tiny4412-20130729.tgzc)配置uboot并编译cduboot_tiny4412maketiny441 查看详情

linux内核lcd驱动分析与换屏方法(tiny4412)

​Linux内核中换屏技术​21.5.1u-boot中的参数bootargs实现换屏​在uboot中有一个bootargs环境变量,这个参数就是传递数据给内核的。​对tiny4412提供的内核,可以通过修改bootargs实现驱动不同的LCD屏。​21.5.2分析bootargs中的lcd参数再启... 查看详情

armcortex-a9(tiny4412)(代码片段)

要求移植linux增加系统调用并烧写至开发板详细步骤一、搭建linux编译环境1、GCC编译器的安装:tarxzvfarm-linux-gcc-4.5.1-v6-vfp-20120301.tgz-C/arm-linux-gcc-v//查看GCC版本2、gedit~/.bashrcexportPATH=$PATH:/opt/FriendlyARM/toolschain/4.5.1/bin3、rebo 查看详情

tiny4412sdk1161下的hd700驱动设置

平台:Tiny4412SDK1161B+HD700kernel:linux3.5手头有一块友善之臂的开发板,需要使用HD700屏来显示图片,但是移植好内核后/dev/fb0设备并不能用,看屏幕显示了三排小企鹅,并且存在色差,怀疑lcd驱动并不配套HD700之个型号,故需要做调... 查看详情

tiny6410之按键裸机驱动

操作步骤:第一步:查看开发板电路原理图  找到LED和按键的管脚所对应的寄存器  LED:(见Tiny6410之LED裸机驱动)    nLED_1-GPK4    nLED_2-GPK5    nLED_3-GPK6    nLED_4-GPK7  Buttons:    K1  GPN0   ... 查看详情

tiny4412的中断资源连接关系示意图

在tiny4412的设备树中可以发现,中断资源是以树的形式呈现的,下面是我画的一张图,大致描述了tiny4412上中断资源的连接关系。可以到http://pan.baidu.com/s/1ge0sz6N下载。其中,红色的表示的是rootinterruptcontroller(中断资源的生产者... 查看详情

uboot移植前奏

  Tiny4412开发板硬件版本为:     底板: Tiny4412/Super4412SDK1506      核心板:Tiny4412-1412 1、下载u-boot源代码,建立u-boot代码仓库   参考:h 查看详情