HAL学习笔记

简介: HAL学习笔记

一、HAL架构



HAL(硬件抽象层,Hardware Abstraction Layer)是为了保护一些硬件提供商的知识产权而提出的,是为了避免Linux的GPL束缚。把控制硬件的动作都放到了HAL中。


新架构、调整为 HAL stub 的观念 主要包含以下一些模块:Gps、Vibrator、Wifi、Copybit、Audio、Camera、Lights、Ril、Overlay等。


HAL架构是当前Android源码中使用的思路,每一个硬件模块称为一个stub(代理人),并且借尸so的形式编译,所有的stub都要通过libhardware.so(由hardware.c)才能找到每一个stub,才能回调每一个stub中硬件抽象接口,当然stub在编写时需要按照HAL_MODULE_INFO_SYM的格式来写,通过libhardware.so找到stub时,就会将该stub加载到内存,返回该stub的模块指针。优点:采用HAL module和HAL stub结合形式,HAL stub不是共享库,上层只拥有访问stub的函数指针,并不需要stub,Runtime只需要根据module ID并通过HAL module提供的统一接口就能取得stub的操作函数,只会被映射到一个进程,不会浪费空间。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XymXBbdA-1635519984284)(https://i.imgur.com/qrtgvMc.jpg)]


二、编写一款支持HAL的Linux的驱动程序步骤



第1步:编写Linux驱动


为Linux驱动添加HAL, 尽量保护敏感数据,代码尽量简洁,将业务逻辑放到HAL Library中。


第2步:编写HAL Library


HAL Library就是普通的Linux Library(*.so)文件,这类库文件有一个接口,通过HAL_MODULE_INFO_SYM变量实现。Service Library就是通过这个接口定义的ID来找到HAL Library的。


第3步:编写Service Library


新HAL架构要求我们必须编写。Service Library可以是Linux Library,也可以是JNI Library。还应该编写一个用JAVA写的服务管理类(ServiceManager).

ServiceManager会调用Service Library,而APK会调用ServiceManager来访问Service Library。


三、编写Linux驱动



以LED驱动为例


在之前实现的Linux驱动的基础上进行修改。去掉所有的与寄存器读写有关的代码,只保留创建设备文件及与寄存器交互的代码(只是简单的读写寄存器操作,不进行GPXDAT的具体操作)。

此环节实现在设备文件的read和write中读写指定的寄存器


编写HAL模块



struct led_module_t{
  struct hw_module_t hw_module;//HAL规定不能直接使用此结构,必须在外面套上一层。
};
struct led_control_device_t{
  struct hw_device_t hw_device;
  int (*set_off)(...);
  int(*set_on)(...);
};
#define LED_HARDWARE_MODULE_ID "led_hal"


第1步:定义结构体和宏


这两个结构体的第1个变量的数据类型必须是hw_module_t和hw_device_t,另外还需要为HAL模块定义一个ID。还有描述模块入口函数的hw_module_methods_t。首先使用的是hw_module_t,然后通过hw_module_methods_t找到.open函数,并且调用该函数,open函数相当于HAL模块的入口


第2步:编写HAL的open函数


初始化hw_device_t结构体。设置硬件操作函数(set_on和set_off)

打开设备文件

初始化寄存器


第3步:定义hw_module_methods_t结构体变量


指定open入口函数


第4步:定义HAL_MODULE_INFO_SYM变量


所有的HAL模块都必须有一个HAL_MODULE_INFO_SYM变量,一般为hw_module_t的或者其子结构体,会初始化此结构体,其中id和methods最重要,id表示HAL模块在Android系统中的标识。


第5步:编写HAL模块的close函数


HAL模块被卸载后会调用close函数


第6步:编写控制LED的函数


编写调用HAL模块的Service



编写调用Service的JAVA库 ##



将Service程序库封装在JAR文件中。

相关文章
|
网络协议 jenkins 调度
Docker【部署 06】Swarm实践及Operation not permitted和No chain/target/match by that name问题处理
Docker【部署 06】Swarm实践及Operation not permitted和No chain/target/match by that name问题处理
940 0
Docker【部署 06】Swarm实践及Operation not permitted和No chain/target/match by that name问题处理
|
Ubuntu 网络安全 数据安全/隐私保护
如何在 Ubuntu 上创建一个 SSH CA 以验证主机和客户端
如何在 Ubuntu 上创建一个 SSH CA 以验证主机和客户端
322 0
|
Java
neo4j通过关系查询子节点
neo4j通过关系查询子节点
976 5
|
前端开发 数据可视化 JavaScript
【揭秘神器】如何用Pyecharts轻松召唤出Echarts?只需几行Python代码,让你的数据瞬间生动起来!
【8月更文挑战第21天】Pyecharts是一款基于Python的图表生成库,利用Echarts强大的JavaScript可视化能力,让开发者无需编写前端代码即可在Python环境中创建美观图表。本文通过实例演示如何安装Pyecharts并生成一个展示城市气温分布的柱状图,包括基本图表生成及自定义样式设置,如颜色调整、图例显示等,最终将图表嵌入HTML文件展示,适合各水平开发者快速掌握数据可视化技能。
410 0
|
JavaScript 前端开发 数据处理
在vue中的form表单中下拉框中的数据来自数据库查询到的数据
这篇文章介绍了如何在Vue框架的表单中将下拉框的数据通过后端接口从数据库动态查询并加载,包括前端HTML代码、JavaScript数据处理、后端接口实现以及表单提交的完整流程。
在vue中的form表单中下拉框中的数据来自数据库查询到的数据
|
Java 关系型数据库 MySQL
【编程基础知识】Eclipse连接MySQL 8.0时的JDK版本和驱动问题全解析
本文详细解析了在使用Eclipse连接MySQL 8.0时常见的JDK版本不兼容、驱动类错误和时区设置问题,并提供了清晰的解决方案。通过正确配置JDK版本、选择合适的驱动类和设置时区,确保Java应用能够顺利连接MySQL 8.0。
1064 1
|
消息中间件 存储 监控
【ZeroMQ的SUB视角】深入探讨订阅者模式、C++编程实践与底层机制
【ZeroMQ的SUB视角】深入探讨订阅者模式、C++编程实践与底层机制
1552 1
|
存储 负载均衡 NoSQL
Nginx如何实现负载均衡以及Session共享教程详解
最近迷上了Nginx,真实麻雀虽小,五脏俱全..功能实在强大.. nginx不单可以作为强大的web服务器,也可以作为一个反向代理服务器,而且nginx还可以按照调度规则实现动态、静态页面的分离,可以按照轮询、ip哈希、URL哈希、权重等多种方式对后端服务器做负载均衡,同时还支持后端服务器的健康检查。
2794 0
|
Ubuntu Linux C语言
Could not establish connection to “xx.xx.xx.xx“:The VS Code Server faild to start.【重要解决方案】
Could not establish connection to “xx.xx.xx.xx“:The VS Code Server faild to start.【重要解决方案】
1179 0
|
存储 运维 算法
PolarDB-X 一致性共识协议 (X-Paxos)
近几年NewSQL和云原生数据库的不断兴起,极大地推动了关系数据库和一致性协议的结合,PolarDB-X也是在这样的背景下应运而生。
2280 0
PolarDB-X 一致性共识协议 (X-Paxos)