精华内容
下载资源
问答
  • 硬件抽象层

    千次阅读 2011-03-20 21:41:00
    硬件抽象层HAL  (Hardware Abstraction Layer )  硬件抽象层是位于操作系统内核与硬件电路之间的接口层,其目的在于将硬件抽象化。它隐藏了特定平台的硬件接口细节,为操作系统提供虚拟硬件平台...

     硬件抽象层 HAL

      (Hardware Abstraction Layer )

      硬件抽象层是位于操作系统内核与硬件电路之间的接口层,其目的在于将硬件抽象化。它隐藏了特定平台的硬件接口细节,为操作系统提供虚拟硬件平台,使其具有硬件无关性,可在多种平台上进行移植。 从软硬件测试的角度来看,软硬件的测试工作都可分别基于硬件抽象层来完成,使得软硬件测试工作的并行进行成为可能。

      硬件抽象层大概分为以下几点HAL:

      *上层软件

      *虚拟驱动,设置管理模块

      *内部通信SERVER

      *内部以太网

      *内部通信CLIENT

      *用户接入口

      硬件抽象层接口的定义和代码的设计具有一下特点:

      *硬件抽象层具有与硬件的密切相关性

      *硬件抽象层具有与操作系统无关性

      *接口定义的功能应包含硬件或系统所需硬件支持的所有功能

      *接口定义简单明了,太多接口函数会增加软件模拟的复杂性

      *具有可测性的接口设计有利于系统的软硬件测试和集成

      硬件抽象层对用户设备接口的功能模拟主要由虚拟驱动模块完成,包括数据包的收发及协议报文的预处理等工作,为上层协议软件提供标准的API函数, 而对用户设备的接口管理则由上层网络管理软件通地设备管理模块对其进行管理配置及监控,内部通信模块运行于内部队以太网络,协调各模块之间的功能接口,保证从处理单元与主处理单元之间实时可靠的数据传输.

    展开全文
  • Android硬件抽象层(HAL)

    千次下载 热门讨论 2013-10-23 10:02:46
    Android硬件抽象层从开发到使用有一个清晰的层次。这个层次恰好对应了Android系统的架构层次,它向下涉及到Linux内核,向上涉及到应用程序框架层的服务,以及应用程序层对它的使用。Android硬件抽象层模块的开发本身...
  • android overlay系统 overlay的硬件抽象层 camera系统与上层接口和硬件抽象层
  • Android硬件抽象层(HAL)概要介绍和学习计划

    万次阅读 多人点赞 2011-06-25 13:03:00
    Android的硬件抽象层,简单来说,就是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。也就是说,把对硬件的支持分成了两层,一层放在用户空间(User Space),一层放在内核空间(Kernel Space),...

          Android的硬件抽象层,简单来说,就是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。也就是说,把对硬件的支持分成了两层,一层放在用户空间(User Space),一层放在内核空间(Kernel Space),其中,硬件抽象层运行在用户空间,而Linux内核驱动程序运行在内核空间。为什么要这样安排呢?把硬件抽象层和内核驱动整合在一起放在内核空间不可行吗?从技术实现的角度来看,是可以的,然而从商业的角度来看,把对硬件的支持逻辑都放在内核空间,可能会损害厂家的利益。我们知道,Linux内核源代码版权遵循GNU License,而Android源代码版权遵循Apache License,前者在发布产品时,必须公布源代码,而后者无须发布源代码。如果把对硬件支持的所有代码都放在Linux驱动层,那就意味着发布时要公开驱动程序的源代码,而公开源代码就意味着把硬件的相关参数和实现都公开了,在手机市场竞争激烈的今天,这对厂家来说,损害是非常大的。因此,Android才会想到把对硬件的支持分成硬件抽象层和内核驱动层,内核驱动层只提供简单的访问硬件逻辑,例如读写硬件寄存器的通道,至于从硬件中读到了什么值或者写了什么值到硬件中的逻辑,都放在硬件抽象层中去了,这样就可以把商业秘密隐藏起来了。也正是由于这个分层的原因,Android被踢出了Linux内核主线代码树中。大家想想,Android放在内核空间的驱动程序对硬件的支持是不完整的,把Linux内核移植到别的机器上去时,由于缺乏硬件抽象层的支持,硬件就完全不能用了,这也是为什么说Android是开放系统而不是开源系统的原因。

    《Android系统源代码情景分析》一书正在进击的程序员网(http://0xcc0xcd.com)中连载,点击进入!

         撇开这些争论,学习Android硬件抽象层,对理解整个Android整个系统,都是极其有用的,因为它从下到上涉及到了Android系统的硬件驱动层、硬件抽象层、运行时库和应用程序框架层等等,下面这个图阐述了硬件抽象层在Android系统中的位置,以及它和其它层的关系:

         在学习Android硬件抽象层的过程中,我们将会学习如何在内核空间编写硬件驱动程序、如何在硬件抽象层中添加接口支持访问硬件、如何在系统启动时提供硬件访问服务以及 如何编写JNI使得可以通过Java接口来访问硬件,而作为中间的一个小插曲,我们还将学习一下如何在Android系统中添加一个C可执行程序来访问硬件驱动程序。由于这是一个系统的学习过程,笔者将分成六篇文章来描述每一个学习过程,包括:

         一. 在Android内核源代码工程中编写硬件驱动程序

         二. 在Android系统中增加C可执行程序来访问硬件驱动程序

         三. 在Android硬件抽象层增加接口模块访问硬件驱动程序

         四. 在Android系统中编写JNI方法在应用程序框架层提供Java接口访问硬件

         五. 在Android系统的应用程序框架层增加硬件服务接口

         六. 在Android系统中编写APP通过应用程序框架层访问硬件服务

         学习完这六篇文章,相信大家对Android系统就会有一个更深刻的认识了,敬请关注。

    老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!

    展开全文
  • 本文主要介绍嵌入式操作系统的通用硬件抽象层设计。
  • 硬件抽象层(Hardware Abstraction Layer,HAL)的引入可有效解决这一问题。HAL是将硬件平台与应用软件隔离开来的软件层次,通过硬件抽象技术实现硬件相关和硬件无关两部分程序代码的隔离,为应用软件提供一个没有...
  • 本文主要介绍在Android 的硬件抽象层,学习Android 硬件抽象层(HAL)对理解整个Android都是有非常大的作用,有兴趣的小伙伴可以参考下
  • SYSBIOS系统开发入门-6-硬件抽象层-硬件中断 定时器.rar SYSBIOS系统开发入门-6-硬件抽象层-硬件中断 定时器.rar
  • Android GPS HAL driver porting 笔记,详细的描述了Android GPS 硬件抽象层的基本架构
  • 硬件抽象层的原理与实现;硬件抽象层的原理与实现;硬件抽象层的原理与实现
  • 论文在对软件通信体系结构专用硬件补充规范中的硬件抽象层连通性HAL-C内容进行了深入研究的基础上,提出了一种基于软件通信体系结构的DSP硬件抽象层连通性的实现方法。实践证明,该方法符合软件通信体系结构的硬件...
  • HAL 硬件抽象层

    千次阅读 2019-03-07 21:45:33
    通过硬件抽象层,andriod系统通过如下两层来支持硬件设备备。 1. 第一层 在用户空间实现。 2.第二层 在内核空间实现。 andriod 系统中,推出HAL为了保护硬件提供商的知识产权,为了避开Linux的GPL束搏。将控制硬件...

    HAL 层是位于操作系统内核与硬件电路之间的接口层。硬件抽象化。隐藏了特定平台的硬件接口细节。

    HAL能够向下屏蔽硬件驱动模块的实现细节。向上提供硬件访问服务。通过硬件抽象层,andriod系统通过如下两层来支持硬件设备备。

    1. 第一层 在用户空间实现。
    2.第二层 在内核空间实现。

    andriod 系统中,推出HAL为了保护硬件提供商的知识产权,为了避开Linux的GPL束搏。将控制硬件的动作放到了andtriod HAL中,而Linux driver仅负责简单的交互作用。甚至将硬件寄存器空间直接映射到用户空间。基于apache  的license ,因此硬件厂商可以只提供二进制代码。

    andriod 对硬件分两层来实现原因

    1.Linux内核代码是遵循GPL1协议,在Linux中添加或者修改了代码,就必须公开。若andriod 系统使用的linux 系统一样。把对硬件的支持完全实现在硬件驱动模块中,那必须公开代码,损害了硬件厂商利益。

    2.如果对硬件的支持完全在andriod系统用户空间中,这无法做到,因为只有内核空间才有特权操作硬件设备。因此这种方案就是分层实现。内核空间是硬件驱动模块的形式来支持,提供简单的硬件访问通道。用户空间以硬件抽象层模块的形式提供支持。

    设备驱动分为内核空间和用户空间两部分:

    • 内核空间主要负责硬件访问逻辑(GPL)
    • 用户空间主要负责参数和访问流程控制(Apache License)

     

    Android硬件驱动程序开发:与传统的Linux硬件驱动程序开发是一样的
    Android硬件驱动程序验证
    Android硬件抽象层模块开发

    Android硬件访问服务开发

    HAL层的通用结构剖析

    1. 通用的321架构 
      HAL层的主要框架是由三个结构体,两个常量,一个函数构成,所有的硬件抽象模块都是必须遵循321架构,在此基础上扩展自有的功能。 
    2. 三个结构体
      //文件位置:hardware/libhardware/include/hardware/hardware.h
      /**
       * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
       * and the fields of this data structure must begin with hw_module_t
       * followed by module specific information.
       */
      typedef struct hw_module_t {
          /** tag must be initialized to HARDWARE_MODULE_TAG */
          uint32_t tag;
      ......
      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_module_methods_t;

      /**
       * Every device data structure must begin with hw_device_t
       * followed by module specific public methods and attributes.
       */
      typedef struct hw_device_t {
          /** tag must be initialized to HARDWARE_DEVICE_TAG */
          uint32_t tag;
      ......
      hw_module_methods_t是封装在hw_module_t里的,里面提供的一个open方法需要具体的实现模块去重载;hw_module_t里面有很多关于模块的信息需要在初始化的时候去填充,非常关键的一个就是重载hw_module_methods_t中的open函数;hw_device_t里主要是和硬件设备相关的一些操作,各硬件模块需要继承该结构体。 
      - 两个常量和一个函数

    3. //文件位置:hardware/libhardware/include/hardware/hardware.h
      /**
       * Name of the hal_module_info
       */
      #define HAL_MODULE_INFO_SYM HMI

      /**
       * Name of the hal_module_info as a string
       */
      #define HAL_MODULE_INFO_SYM_AS_STR "HMI"

      /**
       * Get the module info associated with a module by id.
       *
       * @return: 0 == success, <0 == error and *module == NULL
       */
      int hw_get_module(const char *id, const struct hw_module_t **module);

      HAL_MODULE_INFO_SYM和HAL_MODULE_INFO_SYM_AS_STR与HAL的模块入口有关,在上层调用hw_get_module时,通过模块ID和对应的HMI(通过dlopen/dlsym进行映射)结构体找到模块入口,然后通过之前重载的open函数,就可以获得设备的操作接口(hw_device_t),之后就可以通过module访问模块实现的相关函数

      三、一个例子
      编程的学习从HelloWorld开始,那嵌入式应该就是从点灯开始。 
      下面我们就先从一个简单的LED模块的例子,来全面的的理解下HAL的基础框架。 
       
      在前面提到了三个结构体,各实现模块需要去继承并客制化自己的操作接口。我们可以从图中看到LED模块遵循该准则,其中hw_module_methods_t是封装在hw_module_t里的,具体的关系图如下: 

    展开全文
  • 系统软件模块与硬件之间的接口是嵌入式实时系统的主要特征,是系统设计过程中的必需环节,也是影响嵌入式系统应用前景的关键问题之一。硬件抽象层(Hardware Abstraction Layer,HAL)的引入可有效解决这一问题。
  • SCA规范下FPGA的硬件抽象层设计.pdf
  • 基于RapidIO的FPGA硬件抽象层设计.pdf
  • android HAL 硬件抽象层

    2019-02-28 16:34:14
    1. 开发 Android 硬件抽象层 1.1 HAL 层模块编写规范 Android 系统的硬件抽象层以模块的形式来管理各个硬件访问接口。每一个硬件模块都对应有一个动态链接库文件。 在系统内部,每一个硬件抽象层模块都使用结构体 hw...

    1. 开发 Android 硬件抽象层

    1.1 HAL 层模块编写规范

    Android 系统的硬件抽象层以模块的形式来管理各个硬件访问接口。每一个硬件模块都对应有一个动态链接库文件。

    在系统内部,每一个硬件抽象层模块都使用结构体 hw_moudle_t 描述,而硬件设备则使用结构体 hw_device_t 来描述。下面分别描述硬件抽象层模块文件的命令规范以及结构体 hw_moudle_t 和 hw_device_t 的含义。

    1.1.1 硬件抽象层模块编写规范

    硬件抽象层的模块文件的命令规范定义在 hardware/libhardware/hardware.c 文件中

    /**
     * There are a set of variant filename for modules. The form of the filename
     * is "<MODULE_ID>.variant.so" so for the led module the Dream variants 
     * of base "ro.product.board", "ro.board.platform" and "ro.arch" would be:
     *
     * led.trout.so
     * led.msm7k.so
     * led.ARMV6.so
     * led.default.so
     */
    
    static const char *variant_keys[] = {
        "ro.hardware",  /* This goes first so that it can pick up a different
                           file on the emulator. */
        "ro.product.board",
        "ro.board.platform",
        "ro.arch"
    };
    
    • 硬件抽象层模块文件的命令规范:<MOUDLE_ID>.variant.so
      • MOUDLE_ID 表示模块的ID
      • variant 表示variant_keys四个系统属性值的其中一个,顺序依次
      • variant 如果四个属性值都不存在,则将 variant 的值设为 default

    variant变量取值过程:

    ro.hardware: /prop/cpuinfo 的 Hardware 字段

    其他三个在:/system/build.prop 中查找

    1.1.2 硬件抽象层模块结构体定义规范

    结构体 hw_device_t 和 hw_moudle_t 及其它相关结构体定义在文件 hardware/hardware.h 中

    /**
     * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
     * and the fields of this data structure must begin with hw_module_t
     * followed by module specific information.
     */
    typedef struct hw_module_t {
        /** tag must be initialized to HARDWARE_MODULE_TAG */
        uint32_t tag;
    
        uint16_t module_api_version;
        
        uint16_t hal_api_version;
    #define version_minor hal_api_version
    
        /** Identifier of module */
        const char *id;
    
        /** Name of this module */
        const char *name;
    
        /** Author/owner/implementor of the module */
        const char *author;
    
        /** Modules methods */
        struct hw_module_methods_t* methods;
    
        /** module's dso */
        void* dso;
    
    #ifdef __LP64__
        uint64_t reserved[32-7];
    #else
        /** padding to 128 bytes, reserved for future use */
        uint32_t reserved[32-7];
    #endif
    }
    
    1. 硬件抽象层中的每一个模块都必须自定义一个硬件抽象层模块结构体,而且它的第一个成员变量的类型必须是 hw_moudle_t
    2. 硬件抽象层的每一个模块都必须存在一个导出符号 HAL_MODULE_INFO_SYM,它指向一个自定义的硬件抽象层模块结构体。
    3. 结构体 hw_moudle_t 的成员变量 tag 值必须设置为 HARDWARE_MODULE_TAG,用来标识这是一个硬件抽象层模块结构体
    4. 结构体 hw_moudle_t 的成员变量 dso 用来保存加载硬件设备层模块后得到的句柄值。我们知道每一个硬件抽象层模块都对应有一个动态链接库文件。加载硬件抽象层模块的过程实际上就是调用 dlopen 函数来加载与其对应的动态链接库文件的过程。在调用 dlclose 函数来卸载这个硬件抽象层模块时,需要用到这个句柄值。
    5. hw_module_methods_t 变量定义了硬件抽象层模块的操作方法列表。
    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_module_methods_t;
    
    1. 结构体 hw_device_t 用来描述一个已经打开的硬件设备。
    typedef struct hw_device_t {
        /** tag must be initialized to HARDWARE_DEVICE_TAG */
        uint32_t tag;
    
        uint32_t version;
    
        /** reference to the module this device belongs to */
        struct hw_module_t* module;
    
        /** padding reserved for future use */
    #ifdef __LP64__
        uint64_t reserved[12];
    #else
        uint32_t reserved[12];
    #endif
    
        /** Close this device */
        int (*close)(struct hw_device_t* device);
    
    } hw_device_t;
    
    ###################################
    (1) 硬件抽象层模块中的每一个硬件设备必须自定义一个硬件设备结构体
        而且它的第一个成员变量的类型必须为 hw_device_t
    (2) 结构体 hw_device_t 的成员变量 tag 的值必须设置为 HARDWARE_DEVICE_TAG
        用来标识这是一个硬件抽象层中的硬件设备结构体
    (3) close 是一个函数指针,用来关闭一个硬件设备
    

    1.2 编写硬件抽象层模块接口

    每一个硬件抽象层模块在内核中都对应一个驱动程序,硬件抽象层模块就是通过这些驱动程序来访问硬件设备的,他们通过读写设备文件来进行通信

    硬件抽象层的模块接口源文件一般保存在 harware/libhardware 中,以 freg模块 寄存器操作为例,进行说明,它的目录结构如下:

    ~ Android/hardware/libhardware
    ---- include
        ----- hardware
            ---- freg.h
            
    ---- moudles
        ---- power
            ---- freg.c
            ---- Android.mk
    

    其中 freg.h 和 freg.c 是源文件,Android.mk 是模块的编译脚本文件

    —> frag.h

    #ifndef ANDROID_INCLUDE_HARDWARE_FRAG_H
    #define ANDROID_INCLUDE_HARDWARE_FRAG_H
    
    #include <hardware/hardware.h>
    
    __BEGIN_DECLS
    
    // 硬件模块ID
    #define FRAG_HARDWARE_MODULE_ID "freg"
    
    // 硬件设备ID
    #define FRAG_HARDWARE_DEVICE_ID "freg"
    
    // 自定义硬件模块结构体
    typedef struct freg_moudle_t {
        struct hw_module_t common;
    }
    
    // 自定义设备结构体
    typedef 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);
    }
    
    __END_DECLS
    
    #endif  // ANDROID_INCLUDE_HARDWARE_FRAG_H
    

    这个文件中的常量结构体都是按照硬件抽象层模块编写规范来定义的。

    1. 宏 FRAG_HARDWARE_MODULE_ID 描述模块ID
    2. 宏 FRAG_HARDWARE_DEVICE_ID 描述设备ID
    3. 结构体 freg_moudle_t 描述自定义的模块结构体
    4. 结构体 freg_device_t 描述虚拟硬件设备,其中 fd 用来描述打开的文件设备 /dev/frag,成员变量 set_val 和 get_val 是函数指针,用来写和读虚拟硬件设备freg的寄存器地址。

    —> frag.c

    ...
    #define DEVICE_NAME "/dev/frag"
    #define DMOUDLE_NAME "frag"
    #define MOUDLE_AUTHOR "kevin"
    
    /* 设备打开与关闭接口 */
    static int freg_device_open(const struct hw_moudle_t* moudle, const char* id, struct hw_device_t** device);
    static int freg_device_open( struct hw_device_t** device);
    
    /* 设备寄存器读写接口 */
    static int freg_get_val(struct freg_device_t* dev, int* val);
    static int freg_set_val(struct freg_device_t* dev, int val);
    
    /* 定义模块操作方法结构体变量  */
    static struct hw_moudle_methonds_t freg_moudle_methods = {
        open: freg_device_open
    }
    
    /* 定义模块结构体变量 */
    struct freg_module_t HAL_MODULE_INFO_SYM = {
        .common = {
            .tag = HARDWARE_MODULE_TAG,
            .module_api_version = 1,
            .hal_api_version = 1,
            .id = POWER_HARDWARE_MODULE_ID,
            .name = MOUDLE_NAME,
            .author = MOUDLE_AUTHOR,
            .methods = &freg_moudle_methods,
        },
    
        .init = power_init,
        .setInteractive = power_set_interactive,
        .powerHint = power_hint,
    };
    ...
    

    在这段代码中,最值得关注的是模块变量 HAL_MODULE_INFO_SYM 的定义,按照硬件抽象层模块编写规范,每一个硬件抽象层模块必须导出一个名称为 HAL_MODULE_INFO_SYM 的符号,它指向一个自定义的硬件抽象层模块结构体。

    —> Android.mk

    1. LOCAL_PATH := $(call my-dir)
    2. include $(CLEAR_VARS)
    3. LOCAL_MODULE_TAGS := optional
    4. LOCAL_PROPRIETARY_MODULE := true
    5. LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
    6. LOCAL_SHARED_LIBRARIES := liblog
    7. LOCAL_SRC_FILES := freg.cpp
    8. LOCAL_MODULE := freg.default
    9. include $(BUILD_SHARED_LIBRARY)
    
    1. 这是硬件抽象层的编译脚本文件,第九行指定将模块编译成一个动态链接库文件
    2. LOCAL_MODULE_PATH 指定了库保存的路径(8.1: /vendor/lib/hw)
    3. 将硬件抽象层模块 freg 对应的文件命令为 freg.default,编译成功后在指定的位置成功 freg.default.so,当我们要加载 freg 抽象层模块 freg 时,只需要指定它的ID值,就能找到对应的 so 文件

    1.3 硬件抽象层模块的加载过程

    在 Android 硬件抽象层,负责加载硬件抽象模块的函数时 hw_get_moudle,它的原型如下:

    # Android/hardware/libhardware/include/hardware/hardware.h
    
    /**
     * Get the module info associated with a module by id.
     *
     * @return: 0 == success, <0 == error and *module == NULL
     */
    int hw_get_module(const char *id, const struct hw_module_t **module);
    
    ===================================================
    id:输入参数,表示要加载的硬件抽象层模块ID
    moudle:输出参数,如果加载成功,它指向一个自定义的硬件抽象层模块结构体
    
    函数返回值等于0代表加载成功,小于0则表示加载失败
    

    简单阐述一下 hw_get_module 的实现过程,代码在 hardware.c 中

    1. 从 variant_keys 中查找对应注册的模块,获取动态链接库路径
    2. 调用 dlopen 函数将动态连接库加载到内存中,成功则返回 handler 句柄
    3. 使用 dlsym 函数获取名称为 HAL_MODULE_INFO_SYM_AS_STR 的符号,这个 HAL_MODULE_INFO_SYM_AS_STR 符号指向一个自定义的抽象层模块结构体,它包含了模块的所有信息。
    4. HAL_MODULE_INFO_SYM_AS_STR 自定义抽象层模块结构体的第一个成员变量为 hw_moudle_t,将 hw_moudle_t.id 与所要加载的模块ID做比较,返回结果

    2. Android上层访问硬件抽象层

    应用层使用 JNI 访问硬件模块接口

    因为上层应用框架使用java语言开发,而硬件抽象层是使用C++语言进行开发,所以必须通过Java本地接口(JNI)来调用硬件抽象层模块的接口

    应用层使用 binder进程间通信机制 实现跨进程通信

    Android 系统的硬件访问服务通常运行在系统进程 System 中,应用程序所在的进程要想访问硬件访问服务就需要通过一种进程间通信机制。

    Android 提供了一种高效的进程间通信机制 —— Binder进程间通信,应用程序通过它来访问运行在系统进程System中的硬件访问服务。因此实现硬件硬件访问服务之前,首先要定义它的服务接口。

    从应用层往下分析,以PoweManager为例:

    1. PoweManager.java

    该文件中为用户提供了很多关于电源管理方法的操作,这些操作都是通过 Android Binder 进程间通信实现,简单来说就是通过 PowerManagerService 服务提供的接口来实现的

    // mService = IPowerManager.Stub.asInterface("---");
    final IPowerManager mService;
    
    
    public boolean isInteractive() {
        try {
            return mService.isInteractive();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
    
    ===========================================
    - 1. mService 是PoweManagerService服务的Binder代理对象
    - 2. 使用 IPowerManager.Stub.asInterface 获取电源管理服务的 Binder 代理对象
    - 3. 使用 mService 代理对象进行电源管理相关的操作,所以使用远程电源管理服务提供的接口
    
    2. IPowerMnager.aidl

    该文件定义了电源硬件访问的服务接口

    Android 接口定义语言(AIDL)是 Android 系统提供的一种描述语言来定义具体跨进程访问能力的服务接口。在编译时,ADIL文件会被转换成 java 语言,这个转换 java 语言中就包含 Binder 本地对象类 Stub,它实现了 IPowerManager 接口。

    前面说到服务接口是用来进程间通信的,提供服务的进程称为Service进程,而使用服务的进程称为 Client 进程(APP),在Service进程中,每一个服务都对应有一个本地 Binder 对象,它通过一个桩(Stub)来等待客户端连接。Client 客户端进程在访问服务之前,首先获取它的一个 Binder 代理对象(Proxy),然后通过这个代理对象接口访问服务接口。

    3. 应用层 java 服务接口实现文件 —— PowerManagerService.java

    前面的 AIDL 文件提供了服务接口,但是还没有一个具体的地方去实现这些接口,在 PowerManagerService.java 中从 IPowerManager.Stub 类继承下来,并且实现了这一些接口

    private final class BinderService extends IPowerManager.Stub {
        ...
    }
    
    4. 实现硬件访问服务接口 —— com_android_server_power_PowerManagerService.cpp
    #include <android/hardware/power/1.1/IPower.h>
    #include <hardware/power.h>
    
    // Check validity of current handle to the power HAL service, and call getService() if necessary.
    // The caller must be holding gPowerHalMutex.
    bool getPowerHal() {
        if (gPowerHalExists && gPowerHalV1_0 == nullptr) {
            gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService();
            if (gPowerHalV1_0 != nullptr) {
                gPowerHalV1_1 =  android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
                ALOGI("Loaded power HAL service");
            } else {
                ALOGI("Couldn't load power HAL service");
                gPowerHalExists = false;
            }
        }
        return gPowerHalV1_0 != nullptr;
    }
    
    int register_android_server_PowerManagerService(JNIEnv* env) {
        int res = jniRegisterNativeMethods(env, "com/android/server/power/PowerManagerService",
                gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
        (void) res;  // Faked use when LOG_NDEBUG.
        LOG_FATAL_IF(res < 0, "Unable to register native methods.");
    
        // Callbacks
    
        jclass clazz;
        FIND_CLASS(clazz, "com/android/server/power/PowerManagerService");
    
        GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivityFromNative, clazz,
                "userActivityFromNative", "(JII)V");
    
        // Initialize
        for (int i = 0; i <= USER_ACTIVITY_EVENT_LAST; i++) {
            gLastEventTime[i] = LLONG_MIN;
        }
        gPowerManagerServiceObj = NULL;
        return 0;
    }
    
    • getPowerHal 方法获取硬件抽象层的 hw_device_t 对象 gPowerHalV1_1
    • 获取到硬件设备 gPowerHalV1_1之后,使用这个对象访问硬件
    • register_android_server_PowerManagerService 方法中调用 jniRegisterNativeMethods 方法将所有实现的方法注册到Java虚拟机中
    5. onload.java —— 增加电源管理函数的声明和调用

    register_android_server_PowerManagerService 函数时上一小节中编写为了注册到 Java 虚拟机中去的。

    onload.cpp 文件实现在 libandroid_service 模块中,当系统加载 libandroid_service 模块时,就会调用 onload.cpp 中的 JNI_Load 函数,添加 native 方法的 Java 虚拟机注册

    extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
    {
        ...
        register_android_server_PowerManagerService(env);
        ...
    }
    
    6. SystemService.java —— 启动电源管理硬件访问服务

    前面说到,System 系统进程中会启动各种硬件访问服务,可以在该文件中添加电源模块服务的启动,这样系统一启动,服务就开启了

    private void startOtherServices() {
        ....
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
        ....
        
        private void startOtherServices() {
            ...
            try {
                // TODO: use boot phase
                mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
            } catch (Throwable e) {
                reportWtf("making Power Manager Service ready", e);
            }
            ...
        }
        
    }
    
    展开全文
  • 硬件抽象层HAL

    2017-06-01 11:16:27
    对Linux内核驱动程序的封装,向上...Android硬件抽象层:如何在内核空间编写硬件驱动程序、如何在硬件抽象层中添加接口支持访问硬件、如何在系统启动时提供硬件访问服务以及 如何编写JNI使得可以通过Java接口来访问硬件
  • 基于Android7.1 音频tinyalsa硬件抽象层动态库开发,具体参考https://blog.csdn.net/u010872301/article/details/89186283
  • 在Ubuntu Android简单介绍硬件抽象层(HAL)一文中,我们简要介绍了在Android系统为为硬件编写驱动程序的方法。简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中。接着Ubuntu ...
  • FPGA硬件抽象层的路由配置设计与实现
  • FPGA硬件抽象层的路由配置设计与实现.pdf
  • STM32硬件抽象层中DCMI驱动的研究.pdf
  • 硬件抽象层是一个处于硬件平台和嵌入式操作系统之间的软件层次。它的主要功能是对系统硬件进行初始化,为操作系统的硬件操作提供一系列接口函数。硬件抽象层提高了嵌入式操作系统的可移植性。本文基于LPC2292处理器...
  • 针对ACR接入方式的特点,讨论了硬件抽象层的实现方式及关键技术。 关键词:ACR(大规模接入汇聚路由器) 硬件抽象层 内部通信 虚拟驱动 目前,大多数路由器均采用分布式转发、集中式路由处理的体系结构[1]。该结构方式...
  • STM32硬件抽象层中DCMI驱动的研究
  • Android的硬件抽象层模块编写规范

    千次阅读 2015-08-24 14:04:57
    硬件抽象层模块编写规范 ​ Android系统的硬件抽象层以模块的形式来管理各个硬件访问接口.每一个硬件模块都对应有一个动态链接库文件.这些动态链接库文件的命令需要符合一定的规范.同时,在系统内部,每一个...
  • WindowsNT硬件抽象层HAL功能分析WindowsNT硬件抽象层HAL功能分析WindowsNT硬件抽象层HAL功能分析
  • 关于Android硬件抽象层

    2015-02-03 12:05:26
    1.为什么需要硬件抽象层硬件抽象层是把部分的驱动的工作放到用户态,这样做是因为Linux遵循GUN License 发布的时候需要公开源代码,而Android是遵循Apache License,无需公布源代码。显然如果把驱动/芯片相关的...
  • 高性能路由器硬件抽象层的关键技术研究.pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 127,153
精华内容 50,861
关键字:

硬件抽象层