本來想用這一篇博客把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的實現其實也就是實現上面每個函數.使它們協同合作而已.