高温条件下打不开摄像头

2019-11-04  本文已影响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做的事情挺多的。

上一篇下一篇

猜你喜欢

热点阅读