android底层开发学习笔记八(hal层架构-1)

1、android层次
    app层
    framework层
    库 | runtime(DVM)层
    HAL层
    linux kernel层

2、hal是什么
    全称:harware abstraction layer,硬件抽象层,在库层和linux kernel层之间,包含很多模块和驱动层的模块一一对应。
    Andhoidl HAL层(即Hardware Abstraction Layer)是Google开发的Android系统里 上层应用操作底层硬件屏蔽的一个软件层次,屏蔽底层细节,为上层提供统一的接口。

3、为什么需要hal
    1). 并不是所有的硬件设备都有标准的Linux Kernel的接口;
    2). Kernel driver涉及到GPL的版权。某些设备制造商并不愿意公开硬件驱动,所以才用HAL方式绕过GPL(这是主要原因);
    3). 针对某些硬件,Android有一些特殊的需求

4、hal怎么实现
    1)存在形式:以.so库文件的形式存在
    2)旧框架module
        定义:旧的HAL 架构(libhardware_legacy)作法,是传统的「module」方式,也就是将*.so 文件当做「shared library」来使用,在runtime(JNI 部份)以 direct function call (直接调用)使用 HALmodule,即通过直接函数调用的方式,来操作驱动程序。应用程序直接加载 *.so库(dlopen)的做法,调用 *.so里的符号(symbol),也是一种方式(即c库的so和hal层的so打包成一个so库文件)。总而言之是没有经过封装,上层可以直接操作硬件。
        弊端:直接调用的方法,是将hal层.so库文件映射到app进程中,如果同时有多个app同时调用这个库,会出现代码重入现象,有两个进程同时操作硬件,导致硬件状态不确定,因此谷歌实现了一个代理人机制(让app访问硬件抽象层模块的代理人,而不是直接访问硬件抽象层的模块),引出hal层新框架

    3)新框架module stub
        a.新的hal架构介绍(stub代理人):
            hal stub 是一种代理人(proxy)的概念,stub 虽然仍是以*. so的形式存在,但HAL 已经将*.so 隐藏起来了(hal 层的方法封装到 stub结构体中,不能直接访问,而是通过stub结构体和它的操作接口访问)。Stub向HAL「提供」操作函数(operations),而runtime 则是向 HAL 取得特定模块(stub)的 operations,再 callback这些操作函数。这种以 indirect function call 的架构,让HAL stub 变成是一种「包含」关系,即HAL里包含了许许多多的 stub(代理人)。Runtime 只要说明「类型」,即module ID,就可以取得操作函数。对于目前的HAL,可以认为Android定义了HAL层结构框架,通过几个接口访问硬件从而统一了调用方式。

        b.新hal层架构stub的必备元素
           分析: 一个硬件模块,在hal层中都有一个对应的stub,c库要找到对应的stub,并且通过stub来调用硬件操作方法。
           必备元素:hal用一个结构体描述stub,这个结构体要包含一个唯一ID,这样c库就可以通过此ID找到stub,还要包含这个stub要实现的方法供c库调用。
            获取stub module的函数:hw_get_module(id),通过id可以获取到一个hw_module_t(stub)

         c.代码架构
                1、struct  hw_module_t 结构体,关键成员如下
                    / ** Identifier of module */   const char *id;
                    / ** Modules methods */       struct hw_module_methods_t* methods;

                 2、struct hw_module_methods_t结构体,只有一个open函数成员,那么操作硬件的其他方法(ioctl, read, wirte)要怎么向上c库层提供?
                    typedef struct hw_module_methods_t   {
                        / ** Open a specific device */
                        int (*open) (const struct hw_module_t* module, const char* id,  struct hw_device_t ** device);}注意第三个参数hw_device_t ,是返回给c库层的结构体,因此可以将其他函数通过此结构体返回给c库层。

                3、struct hw_device_t ** device结构体
                     1)结构体成员
                        uint32_t version;
                        struct hw_module_t* module;
                        int (*close) (struct hw device t* device);

                    2)这个结构体没有ioctl, read, wirte这些函数成员,因此需要自定义一个结构体struct led_device_t,封装这些函数,同时第一个成员包含struct hw_device_t (继承struct hw_device_t ),这样可以通过返回给上层c库的struct hw_device_t 地址访问自定义的结构体led_device_t(struct hw_device_t 指针强转成led_device_t指针,结构体第一个变量的地址就是结构体的地址),进而调用led_device_t中的ioctl, read, wirte函数。

以上是hal层架构所需要实现的结构体以及操作方法介绍,具体hal层的代码实现下篇进行说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值