博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HAL学习
阅读量:4207 次
发布时间:2019-05-26

本文共 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结构:

[cpp] 
  1. typedef struct gralloc_module_t {  
  2.     struct hw_module_t common;  
  3.       
  4.     /* 
  5.      * (*registerBuffer)() must be called before a buffer_handle_t that has not 
  6.      * been created with (*alloc_device_t::alloc)() can be used. 
  7.      *  
  8.      * This is intended to be used with buffer_handle_t's that have been 
  9.      * received in this process through IPC. 
  10.      *  
  11.      * This function checks that the handle is indeed a valid one and prepares 
  12.      * it for use with (*lock)() and (*unlock)(). 
  13.      *  
  14.      * It is not necessary to call (*registerBuffer)() on a handle created  
  15.      * with (*alloc_device_t::alloc)(). 
  16.      *  
  17.      * returns an error if this buffer_handle_t is not valid. 
  18.      */  
  19.     int (*registerBuffer)(struct gralloc_module_t const* module,  
  20.             buffer_handle_t handle);  
  21.   
  22.     /* 
  23.      * (*unregisterBuffer)() is called once this handle is no longer needed in 
  24.      * this process. After this call, it is an error to call (*lock)(), 
  25.      * (*unlock)(), or (*registerBuffer)(). 
  26.      *  
  27.      * This function doesn't close or free the handle itself; this is done 
  28.      * by other means, usually through libcutils's native_handle_close() and 
  29.      * native_handle_free().  
  30.      *  
  31.      * It is an error to call (*unregisterBuffer)() on a buffer that wasn't 
  32.      * explicitly registered first. 
  33.      */  
  34.     int (*unregisterBuffer)(struct gralloc_module_t const* module,  
  35.             buffer_handle_t handle);  
  36.       
  37.     /* 
  38.      * The (*lock)() method is called before a buffer is accessed for the  
  39.      * specified usage. This call may block, for instance if the h/w needs 
  40.      * to finish rendering or if CPU caches need to be synchronized. 
  41.      *  
  42.      * The caller promises to modify only pixels in the area specified  
  43.      * by (l,t,w,h). 
  44.      *  
  45.      * The content of the buffer outside of the specified area is NOT modified 
  46.      * by this call. 
  47.      * 
  48.      * If usage specifies GRALLOC_USAGE_SW_*, vaddr is filled with the address 
  49.      * of the buffer in virtual memory. 
  50.      * 
  51.      * THREADING CONSIDERATIONS: 
  52.      * 
  53.      * It is legal for several different threads to lock a buffer from  
  54.      * read access, none of the threads are blocked. 
  55.      *  
  56.      * However, locking a buffer simultaneously for write or read/write is 
  57.      * undefined, but: 
  58.      * - shall not result in termination of the process 
  59.      * - shall not block the caller 
  60.      * It is acceptable to return an error or to leave the buffer's content 
  61.      * into an indeterminate state. 
  62.      * 
  63.      * If the buffer was created with a usage mask incompatible with the 
  64.      * requested usage flags here, -EINVAL is returned.  
  65.      *  
  66.      */  
  67.       
  68.     int (*lock)(struct gralloc_module_t const* module,  
  69.             buffer_handle_t handle, int usage,  
  70.             int l, int t, int w, int h,  
  71.             void** vaddr);  
  72.   
  73.       
  74.     /* 
  75.      * The (*unlock)() method must be called after all changes to the buffer 
  76.      * are completed. 
  77.      */  
  78.       
  79.     int (*unlock)(struct gralloc_module_t const* module,  
  80.             buffer_handle_t handle);  
  81.   
  82.   
  83.     /* reserved for future use */  
  84.     int (*perform)(struct gralloc_module_t const* module,  
  85.             int operation, ... );  
  86.   
  87.     /* reserved for future use */  
  88.     void* reserved_proc[7];  
  89. } gralloc_module_t;  
  90. 2、然后是扩展的hw_device_t结构:  
  91. typedef struct alloc_device_t {  
  92.     struct hw_device_t common;  
  93.   
  94.     /*  
  95.      * (*alloc)() Allocates a buffer in graphic memory with the requested 
  96.      * parameters and returns a buffer_handle_t and the stride in pixels to 
  97.      * allow the implementation to satisfy hardware constraints on the width 
  98.      * of a pixmap (eg: it may have to be multiple of 8 pixels).  
  99.      * The CALLER TAKES OWNERSHIP of the buffer_handle_t. 
  100.      *  
  101.      * Returns 0 on success or -errno on error. 
  102.      */  
  103.       
  104.     int (*alloc)(struct alloc_device_t* dev,  
  105.             int w, int h, int format, int usage,  
  106.             buffer_handle_t* handle, int* stride);  
  107.   
  108.     /* 
  109.      * (*free)() Frees a previously allocated buffer.  
  110.      * Behavior is undefined if the buffer is still mapped in any process, 
  111.      * but shall not result in termination of the program or security breaches 
  112.      * (allowing a process to get access to another process' buffers). 
  113.      * THIS FUNCTION TAKES OWNERSHIP of the buffer_handle_t which becomes 
  114.      * invalid after the call.  
  115.      *  
  116.      * Returns 0 on success or -errno on error. 
  117.      */  
  118.     int (*free)(struct alloc_device_t* dev,  
  119.             buffer_handle_t handle);  
  120.   
  121. } alloc_device_t;  

