Android HAL层hardware module的设计

Android应用程序访问linux驱动第二步:实现并测试hardware层 不管是出于什么样地考虑,android系统终究是提供了hardware层来封装了对Linux的驱动的访问,同时为上层提供了一个统一的硬件接口和硬件形态。一.Hardware概述在Hardware层中的一个模块中,主要设计一下三个结构: struct hw_module_t struct hw_module_methods_t struct hw_device_t 这三个结构体的关系是这样的:我们在 阅读详情

Android为了屏蔽硬件的复杂性,设计了一个HAL层,HardwareAbstarct Layer,即硬件抽象层。HAL层位于驱动和framework之间,为各个硬件厂家提供的形形色色的驱动模块规定了统一的接口。在Android里面,这些接口是用c语言描述的,而在c语言中,接口都是用函数指针来描述的。所以我们在这些接口模块中看到大量函数指针,下面的驱动去实现这些接口,并挂载到这些接口模块上。

这些接口模块本质上就是一些so库,采用动态加载的形式被framework层调用。Framwork层会在使用到某个功能时去尝试dlopen对应的so库,若这个库存在,调用它,若不存在,就认为系统不支持这个功能。完成查找这个硬件模块是否存在,以及去dlopen,dlsym该模块的初始化函数的那些逻辑放在libhardware.so中。那么,framework和hal的关系可以形象的表示为这样的模型:


Audio_interfaces中定义了HAL层的Audio模块(一些so库),比如

static const char * constaudio_interfaces[] = {

   AUDIO_HARDWARE_MODULE_ID_PRIMARY,

    AUDIO_HARDWARE_MODULE_ID_A2DP,

AUDIO_HARDWARE_MODULE_ID_USB,

}

AudioFlinger使用loadHwModule_l来加载audioInterfaces。实际是去加载HAL层得一些so库。用函数hw_get_module_by_class拿到module,然后用audio_hw_device_open拿到device。所有的HAL层的硬件module都是这么干的。这俩函数定义在libhardware.so中,在编译audioflinger.so时, 这个库是作为动态共享库参加链接的。

我们来看看具体过程:

static intload_audio_interface(const char *if_name, audio_hw_device_t **dev)
{
    const hw_module_t *mod;
    int rc;
 
    rc =hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
    ALOGE_IF(rc, "%s couldn't load audiohw module %s.%s (%s)", __func__,
                 AUDIO_HARDWARE_MODULE_ID,if_name, strerror(-rc));
    if (rc) {
        goto out;
    }
    rc = audio_hw_device_open(mod, dev);
    ALOGE_IF(rc, "%s couldn't open audiohw device in %s.%s (%s)", __func__,
                 AUDIO_HARDWARE_MODULE_ID,if_name, strerror(-rc));
    if (rc) {
        goto out;
    }
    if ((*dev)->common.version <AUDIO_DEVICE_API_VERSION_MIN) {
        ALOGE("%s wrong audio hw deviceversion %04x", __func__, (*dev)->common.version);
        rc = BAD_VALUE;
        goto out;
    }
    return 0;
 
out:
    *dev = NULL;
    return rc;
}

hw_get_module_by_class是在/hardware/libhardware/hardware.c中定义的,这个文件和libhardware/include/hardware/hardware.h一起定义了hal的接口。

有两个基本的结构体:

一个是hw_module_t,定义了模块的一些id,名称,作者等描述信息,

另一个是hw_device_t,没定义太多东西,但是它的继承结构体定义了一个模块对外需要暴露的接口

再看看继承这两个结构体的audio机子的结构体,定义在audio.h (hardware\libhardware\include\hardware),这里定义了:

struct audio_module {
    struct hw_module_t common;
};
 
struct audio_hw_device {
struct hw_device_t common;
。。。
}
struct audio_stream_out {
 
};
struct audio_stream {

};
 
struct audio_stream_in {
};


