1.Android源码开发的C可执行源文件一般存在external目录下
2 Android的几层框架.
application
———————————————
java framework
java natice interface
native framework
hardware
—————————————————
driver
kernel
—————————————————–
3.硬件抽象层以模块来管理各个硬件访问接口
每个硬件模块都对应有一个动态链接库文件
每个硬件抽象层都使用 hw_module_t 来描述
硬件设备 使用 hw_device_t 来描述
4.硬件抽象层文件的命名规范
hardware/libhardware/hardware.c
hw_module_t 和hw_device_t 定义
hardware/libhardware/include/hardware/hardware.h 中
5.每一个硬件抽象层 在内核中都对应一个驱动程序
硬件抽象层就是通过这些驱动程序访问硬件设备的
通过读写设备文件来进行通信的
6.目录结构
hardware/libhardware
.
├── include
│ └── hardware //头文件的存放目录 存放的是xxx.h 文件
├── modules
│ ├── audio //具体模块的存放 xxx.cpp Android.mk
│ ├── audio_remote_submix
│ ├── camera
│ ├── consumerir
│ ├── fingerprint
│ ├── gralloc
│ ├── hwcomposer
│ ├── local_time
│ ├── nfc
│ ├── nfc-nci
│ ├── power
│ ├── sensors
│ │ └── tests
│ ├── soundtrigger
│ ├── tv_input
│ ├── usbaudio
│ └── vibrator
└── tests
xxx.h xxx.cpp是源代码文件
Android.mk是模块的编译脚步文件
需要注意的是:
这里的目录是android自带的目录,除此之外,还有一些厂商的目录,比如MTK,在vender目录下,他同样有一个 hardwar目录,
7. 每一个 模块都需要自定义一个模块结构体
以高通的lights 为例
定义模块ID
#define LIGHTS_HARDWARE_MODULE_ID “lights”
struct light_device_t {
struct hw_device_t common; //第一项必须为hw_device_t 这个结构
/**
* Set the provided lights to the provided values.
*
* Returns: 0 on succes, error code on failure.
*/
int (*set_light)(struct light_device_t* dev,
struct light_state_t const* state);
};
源文件
/hardware/qcom/display/liblight$
每一个硬件模块必须导出一个名称HAL_MODULE_INFO_SYM符号
他指向一个自定义的硬件抽象层模块结构体。
第一个类型为hw_module_t 的tag (必须为HARDWARE_MODULE_TAG )
8. 一个硬件抽象层可能包含多个硬件设备
而这些硬件设备的打开操作是由xxx_device_open来完成的。
9.编译脚本
编译完成后,存在 out/target/produce/gerneric/system/hw 下
名字xxx.default.so
10.mmm make snod
mmm 编译 snod 打包
11.可能存在的问题
open的时候,没有权限
解决方案:
通过uevent 机制
system/core/rootdir
ueventd.rc的配置文件
/dev/freg 0666 root root
更加简单的方法:
2.3 节 (Android系统源码情景分析)
12.在硬件抽象层模块之后,需要在应用程序框架层中实现一个硬件访问服务,
硬件访问服务:通过硬件抽象层模块开为应用程序提供硬件读写操作。
硬件抽象层模块使用 C++
Java Native Interface
硬件访问服务使用Java
13.硬件访问服务运行在系统进程system中,
使用硬件访问服务的应用程序运行在另外的进程中,
即应用程序通过进程间通信机制来访问这些硬件访问服务
binder 进程间通信机制
应用程序通过binder来访问运行在系统进程System中的硬件服务
binder进程间通信机制 要求提供服务的一方必须实现一个具有 跨进程访问能力的服务接口,以便使用服务的一方可以通过这个服务接口来访问它
binder 机制,在C。C++ java 都有相应的实现方法。对于java层,则可以使用下边的方法。
14.硬件访问服务接口
跨进程 访问能力的服务接口
AIDL (frameworks/base/core/java/andriod/os/xxx.aidl)
同时需要修改 frameworks/base 目录下的Android.mk
mmm ./frameworks/base 编译这个接口
aidl 定义的服务借口是用来进行进程间通信的。其中提供服务的进程成为server进程,
而使用服务的进程成为client进程。
不仅仅需要定义aidl,还需要实现server的具体功能,即下边的方法
15.硬件访问服务
frameworks/base/services/java/com/android/server
实现接口的成员函数
16.硬件访问服务的jni方法。 调用硬件抽象层模块
/frameworks/base/services/core/jni
命名com_android_server_xxx.cpp
实现java本地接口方法表
注册java本地接口方法
在onload.cpp中添加xxx函数的声明和调用
修改Android.mk
jni层
com_android_server_lights_LightsService.cpp (frameworks\frameworks\base\services\core\jni)
这是一个对于使用java编写的jni,通用的写法,除此之外还有C++的实现,典型代码Camera的框架,
17. 启动硬件访问服务
Android的硬件访问服务通常在系统进程system中启动,
系统进程system是由应用程序孵化器进程Zygote负责启动的。
zygote 在系统启动时启动。
–>把硬件访问服务运行在系统进程system 中就实现了开机时自动启动
添加到哪里?
frameworks/base/services/java/com/android/server/SystemServer.java
android5.1 和书有点不同
17.编写应用程序
kernel hal jni system binder 应用程序的进程
内核驱动
硬件抽象层模块使用 C++ 通信方法
Java Native Interface
硬件访问服务使用Java
硬件访问服务接口 访问接口