高温条件下打不开摄像头
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做的事情挺多的。