http://blog.csdn.net/joard_yang/article/details/7834772
CameraService.cpp (frameworks\base\services\camera\libcameraservice)
中调用hw_get_module
-
void CameraService::onFirstRef()
-
{
-
BnCameraService::onFirstRef();
-
-
"color:#ff0000;">if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
-
(const hw_module_t **)&mModule) < 0) {
-
LOGE("Could not load camera HAL module");
-
mNumberOfCameras = 0;
-
}
-
else {
-
mNumberOfCameras = mModule->get_number_of_cameras();
-
if (mNumberOfCameras > MAX_CAMERAS) {
-
LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
-
mNumberOfCameras, MAX_CAMERAS);
-
mNumberOfCameras = MAX_CAMERAS;
-
}
-
for (int i = 0; i < mNumberOfCameras; i++) {
-
setCameraFree(i);
-
}
-
}
-
}
看一下hw_get_module是怎么回事
-
int hw_get_module(const char *id, const struct hw_module_t **module)
-
{
-
return "color:#ff0000;">hw_get_module_by_class(id, NULL, module);
-
}
他只是一个封装实际调用了hw_get_module_by_class@Hardware.c (hardware\libhardware)
好在不长,看看吧
-
int hw_get_module_by_class(const char *class_id, const char *inst,
-
const struct hw_module_t **module)
-
{
-
int status;
-
int i;
-
const struct hw_module_t *hmi = NULL;
-
"color:#ff0000;"> char prop[PATH_MAX];
-
char path[PATH_MAX];
-
char name[PATH_MAX];
-
-
if (inst)
-
snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
-
else
-
strlcpy(name, class_id, PATH_MAX);
-
-
-
-
-
-
-
-
-
-
for (i=0 ; i
-
if (i < HAL_VARIANT_KEYS_COUNT) {
-
if (property_get(variant_keys[i], prop, NULL) == 0)
-
"color:#ff0000;">
-
"ro.hardware[qcom]"
-
"ro.product.board"[7x27],
-
"ro.board.platform"[msm7627a],
-
"ro.arch",
-
"ro.hw_platform"[QRD_SKU3-1100]
-
这几个属性文件中获得硬件的信息
-
有些硬件信息的字符串会出现在编译后生成的.so名字中
-
{
-
continue;
-
}
-
snprintf(path, sizeof(path), "%s/%s.%s.so",
-
HAL_LIBRARY_PATH2, name, prop);
-
if (access(path, R_OK) == 0) break;
-
-
snprintf(path, sizeof(path), "%s/%s.%s.so",
-
HAL_LIBRARY_PATH1, name, prop);"color:#ff0000;">
-
这样一个路径,这个库里有QualcommCamera.cpp,这是
-
camera模块HAL代码开始的地方
-
if (access(path, R_OK) == 0) break;
-
} else {
-
snprintf(path, sizeof(path), "%s/%s.default.so",
-
HAL_LIBRARY_PATH1, name);
-
if (access(path, R_OK) == 0) break;
-
}
-
}
-
-
status = -ENOENT;
-
if (i < HAL_VARIANT_KEYS_COUNT+1) {
-
-
-
status = load(class_id, path, module);"color:#ff0000;">
-
到path(/system/lib/hw/camera.msm7627a.so)这个路径下找到一个id(camera)匹配的module
-
}
-
-
return status;
-
}
再来看看load这个函数@hardware.c (hardware\libhardware)
-
static int load(const char *id,
-
const char *path,
-
const struct hw_module_t **pHmi)
-
{
-
int status;
-
void *handle;
-
struct hw_module_t *hmi;
-
-
-
-
-
-
-
handle = dlopen(path, RTLD_NOW);
-
if (handle == NULL) {
-
char const *err_str = dlerror();
-
LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
-
status = -EINVAL;
-
goto done;
-
}
-
-
"color:#ff0000;">
-
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
-
hmi = (struct hw_module_t *)dlsym(handle, sym);
-
if (hmi == NULL) {
-
LOGE("load: couldn't find symbol %s", sym);
-
status = -EINVAL;
-
goto done;
-
}
-
-
-
if (strcmp(id, hmi->id) != 0) {
-
LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
-
status = -EINVAL;
-
goto done;
-
}
-
-
hmi->dso = handle;
-
-
-
status = 0;
-
-
done:
-
if (status != 0) {
-
hmi = NULL;
-
if (handle != NULL) {
-
dlclose(handle);
-
handle = NULL;
-
}
-
} else {
-
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
-
id, path, *pHmi, handle);
-
}
-
-
*pHmi = hmi;
-
-
return status;
-
}
在打开的.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.
阅读(2117) | 评论(0) | 转发(0) |