硬件抽象层模块编写规范



Android系统的硬件抽象层以模块的形式来管理各个硬件訪问接口.每个硬件模块都相应有一个动态链接库文件.这些动态链接库文件的命令须要符合一定的规范.同一时候,在系统内部。每个硬件抽象层模块都使用结构体hw_module_t来描写叙述。而硬件设备则使用结构体hw_device_t来描写叙述.以下我们跟着老罗来学习描写叙述硬件抽象层模块文件的命名规范以及结构体hw_module_t和hw_device_t的定义.

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"
};

这段代码和凝视的意思是,硬件抽象层模块文件的命名规范为".variant.so",当中,MODULE_ID表示模块的ID,variant表示四个系统属性ro.hardware,ro.product.board。ro.board.platform。ro.arch 之中的一个.系统在载入硬件抽象层模块的时候,以此依照ro.hardware,ro.product.board,ro.board.platform。ro.arch的顺序来取他们的属性值.假设当中的一个属性存在。那么就把他的值作为variant的值。然后在检查相应的文件是否存在,假设存在。那么就找到要载入的硬件抽象层模块文件了.否则,就继续找下一个系统属性.假设这四个系统属性都不存在,或者相应这四个系统属性的硬件抽象层模块文件不存在。那么就使用”MODULE_ID.default.so”来作为要载入的硬件抽象层模块文件的名称.

系统属性ro.hardware是在系统启动时,由init进程负责设置.它首先会读取/proc/cmdline文件,检查里面有没有一个名称为androidboot.hardware的属性,假设有。就把他的值作为属性ro.hardware的值,否则,就将/proc/cpuinfo文件的内容读取出来,并且将里面的硬件信息解析出来,即将Hardware字段的内容作为属性ro.hardware的值.比如,在Android模拟器中,从/proc/cpuinfo文件读取出来的Hardware字段内容为goldfish,于是。init进程会将属性ro.hardware的值设置为”goldfish”.系统属性ro.product.board,ro.board.platform。ro.arch是从/system/build.prop文件读取出来的.文件/system/build.prop是由编译系统中的编译脚本build/core/Makefile和Shell脚本build/tools/buildinfo.sh生成的.

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

结构体hw_module_t和hw_device_t以及其相关的其它结构体定义在文件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.
*
* 每个硬件模块肯定会有一个名为HAL_MODULE_INFO_SYM的数据结构,并且
* 这个数据结构的域一定是以hw_module_t開始,后面跟着模块特殊的信息.
*
*/
typedef struct hw_module_t {
/** tag must be initialized to HARDWARE_MODULE_TAG */
    /** tag一定要被初始化为HARDWARE_MODULE_TAG  */
uint32_t tag;
/** major version number for the module */
/** 这个模块的主版本码  */
uint16_t version_major;
/** minor version number of the module */
    /** 这个模块的小版本 */
uint16_t version_minor;
/** 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 */
    /** 模块的dso */
void* dso;
/** padding to 128 bytes, reserved for future use */
/** 填充到128字节,为以后的使用所保留 */
uint32_t reserved[32-7];
} hw_module_t;

结构体hw_module_t中的每个成员的凝视都已经在上面翻译了。只是,有几个点须要注意:

1):在结构体hw_module_t的定义前面有一段凝视,意思是硬件抽象层中的每个模块都必须自己定义一个硬件抽象层模块结构体,并且他的第一个成员变量的类型必须为hw_module_t.

2):硬件抽象层每个模块都必须存在一个导出符号HAL_MODULE_INFO_SYM。即HMI,他指向一个自己定义的硬件抽象层模块结构体.

3):结构体hw_module_t的成员变量tag的值必须设置为HARDWARE_MODULE_TAG。即设置为一个常量值(‘H’ << 24 | ‘W’ << 16 | ‘M’ << 18 | ‘T’),用来标志这是一个硬件抽象层结构体.

4):结构体hw_module_t的成员变量dso用来保存载入硬件抽象层模块后得到的句柄值.前面提到,每个硬件抽象层都相应一个动态链接库文件.载入硬件抽象层模块的过程实际上就是调用dlopen函数来载入与其相应的动态链接库文件的过程.在调用dlclose函数来卸载这个硬件抽象层模块的时候,要用到这个句柄值。因此,我们在载入时须要将他保存起来.

5):结构体hw_module_t的成员变量定义了一个硬件抽象层模块的操作方法列表。他的类悉为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;

结构体hw_module_methods_t仅仅有一个成员变量,他是一个函数指针。用来打开硬件抽象层模块中的硬件设备.当中,參数module表示要打开的硬件设备所在的模块。參数id表示要打开的设备的ID,參数device是一个输出參数,用来描写叙述一个已经打开的硬件设备.因为一个硬件抽象层模块可能包括多个设备硬件,因此,在调用结构体hw_moduel_methods_t的成员变量open来打开一个硬件设备的时候,我们须要指定他的ID.硬件抽象层中的硬件设备使用结构体hw_device_t来描写叙述.


