Android HAL 层框架分析以及代码示例
发布日期:2021-05-07 13:27:16 浏览次数:19 分类:精选文章

本文共 3205 字,大约阅读时间需要 10 分钟。

Android系统的硬件抽象层(Hardware Abstract Layer, HAL)运行在用户空间中,它向下屏蔽硬件驱动模块的实现细节,向上提供硬件访问服务。通过硬件抽抽象层,Android系统分为两层来支持硬件设备,其中一层实现在用户空间(User Space),另外一层是内核空间(Kernel Space)。传统的Linux系统将对硬件的支持完全放在内核空间中,但由于Android系统遵循开源协议GPL,如果对硬件的支持逻辑全部放在内核空间中,厂商的商业机密将无法保护。因此,Android系统将硬件支持分为两层:内核驱动层负责底层硬件操作,而硬件抽象层模块则负责上层接口定义和操作逻辑,保护厂商的利益。

硬件抽象层概述

硬件抽象层模块(HAL Module)在Android系统中以动态链接库(.so文件)的形式存在。模块文件的命名规范为“<MODULE_ID>.variant.so”,其中<MODULE_ID>为模块ID,variant表示系统属性(如ro.hardware、ro.product.board等),具体取值由系统属性决定。系统属性ro.hardware的值通常来自/proc/cmdline或/proc/cpuinfo文件,而ro.product.board、ro.board.platform和ro.arch则来自/system/build.prop文件。

硬件抽抽象层模块结构体hw_module_t和设备结构体hw_device_t的定义位于文件hardware/libhardware/hardware.h中。模块结构体hw_module_t包含模块标识、版本信息、模块ID、模块名称、作者信息以及操作方法列表等成员变量。设备结构体hw_device_t则包含设备标识、设备版本、所属模块以及设备操作接口。

开发Android硬件驱动程序

为了便于描述,我们开发一个虚拟字符硬件设备fake register,它有一个4字节的寄存器,支持读写操作。驱动程序的实现基于Linux内核的字符设备模型,定义了文件操作接口。驱动程序的实现如下:

#include 
#include
...struct Freg_struct { struct mutex mutex; struct cdev freg_cdev; char val;};static struct kobject *freg_kobj;static ssize_t freg_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { struct Freg_struct *dev = container_of(kobj, struct Freg_struct, freg_cdev); mutex_lock(&dev->mutex); val = dev->val; mutex_unlock(&dev->mutex); return snprintf(buf, PAGE_SIZE, "%d\n", val);}...

测试程序如下:

#include 
#include
...int main() { int fd = open("/dev/freg", O_RDWR); if (fd == -1) { printf("Failed to open device\n"); return -1; } printf("Read original value:\n"); read(fd, &val, sizeof(val)); printf("%d\n"); val = 5; printf("Write value %d to /dev/freg\n", val); write(fd, &val, sizeof(val)); printf("Read the value again:\n"); read(fd, &val, sizeof(val)); printf("%d\n"); close(fd); return 0;}

开发Android硬件抽象层模块

硬件抽象层模块freg的实现包括三个文件:freg.h、freg.cpp和Android.mk。

  • freg.h 定义模块和设备接口:
  • #ifndef ANDROID_FREF_INTERFACE_H#include 
    ...#define FREG_HARDWARE_MODULE_ID "freg"#define FREG_HARDWARE_DEVICE_ID "freg"struct freg_module_t { struct hw_module_t common;};struct freg_device_t { struct hw_device_t common; int fd; int (*set_val)(struct freg_device_t *dev, int val); int (*get_val)(struct freg_device_t *dev, int *val);};#endif
    1. freg.cpp 实现模块接口:
    2. #include 
      #include
      ...static int freg_device_open(const struct hw_module_t *module, const char *id, struct hw_device_t **device) { struct freg_device_t *dev = malloc(sizeof(struct freg_device_t)); if (!dev) return -1; dev->common.tag = HARDWARE_DEVICE_TAG; dev->common.module = (struct hw_module_t *)module; dev->common.close = freg_device_close; dev->set_val = freg_set_val; dev->get_val = freg_get_val; if ((dev->fd = open("/dev/freg", O_RDWR)) == -1) { free(dev); return -1; } *device = (struct hw_device_t *)dev; return 0;}
      1. Android.mk 编译脚本:
      2. LOCAL_MODULE := freg.defaultLOCAL_SRC_FILES := freg.cpp...include $(BUILD_SHARED_LIBRARY)

        开发Android硬件访问服务

        硬件访问服务FregService通过JNI方法与硬件抽象层模块通信,定义服务接口并运行在系统进程中。服务接口定义在aidl文件中,实现服务类并注册到Service Manager。

        使用硬件访问服务

        应用程序通过Binder进程间通信机制访问硬件访问服务,调用JNI方法进行硬件操作。最终实现了完整的硬件访问流程,满足应用程序对硬件的读写需求。

    上一篇:RK3288 Android5.1 隐藏 蓝牙网络共享与移动网络设置项
    下一篇:RK3288 开 recover功能进入loader模式

    发表评论

    最新留言

    能坚持,总会有不一样的收获!
    [***.219.124.196]2025年04月01日 20时52分10秒