开发板:firefly-rk3399
SDK:Android7.1
背景:编写了一个linux内核的驱动文件,生成设备节点,通过C语言程序进行调用测试,将该C语言测试程序放入开发板进行测试,起测试代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define DEVICE_NAME "/dev/tlc"
int main( int argc, char ** argv )
{
int fd;
printf("\n -----start tlc led test----- \n");
fd = open(DEVICE_NAME, O_RDWR );
printf("fd = %d \n", fd );
if ( fd == -1 )
{
printf("open device %s error \n", DEVICE_NAME );
}
else
{
while(1)
{
printf("-----output led-----\n");
ioctl(fd, 0x31);
//sleep(500);
ioctl(fd, 0x32);
//sleep(500);
ioctl(fd, 0x33);
//sleep(500);
}
}
return 0;
}
测试可用,可正常控制驱动进行LED的操作。
在使用NDK生成so库文件时,将上述代码修改,如下所示:
#include <string.h>
#include <jni.h>
#include <fcntl.h>
#define DEV_NAME "/dev/tlc"
jstring Java_com_tlc_HardwareControlClass_stringFromJNI( JNIEnv *env, jobject thiz )
{
return (*env)->NewStringUTF(env, "tlc from JNI!");
}
jint Java_com_tlc_HardwareControlClass_Init( JNIEnv *env, jobject thiz )
{
int fd = open( DEV_NAME, O_RDWR );
return fd;
}
jint Java_com_tlc_HardwareControlClass_IOCTLED( JNIEnv *env,
jobject thiz,
jint light,
jint controlcode,
jint fd )
{
int FD = fd;
int CTLCODE = controlcode;
unsigned long LIGHT = light;
ioctl( FD, CTLCODE, LIGHT );
return 0;
}
在Ubuntu环境下,使用下载的NDK进行编译,提示 error:implicit declaration of function 'ioctl' is invalid
这个错误,网上信息较少,经过几个小时的搜寻,发现是头文件引用错了,和C中的不同,添加如下头文件
#include <unistd.h>
#include <sys/ioctl.h>
添加后,在编译,提示编译成功!
至此,Android驱动编写,测试,到生成so文件供安卓APP调用的链路打通。从安卓linux小白,到整个过程测通,历时2个星期,查阅了大量资料,踩了无数的坑,终于整通了。抽空我会写一下整个过程,列一下踩过的坑,给后来者提供一些帮助。
该问题参考:
https://blog.csdn.net/zhangchunyu_jndx/article/details/79534584