高通camera模块的启动过程

Camera驱动Vendor sensor部分启动初始化过程

mm-qcamera-daemon进程:

vendor\qcom\proprietary\mm-camera\mm-camera2\server-imagingserver.c的int main(int argc __unused, char *argv[] __unused)函数:

1.查找server节点:查找mdev_info.model=="msm_config"的/dev/media0-x节点,找到挂在它下面entity.type == MEDIA_ENT_T_DEVNODE_V4L &&

entity.group_id == QCAMERA_VNODE_GROUP_ID)的entity,这个entity.name就是server节点名称,一般是/dev/video0;它的注册是在msm.c中的msm_probe()函数

2.初始化驱动的六大模块:”sensor”,”iface”,”isp”,”stats”,”pproc”,”imglib”

函数server_process_module_init():每个模块采用同样的结构体和函数集合, 通过每个模块的mct_module_init_name_t->init_mod函数获取mct_module_t的实例,之后要对某个模块操作就通过调用mct_module_t的实例的函数集合。在sensor模块的mct_module_init_name_t->init_mod函数中就会执行sensor的查找匹配等操作。

3.往kernel的sensor节点设置probe完成的标志

4.while代码处理时间

Sensor模块的启动过程

vendor\qcom\proprietary\mm-camera\mm-camera2\media-controller\modules\sensors\module\module_sensor.c:

步骤大概分为eebin, sensor, eeprom

1创建mct_module_t的实例并对函数集合赋值:

s_module->set_mod = module_sensor_set_mod;

s_module->query_mod = module_sensor_query_mod;

s_module->start_session = module_sensor_start_session;

s_module->stop_session = module_sensor_stop_session;

s_module->set_session_data = module_sensor_set_session_data;

s_module->get_session_data = module_sensor_get_session_data;

2eebin_interface_control():

- qcom,cmm-data-support - Camera MultiModule data capability flag.

- qcom,cmm-data-compressed - Camera MultiModule data compression flag.

- qcom,cmm-data-offset - Camera MultiModule data start offset.

- qcom,cmm-data-size - Camera MultiModule data size

3.. sensor_init_probe():

找到entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT的节点,这个节点在kernel中的msm_sensor_init.c节点注册。

最重要的函数sensor_init_xml_probe(module_sensor_ctrl_t *module_ctrl,  int32_t sd_fd) :读取/vendor/etc/camera/camera_config.xml并解析

2

ov2680

ov2680_chromatix

1

FRONT

90

1

0x3

0x4320

0

1.98

2.4

1.2

68.0

51.0

0.1

1)      根据sensorname,导入对应的驱动库例如libmmcamera_s5k4h8.so,调用sensor_open_lib获取该sensor的信息和函数集合,然后往kernel的sensor init的节点发送VIDIOC_MSM_SENSOR_INIT_CFG命令,这个命令在kernel的msm_sensor_driver.c的msm_sensor_driver_probe()执行,vendor传下来的camera id变成底下的g_sctrl[slave_info->camera_id](如果有一二供兼容,这块的架构可能要改);另外会去关联eeprom、actuator、ois、flash的cell-index;s_ctrl->func_tbl->sensor_power_up上电的时候会去读id,id判断成功则会调用msm_sensor_driver_create_v4l_subdev生成需要的各种节点(video, subdev),返回给vendor的session id就是注册/dev/videox生成的device node number

2)      sensor_create_sbundle():创建该模组对应的module_sensor_ctrl_t实例。

4子设备节点的查找:

module_sensor_find_other_subdev()

(entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&

(entity.group_id == MSM_CAMERA_SUBDEV_ACTUATOR ||

entity.group_id == MSM_CAMERA_SUBDEV_EEPROM ||

entity.group_id == MSM_CAMERA_SUBDEV_FLASH ||

entity.group_id == MSM_CAMERA_SUBDEV_STROBE_FLASH ||

entity.group_id == MSM_CAMERA_SUBDEV_CSIPHY ||

entity.group_id == MSM_CAMERA_SUBDEV_CSID ||

entity.group_id == MSM_CAMERA_SUBDEV_OIS ||

entity.group_id == MSM_CAMERA_SUBDEV_EXT))

5 每个sensor模组的子设备函数表的初始化

module_sensors_subinit()

typedef struct {

int32_t (*open)(void **, void *);

int32_t (*process)(void *, sensor_submodule_event_type_t, void *);

int32_t (*close)(void *);

} sensor_func_tbl_t;

6枚举并创建每个模组的mct_port,链接到s_module-> srcports上。

port_sensor_create()

获取每个模组的驱动中sensor_stream_info_array数据,里面包含几个port以及 每个port下多少个channel,然后创建mct_port,挂到整个sensor  module的srcports上

.sensor_stream_info_array =

{

.sensor_stream_info =

{

{

.vc_cfg_size = 1,

.vc_cfg =

{

{

.cid = 0,

.dt = CSI_RAW10,

.decode_format = CSI_DECODE_10BIT

},

},

.pix_data_fmt =

{

SENSOR_BAYER,

},

},

},

.size = 1,

},

7.对每个sensor获取eeprom数据

module_sensor_init_eeprom()初始化、读取、格式化eeprom数据

8对每个sensor的chromatix数据导入、eeprom数据应用

module_sensor_init_chromatix():调用cm_create();

这个函数会将s5k4h8_chromatix.xml中的common、resolution 0-x下的各种场景(isp、cpp、a3)配置导入到hash表中;

其中chromatix_info是在sensor_util_xml.c的sensor_xml_util_parse_chromatix_name()下赋值的,时间sensor_bundle创建的时候;

rc = addLib(cm, chromatix_name->isp_common, EEPROM_CALIBRATE_LSC);功能是导入isp_common的库,并用EEPROM中的lsc数据替换导入的该部分数据。在导入库的函数addLib_getSymbol()的过程中,会调用int32_t load_chromatix(const char *name, const char *path, void **handle, void **symbol),这个函数的实现是在chromatix_sub_module.c中,在这个实现中会去调用path对应的库的void *load_chromatix(void)。还会调用(cm->eeprom_func))->process( cm->eeprom_ctrl, cal_type, data_sym)去替换cal_type对应的数据。

Camera驱动vendor  sensor  start  session过程

module_sensor_start_session():

sensor_thread_create():处理SET_AUTOFOCUS和OFFLOAD_FUNC(降低主线程负载)两个事件

module_sensor_init_session():

1)   初始化s_bundle->frame_ctrl.frame_ctrl_q;

2)   对每个sub dev调用open函数

3)   SUB_MODULE_CHROMATIX处理CHROMATIX_SET_CM事件

4)   SUB_MODULE_ACTUATOR处理ACTUATOR_SET_EEBIN_DATA

5)   module_sensor_offload_init_config():SUB_MODULE_SENSOR处理SENSOR_INIT事件,处理各种初始化变量

6)   SUB_MODULE_SENSOR处理SENSOR_SET_FORMATTED_CAL_DATA事件

管道

分为无名管道(父母兄弟进程)和命名管道

Int pipe(int fd[2]):  fd[0]:用于读出数据;  fd[1]:用于写入数据

struct pollfd   pollfds={

pollfds.fd = fd[0]

pollfds.events = POLLIN|POLLPRI;

};

Int ready = Poll(&pollfds, 1, -1);

Int read_bytes = read(pollfds.fd, &event, sizeof(isp_trigger_thread_event_t));

write(fd[1], &trigger_thread_event, sizeof(trigger_thread_event));

(0)

相关推荐