一、HAL层简介
Android HAL层(Hardware Abstraction Layer硬件抽象层)是一种Android系统的硬件驱动架构,它的主要作用是提供一个硬件抽象层次给其他上层的框架(比如Android Framework层,Java层,Native层等)来访问硬件。HAL层可以看做是硬件差异化的一个抽象,把所有不同平台、不同接口的硬件统一在一个接口下面并且对外提供一个相同的接口,这样应用就可以直接调用这个接口完成操作,而不用关心底层封装的细节。
HAL是一种基于C语言编写的Nativelib库,它暴露API常常以硬件的形式呈现,比如camera库、audioflinger库等。在Android系统启动时,各个硬件模块会通过HAL层加载,然后在系统整个生命周期中对应用程序的请求提供服务。在HAL层,硬件驱动程序会抽象为一个或多个模块,每个模块都有不同的作用,提供类似设备初始化、I/O访问等服务。
下面我们来介绍几个常见的HAL层API:
//camera的hal层API struct camera_module_t HAL_MODULE_INFO_SYM; struct camera_module_t { hw_module_t common; int (*get_number_of_cameras)(void); int (*get_camera_info)(int camera_id, struct camera_info *info); int (*set_callbacks)(const camera_module_callbacks_t *callbacks); void (*get_vendor_tag_ops)(vendor_tag_ops_t *ops); int (*open_legacy)(const struct hw_module_t* module, const char* id, uint32_t halVersion, struct hw_device_t** device); int (*set_torch_mode)(const char* camera_id, bool enabled); int (*init)(const struct camera_module_callbacks_t *callbacks); };
//audio的hal层API struct audio_module HAL_MODULE_INFO_SYM; struct audio_module { hw_module_t common; uint32_t (*get_supported_devices)(const struct audio_module *module); struct audio_device *(*get_device)(const struct audio_module *module, const char *name); int (*create_audio_patch)(const struct audio_module *module, unsigned int num_sources, const struct audio_port_config *sources, unsigned int num_sinks, const struct audio_port_config *sinks, audio_patch_handle_t *handle); int (*release_audio_patch)(const struct audio_module *module, audio_patch_handle_t handle); int (*get_audio_port)(const struct audio_module *module, struct audio_port *port); void (*set_audio_port_config)(const struct audio_module *module, const struct audio_port_config *config); };
二、HAL层开发流程
为了在Android系统中实现自己的硬件驱动,我们需要了解HAL层的开发流程,这个流程主要包括底层硬件驱动实现、HAL模块实现和HAL接口部署,下面我们分别来讲解:
- 底层硬件驱动实现:首先需要根据具体的硬件设备来编写对应的硬件驱动程序,这个过程一般使用C或C++来编写。硬件驱动编写好后,需要编译为动态库文件,一般是为.so或者 .dll文件格式。
- HAL模块实现:在HAL模块实现中,我们需要定义硬件相关的抽象数据结构和HAL API接口之间的关系,通常我们会定义一个.h文件来定义这些接口,同时提供相应的.h和.cpp实现文件,以实现这些接口函数的功能。
- HAL接口部署:在HAL接口部署中,我们需要将我们实现好的HAL模块部署到Android系统中,这里我们有两种方式来完成:第一种方式是直接将.so文件部署到$ANDROID_SYSTEM/lib/hw文件夹下;第二种方式是将.so文件和对应的.xml文件都打包成一个HAL module zip包,然后放到设备中的/system/vendor/,然后在设备重新启动时,HAL层的库文件会被自动加载。
三、HAL层开发注意点
在HAL层开发过程中,需要注意以下几点:
- 高效处理多线程操作:在HAL层中,多线程运行是一个常见的使用场景,需要注意多线程并发访问时的数据安全性。开发者需要注意锁的使用,例如在camera HAL中,CPU控制器和ISP控制器需要使用锁控制,以确保多线程操作能够正常协作运行。
- 对硬件操作进行一些扩展:在有一些一些特定的设备实现中,硬件的操作可能比较特殊,比如需要将多个寄存器写入一次操作中等。在HAL层中,需要增加对这些特定硬件的操作支持。
- 良好的适配性:对于HAL层开发,没有标准的开发规范,每个供应商的开发方式都大不相同,所以作为一个HAL开发人员,需要确保你的HAL代码是具有适配性的,兼容多种硬件设备,从而提供平台无关的代码。
- 使用好模板:在Android HAL中,开发者需要定义一些基本的数据结构和函数,这些结构和函数是很多HAL模块都有的,比如audio_hal_module_t和camera_module_t。HAL提供了一些模板代码,可以把这些需要自己实现的结构初始化工作用代码一次性完成,减轻开发者的工作量。
四、总结
本文介绍了Android HAL层的概念及开发流程,HAL层的重要性在于为其他上层框架提供硬件抽象,使得上层框架可以不用考虑如何访问底层硬件设备。同时本文还介绍了HAL层开发时需要注意的一些问题。新手开发人员可以使用HAL层为自己的硬件设备编写驱动程序,减轻了硬件驱动开发的负担。