分享

android中camera的hal模块怎么被调用

 开花结果 2013-01-17
CameraService.cpp (frameworks\base\services\camera\libcameraservice)

中调用hw_get_module

  1. void CameraService::onFirstRef()  
  2. {  
  3.     BnCameraService::onFirstRef();  
  4.   
  5.     <span style="color:#ff0000;">if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,  
  6.                 (const hw_module_t **)&mModule) < 0)</span> {  
  7.         LOGE("Could not load camera HAL module");  
  8.         mNumberOfCameras = 0;  
  9.     }  
  10.     else {  
  11.         mNumberOfCameras = mModule->get_number_of_cameras();  
  12.         if (mNumberOfCameras > MAX_CAMERAS) {  
  13.             LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",  
  14.                     mNumberOfCameras, MAX_CAMERAS);  
  15.             mNumberOfCameras = MAX_CAMERAS;  
  16.         }  
  17.         for (int i = 0; i < mNumberOfCameras; i++) {  
  18.             setCameraFree(i);  
  19.         }  
  20.     }  
  21. }  

看一下hw_get_module是怎么回事

  1. int hw_get_module(const char *id, const struct hw_module_t **module)  
  2. {  
  3.     return <span style="color:#ff0000;">hw_get_module_by_class(id, NULL, module);  
  4. </span>}  

他只是一个封装实际调用了hw_get_module_by_class@Hardware.c (hardware\libhardware)

好在不长,看看吧

  1. int hw_get_module_by_class(const char *class_id, const char *inst,  
  2.                            const struct hw_module_t **module)  
  3. {  
  4.     int status;  
  5.     int i;  
  6.     const struct hw_module_t *hmi = NULL;  
  7.  <span style="color:#ff0000;">   char prop[PATH_MAX];//几个关键的数组  
  8.     char path[PATH_MAX];//在下面起了重要  
  9.     char name[PATH_MAX];//作用  
  10. </span>  
  11.     if (inst)  
  12.         snprintf(name, PATH_MAX, "%s.%s", class_id, inst);  
  13.     else  
  14.         strlcpy(name, class_id, PATH_MAX);//走这里  
  15.   
  16.     /* 
  17.      * Here we rely on the fact that calling dlopen multiple times on 
  18.      * the same .so will simply increment a refcount (and not load 
  19.      * a new copy of the library). 
  20.      * We also assume that dlopen() is thread-safe. 
  21.      */  
  22.   
  23.     /* Loop through the configuration variants looking for a module */  
  24.     for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {  
  25.         if (i < HAL_VARIANT_KEYS_COUNT) {  
  26.             if (property_get(variant_keys[i], prop, NULL) == 0)  
  27.    <span style="color:#ff0000;">//在这里将prop的路径得到,分别从  
  28.     "ro.hardware[qcom]"  
  29.     "ro.product.board"[7x27],  
  30.     "ro.board.platform"[msm7627a],  
  31.     "ro.arch",  
  32.     "ro.hw_platform"[QRD_SKU3-1100]  
  33.     这几个属性文件中获得硬件的信息  
  34.     有些硬件信息的字符串会出现在编译后生成的.so名字中</span>  
  35.            {  
  36.               continue;  
  37.             }  
  38.             snprintf(path, sizeof(path), "%s/%s.%s.so",  
  39.                      HAL_LIBRARY_PATH2, name, prop);  
  40.             if (access(path, R_OK) == 0) break;  
  41.   
  42.             snprintf(path, sizeof(path), "%s/%s.%s.so",  
  43.                      HAL_LIBRARY_PATH1, name, prop);<span style="color:#ff0000;">//走这里,在这里得到/system/lib/hw/camera.msm7627a.so  
  44.                                               这样一个路径,这个库里有QualcommCamera.cpp,这是  
  45.                                               camera模块HAL代码开始的地方</span>  
  46.             if (access(path, R_OK) == 0) break;  
  47.         } else {  
  48.             snprintf(path, sizeof(path), "%s/%s.default.so",  
  49.                      HAL_LIBRARY_PATH1, name);  
  50.             if (access(path, R_OK) == 0) break;  
  51.         }  
  52.     }  
  53.   
  54.     status = -ENOENT;  
  55.     if (i < HAL_VARIANT_KEYS_COUNT+1) {  
  56.         /* load the module, if this fails, we're doomed, and we should not try 
  57.          * to load a different variant. */  
  58.         status = load(class_id, path, module);<span style="color:#ff0000;">//这里关键,函数的三个参数可以串联成一句话:  
  59.         到path(/system/lib/hw/camera.msm7627a.so)这个路径下找到一个id(camera)匹配的module</span>  
  60.     }  
  61.   
  62.     return status;  
  63. }  

再来看看load这个函数@hardware.c (hardware\libhardware)

  1. static int load(const char *id,  
  2.         const char *path,  
  3.         const struct hw_module_t **pHmi)  
  4. {  
  5.     int status;  
  6.     void *handle;  
  7.     struct hw_module_t *hmi;  
  8.   
  9.     /* 
  10.      * load the symbols resolving undefined symbols before 
  11.      * dlopen returns. Since RTLD_GLOBAL is not or'd in with 
  12.      * RTLD_NOW the external symbols will not be global 
  13.      */  
  14.     handle = dlopen(path, RTLD_NOW);  
  15.     if (handle == NULL) {  
  16.         char const *err_str = dlerror();  
  17.         LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");  
  18.         status = -EINVAL;  
  19.         goto done;  
  20.     }  
  21.   
  22.    <span style="color:#ff0000;"/* Get the address of the struct hal_module_info. */  
  23.     const char *sym = HAL_MODULE_INFO_SYM_AS_STR;  
  24.     hmi = (struct hw_module_t *)dlsym(handle, sym);  
  25. </span>    if (hmi == NULL) {  
  26.         LOGE("load: couldn't find symbol %s", sym);  
  27.         status = -EINVAL;  
  28.         goto done;  
  29.     }  
  30.   
  31.     /* Check that the id matches */  
  32.     if (strcmp(id, hmi->id) != 0) {  
  33.         LOGE("load: id=%s != hmi->id=%s", id, hmi->id);  
  34.         status = -EINVAL;  
  35.         goto done;  
  36.     }  
  37.   
  38.     hmi->dso = handle;  
  39.   
  40.     /* success */  
  41.     status = 0;  
  42.   
  43.     done:  
  44.     if (status != 0) {  
  45.         hmi = NULL;  
  46.         if (handle != NULL) {  
  47.             dlclose(handle);  
  48.             handle = NULL;  
  49.         }  
  50.     } else {  
  51.         LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",  
  52.                 id, path, *pHmi, handle);  
  53.     }  
  54.   
  55.     *pHmi = hmi;  
  56.   
  57.     return status;  
  58. }  

在打开的.so(camera.msm7627a.so)中查找HMI符号的地址,并保存在hmi中。至此,.so中的hw_module_t已经被成功获取,从而可以根
据它获取别的相关接口。
1)HAL通过hw_get_module函数获取hw_module_t
2)HAL通过hw_module_t->methods->open获取hw_device_t指针,并在此open函数中初始化hw_device_t的包装结构中的
函数及hw_device_t中的close函数,如gralloc_device_open。
3)三个重要的数据结构:
    a) struct hw_device_t: 表示硬件设备,存储了各种硬件设备的公共属性和方法       
    b)struct hw_module_t: 可用hw_get_module进行加载的module
    c)struct hw_module_methods_t: 用于定义操作设备的方法,其中只定义了一个打开设备的方法open. 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多