缩写:
HAL:HardwareAbstraction Layer,硬件抽象层
CTS:CompatibilityTest Suite,兼容性测试套件
Android让你能够自由实现设备规格和驱动,HAL提供一套标准方法来在Android平台栈(platform stack)和硬件之间创建软件钩子(hook),Android系统是开源的,你可以贡献自己的接口和增加功能。
为保证设备保持高质量和提供一直的用户体验,每个设备必须通过CTS测试。CTS确保设备满足质量标准,保证APP的可靠运行和好的用户体验。
在移植Android到你的硬件平台上,花些时间从一定高度来理解Android系统框架。因为你的驱动和HAL要和android交互,了解Android工作机制可以帮助你有效控制Android源代码树的多层代码。
图1
1. 应用框架层(Applicationframework)
应用框架层主要是应用程序开发人员经常使用,作为硬件开发者,你应该知道尽可能多的API,且要知道这些API和底层HAL接口的映射关系,这样可以提供关于实现驱动的有用信息。
2. IPC进程间通讯机制Binder(Binder IPC)
Binder机制允许应用框架层款过进程界限并访问Android系统服务代码,这可使高层的框架API和Android系统服务交互,在应用框架层,这种通讯对开发者隐藏并表现为事情就好像是顺其自然完成一样。
3. 系统服务(system services)
应用框架API提供的函数和系统服务通信以访问底层硬件,服务是模块化的,比如比较重要的Windows Manager窗口管理器、Serarch Service搜索服务或是Notification Manager通知管理器。Android包括两组服务:系统(比如Windows Manager和Notification Manager)和多媒体服务(如录制和播放媒体服务)
4. HAL硬件抽象层(Hardware Abstraction Layer)
HAL定义一组标准接口来让设备厂商去实现,允许Android不必知道底层驱动的实现。HAL允许你在不影响或是修改上层系统的前提下实现功能,HAL的实现被打包成为模块(.so文件)文件,并且在适当的时候被Android系统加载。
图2
你必须为产品的硬件实现相应的HAL(和驱动), HAL的实现典型的被编译成共享库模块(.so文件),Android没有要求在HAL实现和设备驱动之间是标准的交互,所以你可以基于自己的情况做最适合的事情。但是,为了保证Android系统能够和硬件正确交互,你必须遵守每个具有硬件特性的HAL接口协议。
5. 标准HAL结构体(Standare HAL structure)
每个特定硬件HAL接口都有其特性,由hardware/libhardware/include/hardware/hardware.h的结构体hw_module_t定义,这样可保证HAL有个可预见的结构。HAL接口允许Android系统一致性的加载你的HAL模块的正确版本。HAL接口由两个通用的组件组成:一个模块(module)和一个设备(device)。
5.1 模块(module)
模块打包了HAL的实现,这些实现作为一个共享库.so文件体现。它包含模块的version、name、author,这些成员帮助Android找到和加载模块,模块对应的结构体为hw_module_t,在hardware/libhardware/include/hardware/hardware.h定义,此结构体描述一个模块和包含比如模块版本、作者和名字。
除此之外,hw_module_t结构体还包含指向hw_module_methods_t结构体的指针methods,hw_module_methods_t结构体包含一个打开模块的函数指针open。这个open函数作为一个抽象服务发起和硬件的通信,每个具体的硬件HAL通常要扩展通用的hw_module_t结构体,增加附加信息来更好的描述具体的硬件。比如摄像头HAL,
typedefstruct camera_module { hw_module_t common; int (*get_number_of_cameras)(void);//扩展部分 int (*get_camera_info)(int camera_id,struct camera_info *info); //扩展部分 }camera_module_t;
当你实现一个HAL和创建模块结构体,你必须以HAL_MODULE_INFO_SYM来给name成员赋值,比如:
structaudio_module HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version =AUDIO_MODULE_API_VERSION_0_1, .hal_api_version =HARDWARE_HAL_API_VERSION, .id = AUDIO_HARDWARE_MODULE_ID, .name ="NVIDIA Tegra Audio HAL", .author = "The Android Open SourceProject", .methods = &hal_module_methods, }, };
5.2 设备(device)
设备抽象了产品实际的硬件,比如一个音频模块包含一个基本的音频设备、一个USB音频设备或一个蓝牙A2DP音频设备。一个设备由hw_device_t结构体描述,像模块一样,每种类型的设备可在hw_device_t结构体的基础上定义更多细节信息,比如指向硬件特征的函数指针,audio_hw_device_t就包含指向音频设备操作的函数指针get_supported_devices。
struct audio_hw_device { struct hw_device_t common; /** * used by audio flinger to enumerate what devices are supported by * each audio_hw_device implementation. * * Return value is a bitmask of 1 or more values of audio_devices_t */ uint32_t (*get_supported_devices)(const struct audio_hw_device *dev); ... }; typedef struct audio_hw_deviceaudio_hw_device_t;
除了这些标准的属性,每个具体硬件HALC接口可以定义多个硬件特有属性和需求
6. HAL模块
HAL的实现被编译成为模块(.so)文件和在Android合适的时候会动态链接它。你可以为你每个HAL实现创建Android.mk文件来编译你的模块并指向你的源代码文件。通常,你的共享库必须以某种格式命名,这样它们才可能被找到和加载。从模块到模块的命名方案略有不同,但是一般遵循下面的形式:<module_type>.<device_name>
非常重要,比如module_type可以是GPS,但如果采用不同的GPS外设,可以通过device_name来区分。
7. Linux内核
开发你的设备驱动类似于开发典型的linux设备驱动,Android使用一个版本的Linux内核,在此内核基础上增加了一些Android特有的内容,比如唤醒锁(wave lock,一个内存管理器系统更积极主动去保护内存)、Binder IPC驱动和其他针对移动嵌入式平台的重要特征,这些特征是系统主要功能和不影响驱动开发。
你可以使用任何支持所需要特诊的版本内核(比如binder驱动),但是,我们推荐采用最新的Android内核版本。
参考链接:
http://source.android.com/devices/index.html