Firefly开源社区
标题:
MIPI摄像头I2C注销的问题解决
[打印本页]
作者:
Xinxin_2011
时间:
2015-1-7 10:15
标题:
MIPI摄像头I2C注销的问题解决
本帖最后由 Xinxin_2011 于 2015-1-7 14:19 编辑
我也是在解决摄像头二次打开失败问题时发现的这个问题。MIPI摄像头的注册是在HAL层中进行的,CameraService在启动时会调用HAL层的camera_get_number_of_cameras函数来获取系统中存在的摄像头数量,首次调用camera_get_number_of_cameras会完成所有摄像头的注册。MIPI摄像头I2C的注册在
hardware/rk29/camera/CameraHal/
CameraHal_board_xml_parse.cpp
文件的
RegisterSensorDevice函数中:
regist_ret = ioctl(camsys_fd, CAMSYS_REGISTER_DEVIO, &extdev);
if (regist_ret<0) {
ALOGD("CAMSYS_REGISTER_DEVIO failed\n");
ret = RK_RET_DEVICEERR;
goto regist_err;
}
复制代码
从代码中可以看出当注册失败时会转到
regist_err处:
regist_err:
if(regist_ret==0 && ret<0) {
// unregister device need modify
err = ioctl(camsys_fd, CAMSYS_DEREGISTER_DEVIO, &sysctl);
if(err<0){
ALOGE("CAMSYS_DEREGISTER_DEVIO failed!\n");
ret = RK_RET_DEVICEERR;
}
}
复制代码
这里存在两个问题:1.如果
CAMSYS_REGISTER_DEVIO操作时注册I2C的设备ID已经存在,则注册会失败。看一下内核驱动
kernel/drivers/media/video/rk_camsys/camsys_drv.c
文件的camsys_extdev_register函数
:
extdev = camsys_find_extdev(devio->dev_id, camsys_dev);
if (extdev != NULL) {
err = -EINVAL; /* ddl@rock-chips.com: v0.0x13.0 */
camsys_warn("Extdev(dev_id: 0x%x) has been registered in %s!",
devio->dev_id, dev_name(camsys_dev->miscdev.this_device));
goto end;
}
复制代码
这时
ioctl函数返回值小于0,即
regist_ret小于0,按照上面的逻辑
if(regist_ret==0 && ret<0),已经存在的
I2C的设备无法得到注销,导致以后注册均失败。
问题2:看一下注销调用
ioctl(camsys_fd, CAMSYS_DEREGISTER_DEVIO, &sysctl),这里传入的参数为
sysctl,看一下
camsys_drv.c
文件的
ioctl函数注销操作部分:
case CAMSYS_DEREGISTER_DEVIO:
{
unsigned int dev_id;
if (copy_from_user((void*)&dev_id,(void __user *)arg, sizeof(unsigned int)))
return -EFAULT;
err = camsys_extdev_deregister(dev_id, camsys_dev, false);
break;
}
复制代码
其中的
arg即为传入的参数
sysctl,
copy_from_user函数负责将用户空间的
sysctl拷贝给内核空间的
dev_id变量,显然这里的类型根本不符。再看一下
camsys_extdev_deregister函数的参数定义:
static int camsys_extdev_deregister(unsigned int dev_id, camsys_dev_t *camsys_dev, bool all)
显然也是根据
dev_id来进行设备注销的,所以注销的部分应改为:
regist_err:
if(ret<0){ // if(regist_ret==0 && ret<0)
// unregister device need modify
//err = ioctl(camsys_fd, CAMSYS_DEREGISTER_DEVIO, &sysctl);
err = ioctl(camsys_fd, CAMSYS_DEREGISTER_DEVIO, &extdev.dev_id);
if(err<0){
ALOGE("CAMSYS_DEREGISTER_DEVIO failed!\n");
ret = RK_RET_DEVICEERR;
}
}
复制代码
作者:
plightsup
时间:
2015-1-7 15:35
樓主測試過解決了?
多謝分享心得啊
作者:
isle
时间:
2015-1-7 19:21
感谢分享{:3_61:}
作者:
proboy_li
时间:
2016-11-28 15:52
过路,看看
作者:
若兮听雨
时间:
2017-2-4 10:03
学习
欢迎光临 Firefly开源社区 (https://dev.t-firefly.com/)
Powered by Discuz! X3.1