LED 驱动在内核中是以混杂设备的形式注册的,设备节点是 /dev/leds,内核中 file_operations 只实现了 unlocked_ioctl 方法,这也限制上层应用必须用 ioctl 来控制 LED 的状态。
1.编写驱动测试程序 leds.c
int main(int argc, char *argv)
{
int fd;
fd = open("/dev/leds", O_WRONLY);
if(fd < 0)
{
printf("open /dev/leds error\n");
return -1;
}
ioctl(fd, 1, 0); //点亮第1盏灯 ioctl(fd, ledState, ledID);
close(fd);
return 0;
}
*编译:# arm-linux-gcc -o leds leds.c
*使用 adb 命令下载到开发板:E:\driver\tiny6410\led> adb push leds /system
*执行:# ./leds
*出现错误:# sh: ./leds: Permission denied 这是由于 leds 没有可执行权限造成的,使用命令 # chmod 777 leds 为 leds 增加可执行权限
*再次执行:# ./leds
*出现错误:# sh: ./leds: not found 这是缺少某些 C 库造成的,使用静态编译 # arm-linux-gcc -static -o leds leds.c
*再次下载到开发板中运行,LED 总算点亮了
2.利用 NDK 构建 Android JNI 库
要让使用 C 语言编写的方法能被 Android 应用程序调用,两者必须符合一定的接口规范,修改 leds.c。
Java_com_fourmily_AndroidSDK_HardwareControler_setLedState
Java:JNI 中的方法都必须使用 Java 作为开头
com_fourmily_AndroidSDK:方法所在类的 package 名
HardwareControler:方法所在类的类名
setLedState:方法名
*将 leds.c 拷贝到 [NDK]/apps/led/jni ([NDK]代表NDK的安装目录)
*在 [NDK]/apps/led/jni 目录下编写 Android 的 Makefile Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := leds //编译后的库文件名,NDK会自动加前缀lib和后缀.so
LOCAL_SRC_FILES := leds.c //要编译的源文件
include $(BUILD_SHARED_LIBRARY) //构建共享库标志
Android.mk 是用来编译 leds.c 的 Makefile,因此两个文件应该同处于 jni 目录下。编译的结果保存在 [NDK]/apps/led 目录下的 libs/armeabi/ 目录下。
*编译之前应该在 [NDK]/apps/led 目录下编写 Application.mk 即顶层 Makefile
APP_PROJECT_PATH := $(call my-dir) //jni目录所在的上一层目录
APP_MODULES := leds //库文件名
*NDK 顶层目录下:[NDK]# make APP=led 这里的 led 代表 apps 目录下的 led 目录。
3.使用生成的 libleds.so 编写 Android 应用程序
libleds.so 只能被 com.fourmily.AndroidSDK.HardwareControler 这个类加载,本地接口也都必须在这个类中进行声明。
——忠于梦想 勇于实践 linux_xpj@opencores.org
阅读(2665) | 评论(0) | 转发(1) |