3、最后是两个方法:

[cpp] 
  1. static inline int gralloc_open(const struct hw_module_t* module,   
  2.         struct alloc_device_t** device) {  
  3.     return module->methods->open(module,   
  4.             GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device);  
  5. }  
  6.   
  7. static inline int gralloc_close(struct alloc_device_t* device) {  
  8.     return device->common.close(&device->common);  
  9. }  

这里直接调用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结构:

[cpp] 
  1. typedef struct hw_module_t {  
  2.     /** tag must be initialized to HARDWARE_MODULE_TAG */  
  3.     uint32_t tag;  
  4.   
  5.     /** major version number for the module */  
  6.     uint16_t version_major;  
  7.   
  8.     /** minor version number of the module */  
  9.     uint16_t version_minor;  
  10.   
  11.     /** Identifier of module */  
  12.     const char *id;  
  13.   
  14.     /** Name of this module */  
  15.     const char *name;  
  16.   
  17.     /** Author/owner/implementor of the module */  
  18.     const char *author;  
  19.   
  20.     /** Modules methods */  
  21.     struct hw_module_methods_t* methods;  
  22.   
  23.     /** module's dso */  
  24.     void* dso;  
  25.   
  26.     /** padding to 128 bytes, reserved for future use */  
  27.     uint32_t reserved[32-7];  
  28.   
  29. } hw_module_t;  

比较重要的是id和methods,id用来区分各个模块,而hw_module_methods_t我们可以看到其定义是:

[cpp] 
  1. typedef struct hw_module_methods_t {  
  2.     /** Open a specific device */  
  3.     int (*open)(const struct hw_module_t* module, const char* id,  
  4.             struct hw_device_t** device);  
  5.   
  6. } hw_module_methods_t;  

一个open方法,指向了打开这个模块的Open方法

我们看一下gralloc模块相关结构的关系图:



1、  先看一下private_module_t(hw_module_t)结构的赋值

