Firefly开源社区

打印 上一主题 下一主题

MIPI摄像头I2C注销的问题解决

37

积分

0

威望

0

贡献

技术小白

积分
37

MIPI摄像头I2C注销的问题解决

发表于 2015-1-7 10:15:23      浏览:9638 | 回复:4        打印      只看该作者   [复制链接] 楼主
本帖最后由 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函数中:
  1. regist_ret = ioctl(camsys_fd, CAMSYS_REGISTER_DEVIO, &extdev);

  2. if (regist_ret<0) {
  3.     ALOGD("CAMSYS_REGISTER_DEVIO failed\n");
  4.     ret = RK_RET_DEVICEERR;
  5.     goto regist_err;
  6. }
复制代码
     从代码中可以看出当注册失败时会转到
regist_err处:
  1. regist_err:
  2. if(regist_ret==0 && ret<0) {
  3.     // unregister device  need modify
  4.     err = ioctl(camsys_fd, CAMSYS_DEREGISTER_DEVIO, &sysctl);
  5.     if(err<0){
  6.         ALOGE("CAMSYS_DEREGISTER_DEVIO failed!\n");
  7.         ret = RK_RET_DEVICEERR;
  8.     }
  9. }
复制代码
    这里存在两个问题:1.如果
CAMSYS_REGISTER_DEVIO操作时注册I2C的设备ID已经存在,则注册会失败。看一下内核驱动kernel/drivers/media/video/rk_camsys/camsys_drv.c文件的camsys_extdev_register函数
  1. extdev = camsys_find_extdev(devio->dev_id, camsys_dev);
  2. if (extdev != NULL) {
  3.     err = -EINVAL;    /* ddl@rock-chips.com: v0.0x13.0 */
  4.     camsys_warn("Extdev(dev_id: 0x%x) has been registered in %s!",
  5.                devio->dev_id, dev_name(camsys_dev->miscdev.this_device));
  6.     goto end;
  7. }
复制代码
    这时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函数注销操作部分:
  1. case CAMSYS_DEREGISTER_DEVIO:
  2. {
  3.     unsigned int dev_id;
  4.     if (copy_from_user((void*)&dev_id,(void __user *)arg, sizeof(unsigned int)))
  5.         return -EFAULT;

  6.     err = camsys_extdev_deregister(dev_id, camsys_dev, false);
  7.     break;
  8. }
复制代码
    其中的
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来进行设备注销的,所以注销的部分应改为:
  1. regist_err:
  2. if(ret<0){  // if(regist_ret==0 && ret<0)
  3.     // unregister device  need modify
  4.     //err = ioctl(camsys_fd, CAMSYS_DEREGISTER_DEVIO, &sysctl);
  5.     err = ioctl(camsys_fd, CAMSYS_DEREGISTER_DEVIO, &extdev.dev_id);
  6.     if(err<0){
  7.         ALOGE("CAMSYS_DEREGISTER_DEVIO failed!\n");
  8.         ret = RK_RET_DEVICEERR;
  9.     }
  10. }
复制代码







回复

使用道具 举报

23

积分

0

威望

0

贡献

技术小白

积分
23
发表于 2015-1-7 15:35:01        只看该作者  沙发
樓主測試過解決了?
多謝分享心得啊
回复

使用道具 举报

936

积分

20

威望

19

贡献

社区版主

Rank: 7Rank: 7Rank: 7

积分
936
发表于 2015-1-7 19:21:53        只看该作者  板凳
感谢分享{:3_61:}
回复

使用道具 举报

58

积分

0

威望

0

贡献

技术小白

积分
58
发表于 2016-11-28 15:52:31        只看该作者  地板
过路,看看
回复

使用道具 举报

79

积分

0

威望

0

贡献

技术小白

积分
79
发表于 2017-2-4 10:03:05        只看该作者  5#
学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表