主题 : 从HAL层到java应用层重写mini6410 led功能 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 70325
精华: 0
发帖: 34
金钱: 170 两
威望: 34 点
贡献值: 0 点
综合积分: 68 分
注册时间: 2012-05-18
最后登录: 2012-10-26
楼主  发表于: 2012-08-08 19:10

 从HAL层到java应用层重写mini6410 led功能

从HAL层到java应用层重写mini6410 led功能

记录了我从HAL层到应用层如何把led这个设备控制实现的过程。如果有遗漏或者错误,请各位高手指点。

led驱动的代码就不说了,以后有空再实现,
第一步,查看linux驱动设备是否工作正常。之后所有的一切,都是在这个leds设备的基础上操作完成的,所以,检查这个设备是不是有用成为了一个很重要的关键。
首先,用adb shell查看android dev下的目录,发现有leds这个设备:
ls -l /dev/leds 这个设备文件就是android中间层用来操作Linux底层led设备的。
回到android2.3.4源代码目录,在 external目录底下建立testDev目录,在下面分别建立Android.mk 和 testDev.c文件
在testDev.c这个文件里,首先写一个测试程序用来测试Leds这个文件设备能否正常运行;
testDev.c,打开设备关键是ioctl这个函数,其中,第二个参数用来控制是否打开一个led设备,第三个参数用来控制打开的是那个led。(testDev.c 和 Android.mk这2个程序可以见附件。)
全部写完之后,用./build-android编译一下,编译的时候,可以指定特定模块编译,这样比较节省时间。不能用mmm这个命令编译,这个编译了之后product的名称就不是mini6410了,这样很多库都会找不到。编译之后android的out/target/product/mini6410/system/bin/ 目录下面会生成一个叫 testDev的文件,然后将开发板开机,用adb push out/target/product/mini6410/system/bin/testDev system/bin/ 把testDev push到开发板上面去,然后用adb shell命令进入到system/bin/目录下面,运行./testDev 就可以检测leds这个设备是否运行正常。


第二步,为linux的led驱动提供android的HAL层。
HAL是android的硬件逻辑层,在这里,主要是为framework层提供一层Led的操作接口。直接操作leds设备的函数在第一步已经指明了,就是ioctl函数,但是,如何将这个功能增加到android的框架里呢?
首先,增加hardware/libhardware/modules/目录下的mydevice目录,然后在这个目录下再新建Led目录,在led目录下,分别建立led.c和Android.mk文件在mydevice这个目录下,也需要建立Android.mk文件用来搜索mydevice目录下的每个驱动设备目录。在hardware/libhardware/include/hardware 下,建立hardware目录,在下层建立mydevice/led.h,该文件用来实现一些module_id之类的宏和结构体,这里比较重要的是DEVICE_NAME一定要写对,这个就是程序需要读取的设备,还有MODULE_NAME的取名要跟Android.mk里面的LOCAL_MODULE前缀一样,否则程序加载的时候会找不到。硬件结构体是继承hw_device_t这个结构的,在这个结构体里,可以定义leds设备的fd,和这个设备需要操作的一些结构函数,比如这边就增加了set_led,用来控制Led设备的。
最后还要修改hardware/libhardware/ Android.mk,将增加好的led结构添加进去。
include $(addsuffix /Android.mk, $(addprefix $(LOCAL_PATH)/, \
            modules/gralloc \
            modules/mydevice \ --》增加这行
            tests \
        ))
        
然后编译一下,out/target/product/mini6410/system/lib/hw目录下会生成led.default.so这个文件,编译就成功了。


第三步,增加jni底层对上层的应用接口。
在这一步当中,封装了底层的.c的接口函数,使得上层Java可以调用, 做到这一步,java应用层应该也可以调用这一步生成的.so,友善提供的.so文件应该就是做到这一步生成的。
这一步当中,首先添加framework/base/services/jni目录下的com_android_server_DeviceService.cpp文件,这个文件用来动态加载jni的接口函数。为java上层提供帮助。Method_table这个表提供了底层到Java层的映射,
    static const JNINativeMethod method_table[]=
    {
        {"openLed", "()Z", (void*)led_init}, --》第一个是java层可以调用的函数名,第二个是函数签名,第三个是本层函数名
        {"set_Led", "(II)I", (void*)setLed},
    };
