您的位置:

Android HAL开发

一、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层为自己的硬件设备编写驱动程序,减轻了硬件驱动开发的负担。