首先介绍一下HAL, Android的HAL是为了保护一些硬件提供商的知识产权而提出的,是为了避开linux的GPL束缚。思路是把控制硬件的动作都放到了Android HAL中,而linux driver仅仅完成一些简单的数据交互作用,甚至把硬件寄存器空间直接映射到user space。而Android是基于Aparch的license,因此硬件厂商可以只提供二进制代码,所以说Android只是一个开放的平台,并不是一个开源的平台。
    总结下来,Android HAL存在的原因主要有:
    1. 并不是所有的硬件设备都有标准的linux kernel的接口
    2. KERNEL DRIVER涉及到GPL的版权。某些设备制造商并不原因公开硬件驱动,所以才去用HAL方    式绕过GPL。
    3. 针对某些硬件,An有一些特殊的需求
如果我们的App需要调用硬件的功能, 一般需经过如下步骤

ConsumerIrService(CIRS)是Android中的一个简单的系统服务, 通过这个服务, 我们不仅可以了解ConsumerIrManager是如何运行的,也可以举一反三学习Android系统服务的实现框架.
CIRS的实现分为初始化, 和发送红外信号两个方面; 他们的时序图如下

CIRS涉及的文件

Framework层-Java
android.hardware.ConsumerIrManager.java
com.android.serve.ConsumerIrService.java

Framework层-C++

frameworks\base\services\core\jni\com_android_server_ConsumerIrService.cpp

HAL层:
hardware\libhardware\include\hardware\consumerir.h
hardware\libhardware\modules\consumerir\consumerir.c

一 首先分析一下初始化流程
1.SystemServer注册CIRS

作为一个Android的系统服务, CIRS在Android启动的时候就开始启动了.
在Android启动, Zygote初始化的时候会启动 SystemServer, 
在SystemServer.java中就会初始化并注册CIRS

2.ConsumerIrService 的初始化 

可以看到, CIRS通过halOpen()函数,打开了红外的硬件设备, 并一直持有这个设备对象的指针 (mNaticeHal),
这就将来就可以通过这个指针, 调用Hal层的红外设备对象, 发送红外信号了

3.com_android_server_ConsumerIrService.cpp中的halOpen函数, 打开红外设备

其实都是Android Hal 层提供的接口
a.使用hw_get_module来拿到红外设备,
b.通过module->methods->open 来打开这个红外设备

CONSUMERIR_HARDWARE_MODULE_ID 这个宏在consumerir.h中定义, 用来标识红外模块,

4. consumerir.h , consumerir.c 这是IR模块的Hal模块代码, 将来会和真正的硬件驱动打交道
定义了 CONSUMERIR_HARDWARE_MODULE_ID:
#define CONSUMERIR_HARDWARE_MODULE_ID "consumerir"

这是在 consumerir.c 中向Hal层注册(声明)的, 这样就可以使用hw_get_module来拿到红外设备,
 
在 consumerir.c中也定义了 module的open函数指针指向consumerir_open函数: 
这样就可以通过module->methods->open 调用到consumerir_open函数了

5.consumerir_open函数定义了外部的模块调用consumerir模块的api, 当然这也是使用了hal框架的模板
这里就有发送红外的函数注册, 这样外界通过使用 dev->transmit函数就可以发送红外信号了

这里谷歌github的代码只是提供了一个demo, 将来需要在这里打开驱动文件, 下面有一个打开驱动文件的实例代码:

  • static int hello_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) {
  • struct hello_device_t* dev;dev = (struct hello_device_t*)malloc(sizeof(struct hello_device_t));
  • if(!dev) {
  • LOGE("Hello Stub: failed to alloc space");
  • return -EFAULT;
  • }
  • memset(dev, 0, sizeof(struct hello_device_t));
  • dev->common.tag = HARDWARE_DEVICE_TAG;
  • dev->common.version = 0;
  • dev->common.module = (hw_module_t*)module;
  • dev->common.close = hello_device_close;
  • dev->set_val = hello_set_val;dev->get_val = hello_get_val;
  • if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {
  • LOGE("Hello Stub: failed to open /dev/hello -- %s.", strerror(errno));free(dev);
  • return -EFAULT;
  • }
  • *device = &(dev->common);
  • LOGI("Hello Stub: open /dev/hello successfully.");
  • return 0;
  • }

参考. http://blog.csdn.net/luoshengyang/article/details/6573809

这个过程很像是Java的基类调用子类, 子类函数自己去实现 . 
这样就通过函数指针在C中实现了类似Java的函数实现功能.

综上就是CIRS的初始化

二 发送红外信号的流程
上面初始化进行完毕,下面发送红外就不在话下了:

1.在App启动的时候会初始化一个Context, 这时候就会初始化一个ConsumerIrManager也就是CIRS的在App端的Proxy出来:

2.在后面,发送红外的时候, 就可以拿到CIRMgr来发送红外了, 当然不过是通过AIDL调用到CIRS的transmit函数

3.在CIRS中, 处理之后调用到haltransmit函数, 注意mNativeHal就是红外的hal模块对象的指针, 他初始化后一直在内存中.

Java不能直接使用调用hal, 所以转发到 CIRS的C++层, 然后调用device进行发送红外

4.前面我们把transmit指针指向了consumerir_transmit, 于是调用consumerir_transmit开始真正的红外发送了:

