美文网首页
高温条件下打不开摄像头

高温条件下打不开摄像头

作者: 窝窝蜗牛 | 来源:发表于2019-11-04 20:51 被阅读0次

    最近碰到一个问题,在高温条件下存储手表后打不开摄像头,查看log

    <3>[   29.961197] msm_sensor_match_id: read id: 0x487b expected id 0x487b:
    <3>[   29.961211] s5k4h7 probe succeeded
    

    可以确定内核能读到sensor id,可以排除大概率与硬件没有问题。同时,可以看到:

    02-21 17:31:17.881  3094  3094 I CameraController: camera open failed,getNumberOfCameras cameraCount:0
    

    说明上层得到的camera count数量为0,明明读取到了id,得到的sensor数量却是0,是在让人费解,日志中继续查找线索:

    <3>[   28.940422] MSM-SENSOR-INIT msm_sensor_wait_for_probe_done:53 msm_sensor_wait_for_probe_done:53 wait timeout
    

    追踪代码,查看msm_sensor_wait_for_probe_done的实现

    static int msm_sensor_wait_for_probe_done(struct msm_sensor_init_t *s_init)
    {
        int rc;
        int tm = 20000;
        if (s_init->module_init_status == 1) {
            CDBG("msm_cam_get_module_init_status -2\n");
            return 0;
        }
        rc = wait_event_timeout(s_init->state_wait,
            (s_init->module_init_status == 1), msecs_to_jiffies(tm));
        if (rc == 0)
            pr_err("%s:%d wait timeout\n", __func__, __LINE__);
    
        return rc;
    }
    

    此处超时,先看下它超时会导致什么,追踪到调用顶层:

    uint8_t get_num_of_cameras()
    {
        ...
          /* Open sensor_init subdev */
        sd_fd = open(subdev_name, O_RDWR);
        if (sd_fd < 0) {
            CDBG_ERROR("Open sensor_init subdev failed");
            return FALSE;
        }
    
        cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE;
        cfg.cfg.setting = NULL;
        if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
            CDBG_ERROR("failed");
        }
        ...
        get_sensor_info();
    }
    

    可以看出是hal层获取camera数量时,打开sensor_init子设备,然后等待probe done,最终去获取sensor信息,得到sensor num。所以由于等待超时此时probe并未结束,所以获取的sensor num自然也是0。为什么知道等待的是probe done,可以追寻等待的信号量s_init->state_wait,守护进程等待所有的module 初始化结束后,发送CFG_SINIT_PROBE_DONE 给内核,内核将此信号量激活:

      cfg.cfgtype = CFG_SINIT_PROBE_DONE;
      if (ioctl(probe_done_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
        CDBG_ERROR("%s: failed\n", __func__);
        ret = FALSE;
      }
      close(probe_done_fd);
    
    static int32_t msm_sensor_driver_cmd(struct msm_sensor_init_t *s_init,
        void *arg)
    {
      ...
      switch (cfg->cfgtype) {
        case CFG_SINIT_PROBE_DONE:
          s_init->module_init_status = 1;
          wake_up(&s_init->state_wait);
      }
      ...
    }
    

    至于为什么会导致超时,据说是一个散热策略,使得camera线程的一些事情不能按时执行,毕竟守护进程端的module init做的事情挺多的。

    相关文章

      网友评论

          本文标题:高温条件下打不开摄像头

          本文链接:https://www.haomeiwen.com/subject/frqjbctx.html