[cpp] 
  1. struct private_module_t HAL_MODULE_INFO_SYM = {  
  2.     base: {  
  3.         common: {  
  4.             tag: HARDWARE_MODULE_TAG,  
  5.             version_major: 1,  
  6.             version_minor: 0,  
  7.             id: GRALLOC_HARDWARE_MODULE_ID,  
  8.             name: "Graphics Memory Allocator Module",  
  9.             author: "The Android Open Source Project",  
  10.             methods: &gralloc_module_methods  
  11.         },  
  12.         registerBuffer: gralloc_register_buffer,  
  13.         unregisterBuffer: gralloc_unregister_buffer,  
  14.         lock: gralloc_lock,  
  15.         unlock: gralloc_unlock,  
  16.     },  
  17.     framebuffer: 0,  
  18.     flags: 0,  
  19.     numBuffers: 0,  
  20.     bufferMask: 0,  
  21.     lock: PTHREAD_MUTEX_INITIALIZER,  
  22.     currentBuffer: 0,  
  23.     pmem_master: -1,  
  24.     pmem_master_base: 0  
  25. };  

这里id赋值为GRALLOC_HARDWARE_MODULE_ID,methods赋值为gralloc_module_methods

看一下gralloc_module_methods

gralloc_module_t扩展了hw_module_t,增加4个方法,这四个方法可以在调用open之前调用。

[cpp] 
  1. static struct hw_module_methods_t gralloc_module_methods = {  
  2.         open: gralloc_device_open  
  3. };  

再看一下alloc_device_t的初始化,是在gralloc_device_open函数中

[cpp] 
  1. int gralloc_device_open(const hw_module_t* module, const char* name,  
  2.         hw_device_t** device)  
  3. {  
  4.     int status = -EINVAL;  
  5.     if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {  
  6.         gralloc_context_t *dev;  
  7.         dev = (gralloc_context_t*)malloc(sizeof(*dev));  
  8.   
  9.         /* initialize our state here */  
  10.         memset(dev, 0, sizeof(*dev));  
  11.   
  12.         /* initialize the procs */  
  13.         dev->device.common.tag = HARDWARE_DEVICE_TAG;  
  14.         dev->device.common.version = 0;  
  15.         dev->device.common.module = const_cast<hw_module_t*>(module);  
  16.         dev->device.common.close = gralloc_close;  
  17.   
  18.         dev->device.alloc   = gralloc_alloc;  
  19.         dev->device.free    = gralloc_free;  
  20.   
  21.         *device = &dev->device.common;  
  22.         status = 0;  
  23.     } else {  
  24.         status = fb_device_open(module, name, device);  
  25.     }  
  26.     return status;  
  27. }  

可以看到,这里把module和device关联起来了

dev->device.common.module =const_cast<hw_module_t*>(module);

并对gralloc设备提供的两个方法进行赋值

dev->device.alloc   = gralloc_alloc;

dev->device.free    = gralloc_free;

 

这样,我们就可以调用gralloc提供的另外两个方法了。

你可能感兴趣的文章
通过LR监控Linux服务器性能
查看>>
通过FTP服务的winsockes录制脚本
查看>>
LRwinsocket协议测试AAA服务器
查看>>
Net远程管理实验
查看>>
反病毒专家谈虚拟机技术 面临两大技术难题
查看>>
几种典型的反病毒技术:特征码技术、覆盖法技术等
查看>>
性能测试一般过程与LR性能测试过程
查看>>
Software Security Testing软件安全测试
查看>>
SQL注入漏洞全接触--进阶篇
查看>>
SQL注入漏洞全接触--高级篇
查看>>
SQL注入法攻击一日通
查看>>
论文浅尝 | 通过共享表示和结构化预测进行事件和事件时序关系的联合抽取
查看>>
论文浅尝 | 融合多粒度信息和外部语言知识的中文关系抽取
查看>>
论文浅尝 | GMNN: Graph Markov Neural Networks
查看>>
廖雪峰Python教程 学习笔记3 hello.py
查看>>
从内核看epoll的实现(基于5.9.9)
查看>>
python与正则表达式
查看>>
安装.Net Framework 4.7.2时出现“不受信任提供程序信任的根证书中终止”的解决方法
查看>>
input type=“button“与input type=“submit“的区别
查看>>
解决Github代码下载慢问题!
查看>>