java层调用映射之后的字符就可以完成对底层的通讯了。全部写完之后,还要在frameworks/base/services/jni/onload.cpp这个文件当中将method_table这个表加载进系统里(JNI_OnLoad),然后在Android.mk下增加com_android_server_DeviceService.cpp文件就可以编译了。
LOCAL_SRC_FILES:= \
    com_android_server_AlarmManagerService.cpp \
    com_android_server_BatteryService.cpp \
    com_android_server_InputManager.cpp \
    com_android_server_LightsService.cpp \
    com_android_server_PowerManagerService.cpp \
    com_android_server_SystemServer.cpp \
    com_android_server_UsbService.cpp \
    com_android_server_VibratorService.cpp \
    com_android_server_location_GpsLocationProvider.cpp \
    com_android_server_DeviceService.cpp \  --》增加这行。
    onload.cpp

第四步,用aidl增加java services。
Aidl是一个工具,他可以用来增加java的services,首先,在frameworks/base/core/java/android/os/路径下增加IDeviceService.aidl接口,然后,在 frameworks/base/Android.mk里面增加这个aidl文件,编译一下,这个时候就会生成stub,新增frameworks/base/services/java/com/android/server这个路径下的DeviceService.java,这个java文件里需要继承刚才用aidl工具生成出来的IDeviceService.Stub,之后对jni接口进行再一次封装。在frameworks/base/services/java/com/android/servier/SystemServer.java里面需要增加这个服务,之后重新编译程序就可以了。

第五步,在java应用层调用底层编译好的java service服务。
用eclipse新建一个java项目,然后在这个新建的工程里面把操作的button做好,这个界面由于只是测试程序,所以就做了一个button,这个button的功能就是依次打开和关闭led灯。

本部分内容设定了隐藏,需要回复后才能看到
[ 此帖被bottles在2012-08-09 13:38重新编辑 ]
级别: 侠客
UID: 58655
精华: 0
发帖: 130
金钱: 645 两
威望: 130 点
贡献值: 0 点
综合积分: 260 分
注册时间: 2011-11-11
最后登录: 2017-09-13
1楼  发表于: 2012-08-08 20:12
看看,,,
级别: 侠客
UID: 11034
精华: 0
发帖: 71
金钱: 355 两
威望: 71 点
贡献值: 0 点
综合积分: 142 分
注册时间: 2009-11-25
最后登录: 2018-02-08
2楼  发表于: 2012-08-08 23:23
还没搞java的。。唉。。
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5407
金钱: 40120 两
威望: 17929 点
贡献值: 71 点
综合积分: 11054 分
注册时间: 2008-01-16
最后登录: 2014-11-22
3楼  发表于: 2012-08-09 13:21
不错,支持一下!
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
级别: 新手上路
UID: 70325
精华: 0
发帖: 34
金钱: 170 两
威望: 34 点
贡献值: 0 点
综合积分: 68 分
注册时间: 2012-05-18
最后登录: 2012-10-26
4楼  发表于: 2012-08-09 13:38
总算全贴好了,功能简单,但是也花了我不少时间
My Blog:www.ipigman.com
级别: 侠客
UID: 19993
精华: 0
发帖: 134
金钱: 670 两
威望: 134 点
贡献值: 0 点
综合积分: 268 分
注册时间: 2010-04-26
最后登录: 2018-04-22
5楼  发表于: 2012-08-09 14:40
请问下楼主,我有一个串口蓝牙。 是不是android能够使用蓝牙,也是按照和你LED 类似的方式去添加,使其支持!
级别: 新手上路
UID: 70325
精华: 0
发帖: 34
金钱: 170 两
威望: 34 点
贡献值: 0 点
综合积分: 68 分
注册时间: 2012-05-18
最后登录: 2012-10-26
6楼  发表于: 2012-08-09 15:25

 回 5楼(hayvane) 的帖子

饿,我也刚刚学。。tiny6410里好像木有蓝牙设备啊?你自己买了设备写了一个?饿,高手。。你可以按照步骤1去确定你能不能操纵这个蓝牙设备,如果可以,那就能这么添加滴。
级别: 骑士
UID: 29604
精华: 9
发帖: 171
金钱: 1830 两
威望: 366 点
贡献值: 9 点
综合积分: 522 分
注册时间: 2010-10-01
最后登录: 2016-04-13
7楼  发表于: 2012-08-10 16:41
参考参考。。。。。。
看看怎么添加框架服务
级别: 新手上路
UID: 75974
精华: 0
发帖: 24
金钱: 120 两
威望: 24 点
贡献值: 0 点
综合积分: 48 分
注册时间: 2012-08-16
最后登录: 2013-07-29
8楼  发表于: 2012-08-16 11:10
很好,我真好也要做这个!
级别: 侠客
UID: 8041
精华: 0
发帖: 88
金钱: 450 两
威望: 101 点
贡献值: 0 点
综合积分: 176 分
注册时间: 2009-08-07
最后登录: 2018-04-11
9楼  发表于: 2012-08-16 17:04
很好看看