android动态驱动程序,Android驱动分析之mkoid(一)

(有不对的地方希望大家给予指正

2.gif)

要了解android驱动,很重要的一点就是要熟悉HAL(硬件抽象层),HAL的作用是把Android Framework与linux内核隔离,使android不过度依赖linux kernel,从而让Android Framework开发可以在不考虑驱动程序的前提下进行(我的理解是厂商已经把驱动做在HAL层,他们没有把这一层驱动代码开源,都已经做成现成的驱动模块,我们只需要根据接口调用就可以了)。 HAL中主要有如下三个结构:

struct hw_module_t

struct hw_module_methods_t

struct hw_module_device_t

这三种结果的继承关系是:hw_module_methods_t继承struct hw_module_t,struct hw_module_t继承struct hw_module_device_t;

其中hw_module_device_t主要实现的是设备关闭的一些操作。struct hw_module_t主要实现的是设备一些基本参数,比如id,name,version等。hw_module_methods_t主要实现了设备打开等一些操控方法。我的理解是类似于linux驱动里的file_operation;

hw_get_module():能够根据模块ID寻找硬件模块动态链接库的地址,然后调用load打开动态链接库从中获取硬件模块结构体地址。

mokoid工程分析

mokoid是google提供的一个LedTest示例程序,通过了解这个工程源码,对理解android层次结构,HAL编程方法非常有意义。我们可以从网络获取这个源码。

mokid结构如下:

a712ddb16a784d26bb8dff634510bbee.png

1ee688c1b00d111d4dd7fbbd34060d43.png

column339-6.jpg

JNI是Java程序可以调用C/C++写的动态链接库,要通过JNI实现android的HAL层。在android下有如下两种方法访问HAL。

1、app程序直接通过service调用.so格式的JNI:这种方法比较简单,但是不规范。

2、通过manage调用service:此方法实现起来比较复杂,但是符合目前的android框架。

第一种方法:直接调用service方法的实现过程

部分代码经过修改,后面的章节会给出修改的原因。

文件:mokoid-read-only/hardware/modules/include/mokoid/led.h

/***************************************************************************/

struct led_module_t {

struct hw_module_t common;

};

//HAL 规定不能直接使用hw_module_t结构,因此需要做这么一个继承。

struct led_control_device_t {

//自定义的一个针对Led控制的结构,包含hw_device_t和支持的API操作

struct hw_device_t common;

/* attributes */

int fd; //可用于具体的设备描述符

/* supporting control APIs go here */

int (*set_on)(struct led_control_device_t *dev, int32_t led);

int (*set_off)(struct led_control_device_t *dev, int32_t led);

};

#define LED_HARDWARE_MODULE_ID "led"

//定义一个MODULE_ID,HAL层可以根据这个ID找到我们这个HAL stub

文件:mokoid-read-only/hardware/modules/led/led.ccolumn339-9.jpg

1fc4972fad5af7aba45c439d65ed2c1b.png

column339-11.jpg

总结:由此可见HAL层主要是对下面三个函数的实现。

struct hw_module_t

struct hw_module_methods_t

struct hw_module_device_t

这三个函数包含的对设备的一些底层的控制操作。

(2)JNI层

文件:mokoid-read-only/frameworks/base/service/jni/com_mokoid_server_LedService.cppf5ba163b23aa845de2eb7be373d97d66.png

column339-13.jpg

92e0cb78c017752fc425b966045a6e69.png

bc3418c362498e2afd534b536a5566c6.png总结:JNI层首先根据HAL层注册的ID找到hw_module_t,

然后通过hw_module_t找到相应的led_control_t.然后JNI就可

以调用HAL里控制方法。再把这些方法进行注册。

(3)service (属于Framework层)

column339-16.jpg

总结:这一步主要就是sevice加载JNI动态库,调用JNI注册的函数

(4)APP 测试程序 (属于APP层)

文件:apps/LedClient/src/com/mokoid/LedClient/LedClient.java

column339-17.jpg

总结:app通过service调用

5、第二种方法:经过Manager调用service

HAL、JNI两层和第一种方法一样,所以后面只分析其他的层次。

(1)Manager (属于Framework层)

APP通过这个Manager和service通讯。

文件:mokoid-read-only /frameworks/base/core/java/mokoid/hardware/LedManager.javaf635c37ca5cb6f45d5f7e9ae8a87ccce.png

8aceebc6dcc9a74175693c7e20418a22.png

ILedService.Stub就是ILedService.aidl由aidl工具自动生成的类。

因为LedService和LedManager在不同的进程,所以要考虑到进程通讯的问题。Manager通过增加一个aidl文件来描述通讯接口

文件:mokoid-read-only/frameworks/base/core/java/mokoid/hardware/ILedService.aidl

column339-20.jpg

(2)SystemServer (属于APP层)

文件:mokoid-read-only/apps/LedTest/src/com/mokoid/LedTest/LedSystemServer.java

column339-21.jpg

(3)APP 测试程序(属于APP层)

文件:mokoid-read-only/apps/LedTest/src/com/mokoid/LedTest/LedTest.java0d21907699030227fd5c29af69f78b8b.png

c5b97035577242d91c6b7e6210058797.png

五、实验中需要注意的问题

将下载后的源码放到你的android源码目录下,然后编译系统。本实验用的android版本为2.1。实验的过程中大致出现过以下几个问题:

1、目标系统中没有生成LedClient.apk或LedTest.apk应用程序

编译完成后,没有在目标系统的system/app/目录下找到LedClient.apk或LedTest应用程序。只有通过单独编译LedClient或LedTest才能在目标目录中生成。方法如下:

#mmm mokoid-read-only/apps/LedTest/

检查原因后发现mokoid-read-only/apps/LedTest/Android.mk

LOCAL_MODULES_TAGS :=user

而我们的s5pc100系统在配置时tapas时选择的是eng,所以没有装载到目标系统。

所以修改LedTest和LedClient的Android.mk

LOCAL_MODULES_TAGS :=user eng

再次编译即可自动装载到目标系统/system/app/目录下。

2、启动后没有图标,找不到应用程序

目标系统启动后找不到两个应用程序的图标。仔细阅读logcat输出的信息发现:

E/PackageManager( 2717): Package com.mokoid.LedClient requires unavailable shared library com.mokoid.server; failing!

原因是找不到 com.mokoid.server。检查mokoid-read-only/frameworks/base/Android.mk发现系统将LedManager和LedService编译成 mokoid.jar库文件。为了让应用程序可以访问到这个库,需要通过com.mokoid.server.xml 来设定其对应关系。解决方法:拷贝com.mokoid.server.xml到目标系统的system/etc/permissions/目录下。

此时两个应用的程序的图标都正常出现了。

3、提示找不到 JNI_OnLoad

按照以前的实验加入下列代码:affb904160bc6491b43e8f4cc54dda23.png

13c64ed53fff019f0c94f36695fc1bd6.png

4、需要针对你的目标平台修改HAL的Makefile

修改mokoid-read-only/hardware/modules/led/Android.mk

LOCAL_MODULE := led.default

5、在eclipse中编译不了LedSystemServer.java

原因是程序中要用到ServiceManager.addService,这需要系统权限。

解决方法可以把应用程序放入Android源码中编译,并确保以下两点:

(1)在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。

(2)修改Android 加入LOCAL_CERTIFICATE := platform.

当然:mokoid工程源码中已经做了这些。

(待续)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值