Android探索与驱动开发学与思(9)

为什么要在Android中加入HAL

1.统一硬件的调用接口。由于HAL有标准的调用接口,所以可以利用HAL屏蔽Linux驱动复杂、不统一的接口。

2.解决了GPL版权问题。由于Linux内核基于GPL协议,而Android基于Apache Licence 2.0协议。因此Google玩了个“穿越”,将原本位于Linux内核中的Linux驱动的敏感代码向上移了一个层次。这样这些敏感代码就摆脱了GPL协议的束缚。那写不想开源的Linux驱动作者也就没必要开源了。

3.针对一些特殊的要求。对于有些硬件,可能需要访问一些用户空间的资源,或在内核空间不方便完成的工作以及特殊需求。在这种情况下,可以利用位于用户空间的HAL代码来辅助Linux驱动完成一些工作。

Android HAL架构:

旧架构:                                新架构:

然后就要编写一个支持HAL的Linux驱动程序,其步骤为:

第一步:编写Linux驱动

第二步:编写HAL Library

第三步:编写Service Library

最后基于HAL的LED驱动去掉了所有与读写寄存器规则相关的代码,只保留了创建设备文件已经与寄存器交互的代码LED驱动利用了设备文件的read和write函数来读写指定的寄存器。基本原理是只从指定寄存器读取或写入5个字节。第1个字节用于指定读写的动作以及寄存器。后4个字节是读写

编写诵点LED驱动的HAL模块;

实际上:HAL模块也是普通的linux共享库(.so文件),只不过HAL模块可以被Android系统自动装载而不是开发人员自己去装载.so文件。.

Linux驱动的 init 函数与main函数的性质类似。在装载Linux驱动的过程中系统会调用init 函数.

既然HAL模块也可以被Android系统自动调用,那个自然也拥有类似main 或init函数的接口。只不过这个接口不是函数, 而是一个固定名称的结构体变量HAL_MODULE_INFO_SYM.

编写 HAL模块的步骤和原理如下:

第l步:定义结构体和宏:编写 HAL 模块需要使用到 3 个非常重要的结构体( hw_module_t 、 hw_device_t 和hw _ module_ method_ t), 在第 l 步需要定义两个新的结构体, 这两个结构体的第 l 个变量的数据类型必须是 hw_module_t和 bw_device_t。 除此之外, 还需要为HAL模块定义一个ID. 实际上在这 l 步就是编写leds_hal.h 头文件的代码。

第 2 步:编写 HAL模块的 open 函数:

open 函数是 HAL 模块的入口点。该函数主要做如下 3 项工作:初始化 hw device_t 的子结构体。打开设备文件。初始化寄存器。

第3 步:定义 hw_module_methods_ t 结构体变量

第4 步: 定义 HAL_MODULE_INFO_SYM 变量

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

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

总结:在LED的驱动中,我们加入HAL使用程序不需要关心Linux驱动和设备文件的交互方式。编写一款支持HAL的linux驱动程序的步骤:

第一步:编写linux驱动

第二步:编写 HAL Library

第三步:编写Service library

编写HAL模块的步骤和原理如下:

第一步:定义结构体和宏

描述HAL模块的hw-module-t结构体

描述HAL设备的HW-device-t结构体

描述模块入口函数的hw-module-methods-t结构体

第二步:编写HAL模块的open函数

第三步:定义hw-module-methods-t结构体变量

第四步:定义HAL-module-info-sym变量

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

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

本章中我学习到了:

1.在Android.系统中使用 Linux驱动有两种方式。 一种是通过传统的方式直接与Linux驱动交互。

2.编写宏时要了解如下俩个知识点:可变参数的宏、Do{.....}while(0)

时间: 2024-08-24 12:08:30

Android探索与驱动开发学与思(9)的相关文章

Android探索与驱动开发学与思(10)

打印内核的调试信息printk: printk与printf区别: printk 函数该函数的用法与printf函数类似,具不过printk函数运行内核空间,printk函数运行在用户空间.也就是说,像Linux驱动这样的Linux内核程序只能使用prink函数输出调试信息. 其次应该防止printk函数可以很方便地将消息写入日志文件或控制台,但是大量使用printk函数频繁操作日志文件或控制台设备文件会严重影响Linux驱动的性能,因此这就要求Linux驱动只在开发阶段使用printk函数输出

Android探索与驱动开发学与思(4)

