考研已经过去了,android驱动的学习也断了半年多了,现在重新捡起来学习,回顾一下Android驱动的大体框架。
Android系统的核心是java,其有一个David虚拟机。Android-app操作硬件也相当于是java操作硬件。
在Linux系统上操作硬件是通过open read write等来实现,也就是操作C库。如果java能直接调用C库中的函数,也就解决了app操作硬件的问题。
下面的文章是java调用C/C++库的方法。
1.方法1——jni调用底层驱动
在android框架中写入c/c++直接调用底层linux驱动,并向上提供jni接口给应用程序:
优点:简单易行;
缺点:主要在于驱动程序,由于在linux中需要遵循GPL协议,需要开源,而许多厂商的一些代码不希望开源。
而且像屏幕等设备可能需要多个app同时操作,这样的话将会导致各种各样的问题。
2.方法2——增加硬件抽象层
将驱动程序一分为二,一部分开源在内核中,一部分不开源在android框架中:
二、举例led android驱动:
从这里我们将看到整个应用框架层到底层驱动的走向。首先,无论是哪种方法,我们都需要实现一个linux驱动以供上层访问led资源。
同样也是通过jni来加载C库,从而通过调用open等来实现对硬件的操作。Android为了实现多个APP能操作同一个硬件,硬件不由app来直接操作,而是有SystemServer来操作。app需要把请求通过serviceManager发给SystemServer,由SystemServer最终完成对硬件的操作。
这里我们反过来思考一个app操作硬件的过程:
1、app需要申请服务和获得服务getservice。
而这个服务是有接口完成的。所以第一步我们需要建立一个aidl文件,来生成接口类。
frameworks/base/core/java/android/os/ILedService.aidl
同时修改 frameworks/base/Android.mk, 加入新建的aidl文件。
2、自动生成ILedService.java
mmm frameworks/base/
编译自动生成
out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/ILedService.java
ILedService.java文件获得了,现在就需要新建与之对应的java文件,实现java下的对硬件操作的函数。
3、创建 LedService.java 实现接口函数
创建完LedService.java后将其放到frameworks/base/services/core/java/com/android/server/中,其上层Android.mk会自动包含此java文件。
4、将服务注册到Service Manager当中
修改frameworks/base/services/java/com/android/server/SystemServer.java
这样的话,app就能获得服务,从而实现对SystemServer的通信,从而实现对硬件的操作。现在就是需要对SystemServer进行修改了。
SystemServer对硬件的操作也是jni,所以其也需要加载C/C++库。在Android系统中已经把所有对硬件操作的jni文件打包为一个.so库,所以我们需要做的是在so库中添加我们对硬件的支持。
5、实现com_android_server_LedService.cpp
将jni文件放到frameworks/base/services/core/jni/目录中。还要注册native接口,在frameworks/base/services/core/jni/onload.cpp中修改。
并修改Android.mk文件,加入com_android_server_LedService.cpp的编译。
这里其实已经差不多实现了对硬件的操作,因为我们实现了对cpp文件的调用并打包进系统,cpp文件就能直接加载C库,调用open等函数实现对硬件的操作。
但是这样的话有一个问题,就是如果驱动有点儿问题,我们就需要修改com_android_server_LedService.cpp,并重新编译系统、烧写系统。这样的话不是很方便。我们可以再引入硬件抽象层(HAL),这样更有利于搭建整个系统。