硬件抽象层(HAL).ppt
《硬件抽象层(HAL).ppt》由会员分享,可在线阅读,更多相关《硬件抽象层(HAL).ppt(33页珍藏版)》请在三一办公上搜索。
1、第9讲 硬件抽象层(HAL),讲师:李宁,讲师 李宁,主要内容,什么是HAL 为什么要在Android在添加HAL 编写和测试基于HAL的LED驱动,讲师 李宁,什么是HAL,HAL(Hardware Abstraction Layer,硬件抽象层)是建立在Linux驱动之上的一套动态库。这套动态库并不属于Linux内核,而是属于Linux内核层之上的系统运行库层。Google为Android增加HAL的主要目的除尽量避免应用程序直接访问Linux驱动外,还有一个重要原因,那就是保护“私人财产”。对于那些既想发布基于Android的Linux驱动程序,又不想将核心业务逻辑公开的企业或个人,HA
2、L简直就是福音。,讲师 李宁,为什么要在Android中加入HAL,讲师 李宁,加入HAL的主要目的,统一硬件的调用接口。由于HAL有标准的调用接口,所以可以利用HAL屏蔽Linux驱动复杂、不统一的接口。解决了GPL版权问题。由于Linux内核基于GPL协议,而Android基于Apache Licence 2.0协议。因此Google玩了个“穿越”,将原本位于Linux内核中的Linux驱动的敏感代码向上移了一个层次。这样这些敏感代码就摆脱了GPL协议的束缚。那写不想开源的Linux驱动作者也就没必要开源了。针对一些特殊的要求。对于有些硬件,可能需要访问一些用户空间的资源,或在内核空间不方
3、便完成的工作以及特殊需求。在这种情况下,可以利用位于用户空间的HAL代码来辅助Linux驱动完成一些工作。,讲师 李宁,Android HAL的旧架构,讲师 李宁,Android HAL的新架构,讲师 李宁,Android HAL程序库的路径,Android HAL的源代码存储的位置并不固定。一般会存储在/hardware目录中。其中/hardware/libhardware_legacy用于保存旧的HAL架构的源代码。新HAL架构的源代码在/hardware/libhardware目录中,当然,这些源代码可以放在/hardware或其他的目录。最终编译生成的.so文件主要放在Android系
4、统的/system/lib/hw目录,也可以放在其他的目录。,讲师 李宁,精简LED驱动,基于HAL的LED驱动去掉了所有与读写寄存器规则相关的代码,只保留了创建设备文件已经与寄存器交互的代码(不涉及到任何规则,只是将数据简单地写入指定的寄存器,或从指定的寄存器读取数据)。LED驱动利用了设备文件的read和write函数来读写指定的寄存器。基本原理是只从指定寄存器读取或写入5个字节。第1个字节用于指定读写的动作以及寄存器。后4个字节是读写的实际的数据(因为LED驱动只涉及到操作一个int类型数据的寄存器,因此使用4个字节个来表示一个int类型的数据)。在与LED驱动交互是,只要向设备文件(/
5、dev/s3c6410_leds_hal)读取或发送5个字节的数据,就可以读写指定的寄存器。,讲师 李宁,测试读写寄存器操作,由于LED驱动程序的设备文件接收的不是字符串,而是字节类型的数据(字节数组),因此需要单独做一个程序向设备文件写入字节形式的数据,或从设备文件中读取字节类型的数据。命令行参数来传递设备文件名、字节数和要传递的字节等信息。命令行语法格式如下:rwdev byte1 byte2.byten编译rw_dev.c程序arm-gcc-static-o/root/drivers/read_write_dev/rwdev/root/drivers/read_write_dev/rw_
6、dev.c,讲师 李宁,调用LED驱动的HAL程序库(1),任何被系统自动调用的程序都会有一个标准的接口。这个接口相当与一个约定的规则。不管任何程序,只要遵循这个规则,就可以成功被调用。例如,C语言可执行程序都会有一个main函数,系统中执行程序是都会寻找main函数来执行;Linux驱动也有多个接口,最常用的就是init和exit函数,除此之外,还有与设备文件相关的read、write、ioctl等函数。只要Linux驱动程序安装接口的要求定义和实现,就可以成功安装在Linux驱动中。,讲师 李宁,调用LED驱动的HAL程序库(2),既然HAL程序库也可以被Android系统自动调用,那么自
7、然也拥有标准的接口。只不过这个接口不是函数,而是一个固定名称的结构体变量HAL_MODULE_INFO_SYM。也就是说,所有的HAL程序都必须要有一个HAL_MODULE_INFO_SYM变量,并且初始化该结构体变量的common成员变量。,讲师 李宁,调用LED驱动的HAL程序库(3),第1步:定义结构体和宏 编写HAL程序库需要使用到3个非常重要的结构体(hw_module_t、hw_device_t和hw_module_methods_t),在第1步需要定义两个新的结构体,这两个结构体的第1个变量的类型必须是hw_module_t和hw_device_t。一般还需要为HAL模块定义一个
8、ID。实际上在这1步就是编写leds_hal.h头文件的代码。,讲师 李宁,调用LED驱动的HAL程序库(4),typedef struct hw_module_t/*模块的Tag,值必须是HARDWARE_MODULE_TAG*/uint32_t tag;/*模块主版本号*/uint16_t version_major;/*模块从版本号*/uint16_t version_minor;/*模块的ID,通过该ID可以找到当前模块*/const char*id;/*模块名称*/const char*name;/*模块作者*/const char*author;/*与模块相关的函数指针,都包含着h
9、w_module_methods_t结构体中*/struct hw_module_methods_t*methods;/*模块的dso,dlopen函数返回的HAL动态库的handler*/void*dso;/*保留的空间*/uint32_t reserved32-7;hw_module_t;,讲师 李宁,调用LED驱动的HAL程序库(5),描述硬件设备(或称为HAL设备)的结构体hw_device_t。typedef struct hw_device_t/*设备的Tag,值必须是HARDWARE_DEVICE_TAG*/uint32_t tag;/*硬件设备的版本号*/uint32_t ve
10、rsion;/*指向描述硬件模块的hw_module_t结构体指针*/struct hw_module_t*module;/*保留的内存空间*/uint32_t reserved12;/*关闭设备的函数指针*/int(*close)(struct hw_device_t*device);hw_device_t;,讲师 李宁,调用LED驱动的HAL程序库(6),描述模块入口函数的结构体hw_module_methods_t。typedef struct hw_module_methods_t/*打开设备是调用的open函数的指针*/int(*open)(const struct hw_modul
11、e_t*module,const char*id,struct hw_device_t*device);hw_module_methods_t;在这3个结构体中,hw_module_t是最先使用到的,然后通过hw_module_t.methods找到hw_module_methods_t.open函数,并调用该函数。这个open函数相当与HAL程序库的入口函数。一般会在这个函数里打开设备文件,初始化hw_device_t结构体设置一些控制硬件设备的函数。,讲师 李宁,调用LED驱动的HAL程序库(7),在第1步先考虑hw_module_t和hw_device_t两个结构体。HAL规则建议不直接
12、使用hw_module_t和hw_device_t(直接使用这,而要新定义两个结构体,将hw_module_t和hw_device_t分别作为新结构体的第1个变量的类型。就像leds_hal.h文件中的led_module_t和led_control_device_t。那么HAL为什么要这么建议呢?,讲师 李宁,调用LED驱动的HAL程序库(8),在说明原因之前,先看一下led_device_open函数和led_control_device_t结构体。static int led_device_open(const struct hw_module_t*module,const char*n
13、ame,struct hw_device_t*device)struct led_control_device_t struct hw_device_t hw_device;int(*set_on)(struct led_control_device_t*dev,int32_t led);int(*set_off)(struct led_control_device_t*dev,int32_t led);,讲师 李宁,调用LED驱动的HAL程序库(9),led_device_open函数将在NDK程序中被调用。该函数的最后1个参数类型是hw_device_t*,不过在调用该函数时,传进来的却是
14、led_control_device_t*。从这一点看。hw_device_t相当与led_control_device_t的父类(C语言中并没有类的概念,这样解释只是便于理解,也可以称为其父结构体)。在调用led_device_open函数时将led_control_device_t*强行转换成了hw_device_t*。对于C语言来说,这样的转换要满足一个条件,就是做为父结构体(hw_device_t)的结构体必须是子结构体(led_control_device_t)的第1个变量的数据类型。,讲师 李宁,调用LED驱动的HAL程序库(10),那么为什么要这样做强行转换呢?主要是因为扩展的需
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 硬件 抽象 HAL
![提示](https://www.31ppt.com/images/bang_tan.gif)
链接地址:https://www.31ppt.com/p-5806764.html