具体的HAL层模块通过继承这两个结构体来实现具体的业务功能。


然后调用dlopen打开so库,然后const char *sym =HAL_MODULE_INFO_SYM_AS_STR;

hmi = (struct hw_module_t *)dlsym(handle, sym);

而在hardware.h中

#defineHAL_MODULE_INFO_SYM_AS_STR "HMI"

所以是拿到名为HMI的符号

而在audio_hw.c的最后,定义了

struct audio_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 = "Default audio HWHAL",
        .author = "The Android Open SourceProject",
        .methods = &hal_module_methods,
    },
};

注意libhardware/include/hardware/audio.h中,定义了

struct audio_module {

    struct hw_module_t common;

};

可以认为audio_module是hw_module_t的子类。

回到load_audio_interface,这是通过hw_get_module_by_class拿到了hw_module_t

然后在调用audio_hw_device_open(mod,dev),本质上是调用module->methods->open拿到了hw_device_t的子类audio_hw_device_t。

typedef struct hw_device_t {
    uint32_t tag;
    uint32_t version;
    struct hw_module_t* module;
#ifdef __LP64__
    uint64_t reserved[12];
#else
    uint32_t reserved[12];
#endif
    int (*close)(struct hw_device_t* device);
} hw_device_t;
typedef struct audio_hw_deviceaudio_hw_device_t

而structaudio_hw_device {

    struct hw_device_t common;

uint32_t (*get_supported_devices)(const structaudio_hw_device *dev);

。。。。

}

这时就拿到了audio_hw_device_t,这个结构体全是各种函数指针,这些指针都已经在调用module->methods->open时已经赋值过了。

所以此时进程拿到了so的接口。而且具有很好的灵活性

而在Load module之后,会调用module的open函数,我们看看这个module是怎么定义的

static_t struct hw_module_methods_t hal_module_methods ={
    .open =adev_open,
};
 
struct audio_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 ="Manta audio HW HAL",
        .author ="The Android Open Source Project",
        .methods =&hal_module_methods,
    },
};

而open就是为audio_hw_device 赋值,而且还会赋值一些环境相关的结构体和变量,他们一起组成了audio_device.我们可以认为,audio_hw_device里的接口都是暴露给外面的接口。

struct audio_device {

    structaudio_hw_device hw_device;

。。。

}

就是一个继承了hw_device_t的audio_hw_device。


Android音频系统之AudioFlinger(二) 1.1.1 音频设备的管理 虽然AudioFlinger实体已经成功创建并初始化,但到目前为止它还是一块静态的内存空间,没有涉及到具体的工作。 从职能分布上来讲,AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备、某种Stream类型的音频对应什么设备等等。而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如何维护现有系统中的音频设备,以及多 阅读详情

相关推荐

Android AudioFlinger加载HAL层流程

