android从应用到驱动之—camera(2)---cameraHAL的实现

本文是camera系列博客,上一篇是:

android从应用到驱动之—camera(1)---程序调用流程

本来想用这一篇博客把cameraHAL的实现和流程都给写完的.搞了半天,东西实在是太多了.这篇先写cameraHAL的基本实现框架,下一篇在具体写camerahal的流程吧.

cameraHAL的实现:

对于初学者来说,最大的疑问是系统是如何调用hardware的.
这里就以camera来举例说明.
调用hardware的程序是cameraservice,我们就去它里面看看它是如何找到hardware的

先把源码贴上来:

CameraService.cpp

void CameraService::onFirstRef()看这个函数:


找了半天也就是它这个函数里边有hw_get_module()这个函数,一看名字就知道是获取hardware的,不找它找谁啊。那么onFirstRef()函数又是何时调用的?
onFirstRef()属于其父类RefBase,该函数在强引用sp新增引用计数时调用,什么意思?就是当 有sp包装的类初始化的时候调用。这里在frameworks/base/services/camera/libcameraservice/CameraService.h 中class CameraService :中有定义

定义

很明显是这里来初始化的,当然这里不是重点,如果全部都写的话,那基本上就写不完了.
找到了hw_get_module()这个函数,让我们看它的具体实现.
hardware/libhardware/hardware.c
代码如下:

hardware.c

让我们看看它的流程:

hw_get_module流程

可以知道,真正来寻找hardware的桥梁是这个ID,在if (strcmp(id, hmi->id) != 0)中,id是frameworks/base/services/camera/libcameraservice/CameraService.cpp中直接赋值的
如下:


而hmi->id中的这个id很明显是hardware中应该定义的了.
我们看hmi是怎么得来的.


不用跟踪这个函数就能看出来.hmi一定是从sym中来获取的.所以这里我们也就知道hardware中一定要有这个结构体.这也是实现一个hardware必须要做的事情,这里在hardware.h中也有说明:


即hardware中一定要有这个叫HAL_MODULE_INFO_SYM的结构体.这也是实现一个hardware的第一步:Step-1:实现一个名字为HAL_MODULE_INFO_SYM的结构体,这个结构体必须以hw_module_t开头
好吧,来看一下camera的hardware中是怎么定义的.

看一下common是不是结构体hw_module_t
hardware/libhardware/include/hardware/camera.h

好了,既然hardware要有结构体,那么必须要给他初始化.自定义的函数也得给实现了.
上文注释已经写出来了.这里只是粘贴一下函数的实现.

所以也就自然而然的调用到了实现hardware的第二步,Step-2:
open函数的实现及作用.还是看cameraHAL中对其的实现.

层层包装啊,再看HAL_camera_device_open:

这里我们知道.open的作用就是打开指定ID号的摄像头以及填充device结构体,供上层直接调用我们HAL的具体函数比如takePicture(),startPreview()等等.
但是应该怎么去填充这个结构体呢?
还是先看hardware/libhardware/include/hardware/hardware.h怎么说吧.


它说每一个设备都必须以hw_device_t开始,后面跟着methods和attributes.
那我们就在HAL中定义一个static的结构体,按着上边赋值完毕后返回这个指针就成了.看HAL


看看是怎么填充的:

这里先看看camera_device_ops的具体实现,也牵扯到了HAL实现的第三步,Step-3:具体设备的函数实现.

先不说HAL中调用函数的具体实现,看看是service怎么调用的.
以start_preview为例.


OK,函数调用到这里也就完成了应用程序调用hardware内具体设备函数的流程.HAL的实现其实也就是实现上面每个函数.使它们协同合作而已.

原文地址:https://www.cnblogs.com/joseph-linux/p/3519545.html