本文共 7482 字,大约阅读时间需要 24 分钟。
http://blog.csdn.net/new_abc/article/details/8658168
一、HAL调用方式或流程(以gralloc为例):
hw_module_t const* module;
alloc_device_t* grDev;
hw_get_module(GRALLOC_HARDWARE_MODULE_ID,&module);获取hw_module_t结构
gralloc_open(module, &grDev); //调用相应的open接口,在这个接口里会对gralloc设备结构grDev初始化,以 后就可以使用其中的方法
如grDev->alloc(******);
再看一下gralloc.h提供的信息(与gralloc相关):
1、首先是扩展的hw_module_t结构:
- typedef struct gralloc_module_t {
- struct hw_module_t common;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- int (*registerBuffer)(struct gralloc_module_t const* module,
- buffer_handle_t handle);
-
-
-
-
-
-
-
-
-
-
-
-
-
- int (*unregisterBuffer)(struct gralloc_module_t const* module,
- buffer_handle_t handle);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- int (*lock)(struct gralloc_module_t const* module,
- buffer_handle_t handle, int usage,
- int l, int t, int w, int h,
- void** vaddr);
-
-
-
-
-
-
-
- int (*unlock)(struct gralloc_module_t const* module,
- buffer_handle_t handle);
-
-
-
- int (*perform)(struct gralloc_module_t const* module,
- int operation, ... );
-
-
- void* reserved_proc[7];
- } gralloc_module_t;
- 2、然后是扩展的hw_device_t结构:
- typedef struct alloc_device_t {
- struct hw_device_t common;
-
-
-
-
-
-
-
-
-
-
-
- int (*alloc)(struct alloc_device_t* dev,
- int w, int h, int format, int usage,
- buffer_handle_t* handle, int* stride);
-
-
-
-
-
-
-
-
-
-
-
- int (*free)(struct alloc_device_t* dev,
- buffer_handle_t handle);
-
- } alloc_device_t;
3、最后是两个方法:
- static inline int gralloc_open(const struct hw_module_t* module,
- struct alloc_device_t** device) {
- return module->methods->open(module,
- GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device);
- }
-
- static inline int gralloc_close(struct alloc_device_t* device) {
- return device->common.close(&device->common);
- }
这里直接调用modules里面的open方法,该open指针是在hw_get_module时候赋值的。
所有模块的实现基本都是这样,一个扩展的hw_module_t结构,一个扩展的hw_device_t结构,hw_module_t结构的赋值是通过hw_get_module然后传相应的module ID,如GRALLOC_HARDWARE_MODULE_ID,获取相应ID hw_module_t结构的首地址;而hw_device_t结构是通过相应的Open方法,如这里的gralloc_open,通过这个接口,就获得了操作这个设备的方法了。
二、HAL相关实现
首先看一下hw_module_t结构:
- typedef struct hw_module_t {
-
- uint32_t tag;
-
-
- uint16_t version_major;
-
-
- uint16_t version_minor;
-
-
- const char *id;
-
-
- const char *name;
-
-
- const char *author;
-
-
- struct hw_module_methods_t* methods;
-
-
- void* dso;
-
-
- uint32_t reserved[32-7];
-
- } hw_module_t;
比较重要的是id和methods,id用来区分各个模块,而hw_module_methods_t我们可以看到其定义是:
- typedef struct hw_module_methods_t {
-
- int (*open)(const struct hw_module_t* module, const char* id,
- struct hw_device_t** device);
-
- } hw_module_methods_t;
一个open方法,指向了打开这个模块的Open方法
我们看一下gralloc模块相关结构的关系图:
1、 先看一下private_module_t(hw_module_t)结构的赋值
- struct private_module_t HAL_MODULE_INFO_SYM = {
- base: {
- common: {
- tag: HARDWARE_MODULE_TAG,
- version_major: 1,
- version_minor: 0,
- id: GRALLOC_HARDWARE_MODULE_ID,
- name: "Graphics Memory Allocator Module",
- author: "The Android Open Source Project",
- methods: &gralloc_module_methods
- },
- registerBuffer: gralloc_register_buffer,
- unregisterBuffer: gralloc_unregister_buffer,
- lock: gralloc_lock,
- unlock: gralloc_unlock,
- },
- framebuffer: 0,
- flags: 0,
- numBuffers: 0,
- bufferMask: 0,
- lock: PTHREAD_MUTEX_INITIALIZER,
- currentBuffer: 0,
- pmem_master: -1,
- pmem_master_base: 0
- };
这里id赋值为GRALLOC_HARDWARE_MODULE_ID,methods赋值为gralloc_module_methods
看一下gralloc_module_methods
gralloc_module_t扩展了hw_module_t,增加4个方法,这四个方法可以在调用open之前调用。
- static struct hw_module_methods_t gralloc_module_methods = {
- open: gralloc_device_open
- };
再看一下alloc_device_t的初始化,是在gralloc_device_open函数中
- int gralloc_device_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
- {
- int status = -EINVAL;
- if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
- gralloc_context_t *dev;
- dev = (gralloc_context_t*)malloc(sizeof(*dev));
-
-
- memset(dev, 0, sizeof(*dev));
-
-
- dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = 0;
- dev->device.common.module = const_cast<hw_module_t*>(module);
- dev->device.common.close = gralloc_close;
-
- dev->device.alloc = gralloc_alloc;
- dev->device.free = gralloc_free;
-
- *device = &dev->device.common;
- status = 0;
- } else {
- status = fb_device_open(module, name, device);
- }
- return status;
- }
可以看到,这里把module和device关联起来了
dev->device.common.module =const_cast<hw_module_t*>(module);
并对gralloc设备提供的两个方法进行赋值
dev->device.alloc = gralloc_alloc;
dev->device.free = gralloc_free;
这样,我们就可以调用gralloc提供的另外两个方法了。