/**
* Every device data structure must begin with hw_device_t
* followed by module specific public methods and attributes.
*
* 每个设备数据结构都是以hw_device_t開始的,后面跟着模块特定的
* 公共方法和属性.
*/
typedef struct hw_device_t {
/** tag must be initialized to HARDWARE_DEVICE_TAG */
    /** tag一定要被初始化为HARDWARE_DEVICE_TAG */
uint32_t tag;
/** version number for hw_device_t */
/** hw_device_t的版本 */
uint32_t version;
/** reference to the module this device belongs to */
/** 该设备所属模块的引用 */
struct hw_module_t* module;
/** padding reserved for future use */
/** 扩展后面使用 */
uint32_t reserved[12];
/** 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,即设置为一个常量值(‘H’ << 24 | ‘W’ << 16 | ‘M’ << 18 | ‘T’)。用来标志这是一个硬件抽象层中的硬件设备结构体.

3):结构体hw_device_t中的成员变量close是一个函数指针。他用来关闭一个硬件设备.

注意:硬件抽象层中的硬件设备是由其所在的模块提供接口来打开的,而关闭则是由硬件设备自身提供的接口来完毕的.

Android的硬件抽象层模块编写规范的更多相关文章

  1. Android Studio Xposed模块编写(二)

    阅读本文前,假设读者已经看过Android Studio Xposed模块编写(一)  相关环境已经搭建完成.本文演示案例与上文环境一致,不在赘述. 1.概述 Xposed是非常牛叉的一款hook框架 ...

  2. Android Studio Xposed模块编写(一)

    1.环境说明 本文主要参考https://my.oschina.net/wisedream/blog/471292?fromerr=rNPFQidG的内容,自己实现了一遍,侵权请告知 已经安装xpos ...

  3. HAL层编写规范

    andriod HAL模块也有一个通用的入口地址,这个入口地址就是HAL_MODULE_INFO_SYM变量,通过它,我们可以访问到HAL模块中的所有想要外部访问到的方法.  在Linux系统中,后缀 ...

  4. 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口(老罗学习笔记4)

    在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接口.实现这两者的目的是为了向更上一层提供硬件访问接口,即为 ...

  5. 为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口

    在上两篇文章中,我们介绍了如何为Android系统的硬件编写驱动程序,包括如何在Linux内核空间实现内核驱动程序和在用户空间实现硬件抽象层接 口.实现这两者的目的是为了向更上一层提供硬件访问接口,即 ...

  6. 在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序(老罗学习笔记3)

    简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的硬件抽象层中.接着,在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)一文中举例子说明了如何在 ...

  7. 为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序

    在Android硬件抽象层(HAL)概要介绍和学习计划一文中,我们简要介绍了在Android系统为为硬件编写驱动程序的方法.简单来说,硬件驱动程序一方面分布在Linux内核中,另一方面分布在用户空间的 ...

  8. 20151009 C# 第一篇 程序编写规范

    20151009 程序编写规范 1. 代码书写规则: 1).尽量使用接口,然后使用类实现接口. 2).关键语句写注释 3).避免写超过5个参数的方法,如果要传递多个参数,则使用结构 4).避免代码量过 ...

  9. Android内核驱动程序的编写和编译过程

    注意:涉及的代码为android内核代码而不是android源码. 在智能手机时代,每个品牌的手机都有自己的个性特点.正是依靠这种与众不同的个性来吸引用户,营造品牌凝聚力和用户忠城度,典型的代表非ip ...

随机推荐

  1. [leetcode greedy]455. Assign Cookies

    Assume you are an awesome parent and want to give your children some cookies. But, you should give e ...

  2. UNP学习总结(二)

    本文是UNP复习系列的第二篇,主要包括了以下几个内容 UNIX系统下5种I/O模型 阻塞.非阻塞,同步.异步 epoll函数用例 一.Unix下的五种可用I/O模型 阻塞式I/O模型 阻塞式I/O是最 ...

  3. Cpp下匿名对象探究

    先来看看一段代码: #include "iostream" using namespace std; class ABCD { public: ABCD(int a, int b, ...

  4. 时间插件datetimepicker

    相关datetimepicker用法查看官网http://eonasdan.github.io/bootstrap-datetimepicker/ {% load staticfiles %} < ...

  5. Jquery API学习笔记

    学习网站 JQuery API 中文网: http://www.jquery123.com/ 学习一遍API可以更熟练的运用jquery并且拓展思路. 这里只挑选了一些我认为在开发中会用到的一些API ...

  6. CF1042C Array Product 分类讨论+贪心

    考虑有无负数(负数的个数为奇视作“有”,否则为“无”)和有无零 无负数无零,全部合并即可 无负数有零,那么把零合并起来,删掉零 有负数无零,把最大的负数找出来,删掉,合并剩余的数 有负数有零,把零和最 ...

  7. WEB架构师成长之路 三

    Web架构师究竟都要学些什么?具备哪些能力呢?先网上查查架构师的大概的定义,参见架构师修炼之道这篇文章,写的还不错,再查查公司招聘Web架构师的要求. 总结起来大概有下面几点技能要求: 一. 架构师有 ...

  8. spring boot2集成ES详解

    一:运行环境 JDK:1.8 ES:5.6.4 二:学习内容 如何构建spring-data-elasticsearch环境? 如何实现常用的增删改查? 如何实现对象嵌套也就是1对多这种关系? 三:J ...

  9. [LeetCode] Max Points on a Line 题解

    题意 Given n points on a 2D plane, find the maximum number of points that lie on the same straight lin ...

  10. HDU 4497 GCD and LCM (合数分解)

    GCD and LCM Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total ...