涉及到源代码,及上一章所学的git下载的两套源代码,一套是Android源代码,全部下载将近4GB大小,其含金量可想而知.另一套是Android核心部分的linux内核源代码,解压之后几百MB. 首先我们学习下载.编译.和测试Android源代码. 1.配置Android源代码下载环境  (1)创建一个用于存放下载脚本文件(repo)的目录  (2)下载repo脚本文件  (3)创建用于存放Android源代码的目录  (4)初始化  (5)开始下载Android源代码Android源代码目录结

Android探索与驱动开发学与思(8)

蜂鸣器是 S3C6410 开发板上带的一个硬件设备.可以通过向寄存器写入特定的值来控制蜂鸣器 发出尖叫声.PWM驱动的实现方式不同于 LED 驱动, PWM 驱动将由多个文件组成.这也是大多数 Linux 驱动的标准实现方式. 也就是说-个复杂的驱动不太可能将所有的代码都放在一个文件中. 本节讲介绍把linux驱动分成多个文件的方式.这些文件中的数据结构.函数的代码也可以被多个不同的驱动使用,所以这也是代码重用 的重要方法. Linux驱动代码重用: 编译是由多个文件组成的 Linu x 驱动

Android手机嵌入式驱动开发课程教程

本文介绍两种Golang的开发环境一种基于notepad++.另一种基于liteide. 1.下载Golang语言的pkg:http://golangtc.com/download 直接点击安装,一路next. 2.程序员必备神器notepad++开发Golang环境很简单 一次点击:插件->Plugin Manger->Show Plugin Manger,安装插件GOnpp,重启notepad++. 新建文件命名为hello.go用notepad++打开,拷贝如下代码: package m

Android深度探索与驱动开发(五)

开发板是开发和学习嵌入式技术的主要硬件设备, 尽管可以在 PC 上开发 Linux 驱动, 然后重 新编译成 ARM 架构的 Linux 驱动模块.但最终都是要在开发板上进行测试的.这主要是因为 ARM 架构的开发板可基于 X86 架构的 PC 在 CPU 指令以及二进制格式上都有所不同. 而且如果 Linux 驱动需要访问硬件(如 LCD. Wi-町.蓝牙等〉,并且这些硬件很难在 PC 上进行模拟, 那么就要在 带有这些硬件的开发板上进行调试和测试. 开发板从技术上说与我们经常用的手机类似,

Android字符设备驱动开发基于高通msm8916【原创 】

本人才疏浅学,写一篇文档总结自己在msm8916平台上移植自己编写的简单的字符设备驱动开发的整个流程.这个小项目的主要功能是开发一个简单的APP,APP通过JNI去调用位于kernel的字符设备驱动. APP的设计,开发平台Android Studio 主要的文件是下面的三个文件: MainActivity.java文件的内容如下: 1 package com.example.administrator.myled; 2 3 import android.nfc.Tag; 4 import an

Android深度探索与驱动开发(六)

Linux驱动的工作和访问方式是Linux的亮点之一,同时受到了业界的广泛好评. Linux系统 将每一个驱动都映射成一个文件.这些文件称为设备文件或驱动文件,都保存在/dev目录中.这种 设计理念使得与Linux驱动进行交互就像与普通文件进行交互一样容易.当然,也比访问LinuxAPI 更容易. 由于大多数Linux驱动都有与其对应的设备文件, 因此与Linux驱动交换数据就变成了与 设备文件交换数据.例如,向Linux打印机驱动发送一个打印命令,可以直接使用C语言函数open打开设备文件,

Android深度探索与驱动开发(八)

蜂鸣器是 S3C6410 开发板上带的一个硬件设备.可以通过向寄存器写入特定的值来控制蜂鸣器 发出尖叫声.一个完整的蜂呜器驱动(可以打开和关闭蜂鸣 器). PW时驱动的实现方式不同于 LED 驱动, PWM 驱动将由多个文件组成.这也是大多数 Linux 驱动的标准实现方式. 也就是说-个复杂的驱动不太可能将所有的代码都放在一个文件中.最好将 相关的代码放在相应的文件中.在编译 Linux 驱动时将这些文件进行联合编译.这些文件中的数据结构.函数的代码也可以被多个不同的驱动使用, 所 以这也是代

Android深度探索与驱动开发(四)

Linux 网络设备驱动程序由 4 部分组成,分别是网络设备媒介层.网络设备驱动层.网络设 备接口层及网络协议接口层.网络设备媒介层包括各种物理网络设备和传输媒介.对于网络设备 接口层,Linux 系统用 Net_device 结构表示网络设备接口.Net_device 结构保存所有与硬件有关 的接口信息,各协议软件主要通过 Net_device 结构来完成与硬件的交互.网络设备驱动层主要包 括网络设备的初始化.数据包的发送和接收.网络协议接口层提供网络接口驱动程序的抽象接口.初始化(initi