一、前提Audio HAL层最终以.so的方式为Android所用,那这个.so的库如何被AudioFlinger所使用?二、Audio Hardware HAL加载(1)AudioFlingerAudioFlinger加载HAL层:static int load_audio_interface(const char *if_name, const hw_module_t **mod,

前行 6274

android中hw_get_module函数分析

这个函数的主要功能是根据模块ID寻找硬件模块动态链接库德地址,然后调用load去打开动态链接库并从中获取硬件模块结构体地址。具体的源码如下: 代码@/hardware/libhardware/hardware.c int hw_get_module(const char *id, const struct hw_module_t **module) 120 { 121   

LinuxEngineer的专栏 1588

Android系统HAL层开发,编译过程(hello)

在android2.3.1下进行HAL层的开发,先参照网上弄了个hello的demo,首先看下HAL层在android系统中的位置: 硬件驱动程序可以看做是在keinel层,HAL封装了硬件驱动,然后再经过JNI接口的封装才能给Java应用程序调用。 HAL层接口封装的具体流程如下: 1)在../Android-2.3.1/hardware/libhardware/include/...

疾风剑豪 3166

HAL 详解之 hardware 详解

  文章出处:http://blog.youkuaiyun.com/shift_wwx/article/details/54969612 请转载的朋友标明出处~~   前言: 《Android 系统HAL 简介》一文和《Android,在争议中逃离 Linux 内核的 GPL 约束》中对HAL 做了简单的简介,这一文中对HAL 进行详细的分析。     android HAL 主要框架来源于:...

私房菜 7639

Android源码中添加HAL模块实战

本文讲解如何在android源码中添加自己的HAL层代码,并在JNI中调用我们自己编写的HAL模块代码,在服务中调用JNI代码,最终在相机拍照时调用服务,验证JNI中调用的HAL模块代码功能是否正常。

Mekeater的博客 1254

RK3568平台开发系列讲解(HAL层篇)分析HAL module架构

Android硬件抽象层(HAL) JNI向上提供本地函数,向下加载HAL文件并调用HAL的函数。 HAL负责访问驱动程序执行硬件 实质:使用dlopen来加载动态库 hw_get_module(“led”) 1、模块名==&gt;文件名 2、加载 一. 在Android内核源代码工程中编写硬件驱动程序。 二. 在Android系统中增加C可执行程序来访问硬...

内核笔记 3598

Android硬件抽象层HAL总结

Android HAL概述 Android HAL(Hardware Abstract Layer)硬件抽象层,从字面意思可以看出是对硬件设备的抽象和封装,为Android在不同硬件设备提供统一的访问接口。HAL处于Android framework和Linux kernel driver之间,HAL存在的意义有以下2个方面: HAL屏蔽了不同硬件设备的差异,为Android提供了统一的访问硬件设备的接口。不同的硬件厂商遵循HAL标准来实现自己的硬件控制逻辑,但开发者不必关心不同硬件设备的差异,只需要按

转载和创作优秀的博客 2870

BUCK型DC/DC变换器的建模与仿真

BUCK型DC-DC变换器的建模与仿真摘要1 文献调研1.1 研究背景1.2 Buck电路的应用场合2 原理分析2.1 模型介绍2.2 模型分析2.3 频域和时域响应2.4 参数指标要求3 参数设计3.1 校正器选择3.2 校正器参数整定3.2.1 积分器3.2.2 一阶微分环节3.2.3 超前校正器3.3 改进4 结论与展望参考文献 摘要   目前工业自动化水平已成为衡量各行各业现代化水平的一个重要标志。如何对一个系统进行建模分析、补偿校正变得越来越重要。   本文选择BUCK型DC/DC变换器作为载体,

屠龙归来仍是少年 2万+

<Android HAL 之路> HAL 简介

HAL层概述 名称: HAL, Hardware Abstracting Layer,中文名字:硬件抽象层。 作用:对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。向上衔接Android Runtime和Framework,向下衔接驱动程序 产生原因:利益,竞争 Android代码结构中,HAL层的内容主要集中在Hardware目录中,结合之前讲解Ca...

weixin_33827590的博客 173

OpenPCDet安装及其3D检测算法实现

OpenPCDet及pointpillar复现

weixin_58207716的博客 1万+

雷达信号处理——恒虚警检测(CFAR)

上图展示的是同时在距离维和多普勒维进行恒虚警检测的原理,如果只是在距离维或多普勒维做CFAR,检测单元的左右两侧均有设定好数量的保护单元和参考单元。不同的CFAR检测器适用于不同的场景,CA-CFAR算法适用于均匀环境中的单目标或彼此相距较远的多目标环境,在邻近多目标环境会发生目标的遮蔽效应,在杂波边缘会发生杂波边缘效应。从图中也可以看到,根据阈值的选择不同,有不同的检测器,其中CA-CFAR是取的参考单元的均值,SO-CFAR取的是参考单元的最小值,而GO-CFAR是取的参考单元的最大值。

诚朴勇毅 3万+

【Android】HAL层浅析

一、HAL层的前世今生 二、HAL层的通用结构剖析 三、一个例子 四、击破Audio HAL Module 五、小的总结 一、HAL层的前世今生 HAL(Hardware Abstraction Layer),硬件抽象层。由于部分硬件厂商不想把自己的核心代码公开,如果把代码放在内核空间里就需要遵循GUN License,会损害厂家的利益。所以,Google为了响应厂家在A...

冇二哥的专栏 3万+

使用Open3D进行RGB-D图像点云处理

在本文中,我们将使用Open3D来处理RGB-D图像,提取点云并进行一些基本的操作。总结起来,本文介绍了如何使用Open3D库处理RGB-D图像并提取点云。我们展示了如何读取RGB-D图像,创建RGB-D图像和点云,并显示点云。除了显示点云,Open3D还提供了许多其他功能,如点云滤波、点云配准、表面重建等。在创建RGB-D图像时,我们需要指定深度图像的缩放因子和截断值,以及是否将RGB图像转换为强度图像。希望本文能够帮助您入门Open3D,并在处理RGB-D图像和点云数据时提供一些指导。

QfcaLinux的博客 445

AndroidQ 打通应用层到HAL层---(HAL模块实现)

从这篇文章开始准备研究应用层到HAL层的一整套流程,目标是写一个APP调用HAL的一个函数,在AOSP源码环境下进行开发,大概流程是: APP---->Framework service---->native----->HAL 什么是HAL HAL全称Hardware Abstract Layer,硬件抽象层,它向下屏蔽了硬件的实现细节,向上提供了抽象接口,HAL是底层硬件和上层...

qq_34211365的博客 1万+

基于STM32L4XX、HAL库的AD7768BSTZ 模数转换器ADC驱动程序设计

/ 默认SPI配置。// 读取通道数据命令。// 通过SYNC_IN引脚触发转换(如果使用)// 处理数据...// 或者通过SPI命令。// 初始化AD7768。// SPI1引脚配置。

zhusl6688的博客 461

构网型逆变器下垂控制与电流限幅策略研究:理论、仿真与代码实现

随着分布式发电和微电网技术的快速发展,构网型(Grid-Forming, GFM)逆变器因其能够自主建立电压和频率参考、支撑弱电网及孤岛运行而受到广泛关注。本文提出并实现了一种基于下垂控制的构网型逆变器控制策略,将逆变器等效为受控电压源,通过L型滤波器接入配电网。在公共耦合点(PCC)处实时测量三相电压和电流,计算有功和无功功率,进而采用P-w和Q-V下垂控制生成内部频率和电压幅值,合成三相参考电压。针对故障情况下过电流问题,设计了一种自适应电流限幅模块:当电流幅值超过设定上限时,动态降低电压参考系数k_s

huanghm88的专栏 155

Android HAL 层原理分析

Android HAL 简介 Android 系统硬件抽象层(Hardware Abstract Layer)运行在用户空间中,它向下屏蔽了硬件驱动的实现细节,向上提供了硬件访问的服务。通过 HAL 层,Android 系统分为两层来支持硬件设备,其中一层实现在用户空间,另外一层实现在内核空间中,它在 Android 系统框架中的位置如下图所示。传统的 Linux 系统则把对硬件的支持和管理全部...

ninver2007的专栏 2013

TI单芯片毫米波雷达1642代码走读(〇)——总纲

前言 近年来,自动驾驶行业发展如火如荼,雷达技术也逐渐从军工封闭圈走向了开放的市场。 毫米波雷达具有全天候探测能力,特别是在雨雪雾天气以及夜间都能可靠工作,并且探测距离相对其他车载传感器非常远,对运动目标非常敏感,价格还低廉,这些特性都使其成为自动驾驶感知层面不可或缺的一环。 现如今的雷达已经不仅仅局限于测距测速测角等传统的功能,雷达技术正在从感知走向认知、从宽带走向超宽带、从二维走向三维四维、从相控阵走向数字阵列、从单通道走向MIMO、从独立工作走向分布式协同、从分立组件走向射频数字一体化。MIMO

3万+

HAL层代码

之前实现好了linux底层的模拟自设备驱动freg和测试程序后,下面开始学习android下的硬件抽象层,hardware层,也叫HAL层。 主要的文件: hardware/libhardware/hardware.c hardware/libhardware/include/hardware/hardware.h Android的HAL层是Android系统对底层硬件操作屏蔽的一个中

xiaohuima_dong的专栏 1981

大模型系列——一文看懂“提示词” vs “提示词工程” vs “上下文工程”

本文区分了AI领域的三个关键概念:提示词(Prompt)、提示词工程(Prompt Engineering)和上下文工程(Context Engineering)。提示词是直接输入给AI模型的指令文本;提示词工程则是系统化设计、测试和优化提示词的过程;而上下文工程是为AI构建动态上下文,提供恰当信息和工具的科学与艺术。文章通过翻译案例展示了提示词工程的迭代过程,并说明上下文工程在AI Agent中的核心作用——动态收集和组织必要信息。最后强调普通人只需掌握提示词编写,开发AI应用才需深入提示词工程,构建智能

2401_84052244的博客 750

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

2.安卓访问驱动-hal层实现

文章目录1.hardware层概述1.1 主要数据结构1.2 上层访问驱动流程1.3 伪代码 在android系统中会提供hal层,即hardware层来封装对Linux的驱动访问,同时会为上层提供一个统一的硬件接口 1.hardware层概述 1.1 主要数据结构 在hal层,会有以下三个结构体 struct hw_module_t struct hw_module_methods_t struct hw_device_t 1.2 上层访问驱动流程 原文:参考Android应用程序访问linux驱动第

weixin_43824344的博客 1601

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

android hardware解析

HAL层的hardware module主要实现文件为: hardware/libhardware/hareware.c hardware/libhardware/include/hardware/hardware.h Hareware.c中的内容在此就不做解释,可自行学习。 hardware.c中三个重要的结构体: struct hw_module_t; //描述一个硬件模

大磊大的专栏 2738

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Android HAL hardware module分析 以GPS module为例

准备在QT210的android系统中实现GPS功能,程序已经写好了,也可以编译出gps.s5pc110.so的库,但是不知道上层怎么调用这个库,在GPS相关的Android.mk中也没有找到,很是纳闷。通过分析hardware module才知道是怎么回事,之前并没有详细的了解hardware module,现在简单的分析一下。 HAL层的hardware module主要实现

jeffade的专栏 863

Android HAL与Android Framwork层的开发与优化概述

HAL层是Android系统中至关重要的一部分,它使得Framework层能够以一种抽象的方式与硬件设备进行交互。HAL层的开发涉及到硬件特性的抽象和标准化,以便Android系统能够与各种硬件设备兼容。HAL模块的架构通常包括以下几个关键部分:下面是一个简化的示例,展示了如何为一个假设的LED硬件设备实现一个HAL模块。1. 定义硬件接口 (): 2. 实现HAL模块 (): 3. 编译HAL库:在Android系统的构建系统中,HAL模块会被编译成库文件。在设备的BoardConfig.mk文件中,可以

jakelihua 3593

Android Hal层开发简单demo

编译,执行命令mmm aosp/hardware/libhardware/module/demo/会生成一个demo.default.so在aosp/out/target/product/emulator_x86/system/lib/hw/下,将该so push进手机的system/lib/hw/里,等待后续加载。在aosp/frameworks/base/services/java/com/android/server/SystemServer里添加。至此完成Jni层编写。

qq_33907486的博客 1422
上一篇: Android多媒体:AudioTrack
下一篇: Android多媒体:OMX
我把葡萄酿成酒
博客等级 码龄12年 275粉丝 198原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值