同样参考一下 人家发送halloword的代码

  • static int hello_device_close(struct hw_device_t* device) {
  • struct hello_device_t* hello_device = (struct hello_device_t*)device;
  • if(hello_device) {
  • close(hello_device->fd);
  • free(hello_device);
  • }
  • return 0;
  • }
  • static int hello_set_val(struct hello_device_t* dev, int val) {
  • LOGI("Hello Stub: set value %d to device.", val);
  • write(dev->fd, &val, sizeof(val));
  • return 0;
  • }
  • static int hello_get_val(struct hello_device_t* dev, int* val) {
  • if(!val) {
  • LOGE("Hello Stub: error val pointer");
  • return -EFAULT;
  • }
  • read(dev->fd, val, sizeof(*val));
  • LOGI("Hello Stub: get value %d from device", *val);
  • return 0;
  • }

至此, 发送流程就完成了.

三 总结
和Android App的Framework一样. Android 底层的Hal其实也是提供了接口给厂商, 这样厂商就可以
编写自己的Hal模块了!

转一篇eoe论坛上sfshine大神的文章--AndroidHal底层! ConsumerIrService分析相关推荐

  1. 一个大神的文章如何在没有OPENCV的电脑上跑你的程序调用的opencv程序

    这个opencv的环境高了一个多月一直弄不出来,最后看了这个大神的文章,一次通过 直接上连接http://blog.csdn.net/GL_a_/article/details/52870159?re ...

  2. 关于无线充电技术--转大神的文章

    转一位大神的文章. 一篇读懂无线充电技术(附方案选型及原理分析) 0.背景 1.无线供电特点 2.无线供电原理及实现方式 3.现有解决方案分析 4.FAQ及相关测试 5.参考资料 作者:HowieXu ...

  3. 用爬虫来爬取csdn大神的文章的url

    上一篇文章中爬虫来获取廖老师python教程的url并加入搜索url功能,这一篇文章会爬取csdn大神july的所有博客的url,并实现搜索功能就像下面这样 请输入你要查询的知识点:Machine M ...

  4. 爬虫工程师的进阶一览图(爬虫工程师水平对照表)根据崔庆才崔大神的文章总结的

    根据崔大神的文章总结的爬虫水平对照表 一.初级水平 Python [语言基础] requests [请求相关] lxml[解析相关] XPath  [解析相关] BeautifulSoup[解析相关] ...

  5. 一年六篇顶会的清华大神提出Fastformer:史上最快、效果最好的Transformer

    来源:新智元 [导读]Transformer模型好是好,可惜太慢了!最近一位清华大神在arxiv上传了一篇论文,提出新模型Fastformer,线性时间复杂度,训练和推理效率史上最快,还顺手在排行榜刷 ...

  6. 项目前的一篇战地日记-菜鸟和大神的区别

    转眼间,来了兄弟连已经一个月了,这一个月的日子感觉时间过的好充实呀!每天最早12点休息(几乎是不可能的,老多事等着你去完成呢)7.30起床.和以前那样安逸的日子比起来,刚开始还真是让我有点受不了.不过 ...

  7. 读李沐大神的文章有感

    <用随机梯度下降来优化人生> https://zhuanlan.zhihu.com/p/414009313?utm_source=wechat_session&utm_medium ...

  8. 如何在windows电脑上完成原神签到、祈愿抽卡分析等功能

    一款开源的游戏辅助工具--原神助手.支持原神签到.祈愿抽卡分析.查看便签状态和游戏详细数据等. 开发者自述也是偶然间接触到<原神>,于是一发不可收拾,爱上这款游戏了. 在游戏中,如果要查看 ...

  9. 【IT干货】当上技术大神,迎娶白富美,走上人生巅峰的机会了解一下?

    在现今这个社会现状下,IT人才紧缺,IT行业前景大好,导致很多人积极投身于TI行业,但是不是每个人都能学好IT技术,想要成为更高级的IT技术人员,就需要更大的努力和付出. IT行业技术变更周期越来越快 ...

最新文章

  1. python中matrix是什么意思_初识Python
  2. 11.13. Highslide
  3. 关于VMware虚拟机的复制注意事项
  4. 5种Python逐行读取文件的方式
  5. ubuntu docker一键安装mysql_mysql5.6在ubuntu下的docker中安装的办法详细说明
  6. 脚本安装smokeping
  7. 利用 Domino V8 新特性开发 Mashup 应用(转载)
  8. 用Docker快速搭建一个博客网站,很简单的嘛~
  9. 决策树分箱-特征工程之数据离散化处理-基于python实现
  10. Python 使用pip下载失败的解决方案
  11. html网页设计字体变色,网页制作怎么改变字体颜色
  12. 2022在线横幅广告_店标_LOGO制作系统最新源码
  13. 计算机无线模块怎样关闭,台式机无线上网设置_台式电脑如何关闭WIFI?
  14. 兜兜转转 - 2019开启CSDN博客的新篇章
  15. RLC无源网络线性元件的微分方程
  16. HackerRank Truck Tour
  17. PHPexcel 导出身份证处理
  18. 【Druid】Druid连接池(二)——配置监控界面
  19. 小明Q2投影仪好用吗?小明Q2和哈趣K1哪个更值得入手?
  20. 计算机网络——传输层の选择题整理

热门文章

  1. 检索 COM 类工厂中 CLSID 为 {{10020200-E260-11CF-AE68-00AA004A34D5}} 的组件时失败解决办法...
  2. java countdowntimer_Android 倒计时CountDownTimer
  3. 如何在机房限制学生端摆脱老师的控制,实现自由上网
  4. 关于VMware不能上网解决办法
  5. PTA 公路村村通 (30 分)
  6. 微信开发弹窗四种方法
  7. EasyX教程(一)续:画十字
  8. Excel(XLSX/XLS)文件内容导入WEB表单,纯前端无需服务器支持,开源Chrome扩展 v0.0.8,附下载,附github链接(2021/5/8更)
  9. 稻盛和夫:高层次的人,都善于把复杂问题「简单化」
  10. caffe和caffe2的区别