高通camera驱动分析

1、Sensor slave配置

结构体msm_camera_sensor_slave_info定义在media/msm_cam_sensor.h中:

struct msm_camera_sensor_slave_info {
char sensor_name[32];              //sensor名称
char eeprom_name[32];              //eeprom名称
char actuator_name[32];              //actuator名称
enum msm_sensor_camera_id_t         camera_id;              //camera id号
uint16_t         slave_addr;              //从地址
enum msm_camera_i2c_reg_addr_type      addr_type;                              //camera i2c寄存器地址类型
struct msm_sensor_id_info_t         sensor_id_info;              //sensor 芯片id信息
struct msm_sensor_power_setting_array     power_setting_array;              //上电序列
uint8_t is_init_params_vaild;             //初始化参数是否有效
struct msm_sensor_init_params         sensor_init_params;             //sensor初始化参数

};

1.1、枚举类型msm_sensor_camera_id_t的定义如下:

enum msm_sensor_camera_id_t {
CAMERA_0, //camera id 号0
CAMERA_1, //camera id 号1
CAMERA_2, //camera id 号2
CAMERA_3, //camera id 号3
MAX_CAMERAS, //支持的最大id号

};

1.2、枚举类型msm_camera_i2c_reg_addr_type的定义如下:

enum msm_camera_i2c_reg_addr_type{
MSM_CAMERA_I2C_BYTE_ADDR  = 1,         //1字节型
MSM_CAMERA_I2C_WORD_ADDR, //2字型
MSM_CAMERA_I2C_3B_ADDR, //3字节型

};

1.3、结构体msm_sensor_id_info_t的定义如下:

struct msm_sensor_id_info_t{
uint16_t sensor_id_reg_addr;         //对应sensor id号的寄存器地址
uint16_t sensor_id; //sensor id号

};

1.4、结构体 msm_sensor_power_setting_array的定义如下:

enum msm_sensor_power_seq_type_t{
SENSOR_CLK,
SENSOR_GPIO,
SENSOR_VREG,
SENSOR_I2C_MUX,
};
struct msm_sensor_power_setting{     //上电序列
enum msm_sensor_power_seq_type seq_type;
uint16_t seq_val;
long config_val;
uint16_t delay;
void *data[10];
};
struct  msm_sensor_power_setting_array{
struct msm_sensor_power_setting *power_setting;
uint16_t          size;
struct msm_sensor_power_setting         *power_down_setting;
uint16_t          size_down;

};

1.5、结构体msm_sensor_init_params的定义如下:

enum camb_position_t{
BACK_CAMERA_B, //后摄
FRONT_CAMERA_B, //前摄
INVALID_CAMERA_B, //非法
}
struct  msm_sensor_init_params{
/* mask of modes supported: 2D, 3D */
int modes_supported;                //支持camera的模式
/* sensor position: front, back */
enum camb_position_t position; //sensor的位置
/* sensor mount angle */
uint32_t sensor_mount_angle; //sensor安装的角度
};

举例:

以下是imx230_lib.c中对sensor初始化参数的设置。

支持模式的值是在枚举类型camerab_mode_t中:
enum camerab_mode_t{
CAMERA_MODE_2D_B = (1<<0), //2D
CAMERA_MODE_3D_B = (1<<1), //3D
CAMERA_MODE_INVALID = (1<<2), //非法
};

2D模式:平面图像模式。
3D模式:拍照出使裸眼观看就具有立体感的图像的模式,需要使用双摄像头。

sensor安装角度的值是宏定义,在sensor_lib.h中:
/*MOUNT ANGLE >= to this value is considered invalid in sensor lib */
#define SENSOR_MOUNTANGLE_360 360         //360度
/* Sensor mount angle. */
#define SENSOR_MOUNTANGLE_0 0 //0度
#define SENSOR_MOUNTANGLE_90 90 //90度
#define SENSOR_MOUNTANGLE_180 180         //180度

#define SENSOR_MOUNTANGLE_270 270         //270度

2.、Sensor 输出设置

2.1 、Sensor输出格式设置

输出格式:Bayer/YUV.
连接模式:parallel/MIPI. msm8974只支持MIPI.

Raw图格式:8/10/12 bits.

imx230分别设置为Bayer、MIPI、10bit。
 

结构体sensor_output_t 定义在sensor_lib.h中:

typedef struct{
sensor_output_format_t output_format; //输出格式
sensor_connection_mode_t connection_mode; //连接模式
sensor_raw_output_t raw_output; //raw图格式
}sensor_output_t;
 

其中sensor_output_format_t, sensor_connection_mode_t, sensor_raw_output_t为枚举类型,定义如下:

typedef enum{
SENSOR_BAYER, //Bayer格式
SENSOR_YCBCR //YUV格式(Y,Cb,Cr)
}sensor_output_format_t;

typedef enum{
SENSOR_PARALLEL, //并行
SENSOR_MIPI_CSI,         //MIPI CSI
SENSOR_MIPI_CSI_1, //CSI1
SENSOR_MIPI_CSI_2, //CSI2
}sensor_connection_mode_t;

typedef enum{
SENSOR_8_BIT_DIRECT,         //8-bit
SENSOR_10_BIT_DIRECT, //10-bit
SENSOR_12_BIT_DIRECT, //12-bit
}sensor_raw_output_t;

10-bit RAW图数据是通过数据包的格式进行传输的,打包之后的数据格式为8-bit。下表是对RAW10数据包格式限制条件的说明,每一个数据包的长度必须是表中数值的整数倍,bit位传输顺序服从CSI-2规则,LSB优先。

2.2 、Sensor像素格式信息

结构体sensor_pix_fmt_info_t定义在sensor_lib.h中:

struct sensor_pix_fmt_info_t {
uint32_t fourcc;
};
 

像素格式的值V4L2_PIX_FMT_SRGGB10是宏定义在linux/videodev2.h中,如下:

/* __u32为unsigned int 型 */
#define  v4l2_fourcc(a,b,c,d) \
((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24) //为什么这么做?

/* www.siliconimaging.com/RGB%20Bayer.htm */
#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') //BGGR 8bit
#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G','B','R','G') //GBRG 8bit
#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G','R','B','G') //GRBG 8bit
#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R','G','G','B') //RGGB 8bit
#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B','G','1','0') //BGGR 10bit
#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G','B','1','0') //GBRG 10bit
#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B','A','1','0') //GRBG 10bit
#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R','G','1','0') //RGGB 10bit
#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B','G','1','2') //BGGR 12bit
#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G','B','1','2') //GBRG 12bit
#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B','A','1','2') //GRBG 12bit
#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R','G','1','2') //RGGB 12bit

像素格式的值MSM_V4L2_PIX_FMT_META是宏定义在media/msm_cam_sensor.h中:

#define MSM_V4L2_PIX_FMT_META v4l2_fourcc('M','E','T','A')
 

2.3 、Sensor输出尺寸设置

结构体sensor_lib_out_info_t用于保存sensor所支持的不同分辨率的信息。imx230_lib.c中使用结构体sensor_lib_out_info_t定义了一个sensor_out_info[]。sensor_out_info[0]保存最大分辨率信息,sensor_out_info[1]保存1/4最大分辨率的信息。
 

2.3.1、 各参数含义解释

结构体sensor_lib_out_info_t的定义如下:
struct sensor_lib_out_info_t {
uint16_t x_output; //sensor 输出宽度(pixels)
uint16_t y_output; //sensor输出高度(pixels)
uint16_t line_lenth_pclk; //每一帧每一行多少个pixels
uint16_t frame_length_lines; //每一帧多少行
uint32_t vt_pixel_clk;         //sensor 扫描速率(pixels per sec)
uint32_t op_pixel_clk;         //sensor实际输出速率(pixels per sec)
uint16_t bining_factor; /*?: 1 if average is taken, >1 if sum is taken(applies only for if this resolution has binnig) */
float min_fps; //sensor支持的最小帧率
float max_fps; //sensor支持的最大帧率
uint32_t mode; //分辨率所对应的模式
};

使用Chromatix软件进行tuning设置Image Width和Image Height的值时分别参考此处x_output和y_output。

line_length_pckl 和frame_length_lines 是指包含blanking的宽度值和高度值。
line_lenth_pclk和frame_length_lines决定帧的大小。
 

什么是blanking?

每一帧图像的每一行输出是遵循CSI2的通用帧格式。每一行的行尾(Packet Footer,PF)到下一行行头(Packet Header,PH)的期间称为“line blanking”。同样的,每一帧的帧尾(Frame End,FE)到下一帧帧头(Frame Start,FS)的期间称为“frame blanking”。

vt_pixel_clk时钟用于内部图像处理,计算曝光时间和帧率等。
曝光时间计算见4.1。
帧率:frame rate = vt_pixel_clk / (line_lenth_pclk * frame_length_lines).
 

op_pixel_clk = (sensor 输出实际比特率)/bits-per-pixel.

比如,如果 MIPI DDR 时钟值 (sensor MIPI 的时钟 lane 频率) 为 300Mhz, 同时 sensor 使用4 个 lane 传输数据, 每一个 lane 的数据率是 300*2 = 600Mhz. 因此, 总数据率为 600*4= 2400Mhz. 对于 10bit 的 bayer sensor, op_pixel_clk 值可设置为 2400/10 = 240Mhz.这些值可以从 sensor 的寄存器设置中计算出来。

其中的mode的值是宏定义的,如下:
/* HFR模式不用于常规的camera,camcorder */
#define SENSOR_DEFAULT_MODE (1 << 0) //默认模式
#define SENSOR_HFR_MODE (1 << 1)         //高帧率模式,用于捕捉慢动作视频
#define SENSOR_HDR_MODE (1 << 2) //高动态范围图像模式

结构体sensor_lib_out_info_array的定义如下:
struct sensor_lib_out_info_array {
struct sensor_lib_out_info_t *out_info; //指向sensor_lib_out_info_t结构体的指针
uint16_t size;         //sensor_lib_out_info_t结构体数组长度
};

ARRAY_SIZE的宏定义如下:
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) //获取数组长度。
 

2.3.2 、x_output & y_output参数设置

x_output和y_output是sensor输出图像的重要参数,分别代表了图像的宽度和高度,单位是pixel。上层camera app最终就是从这里获取的sensor输出图像的宽度和高度信息,然后根据此信息裁剪出各种尺寸的图片。

Camera app照相所支持的图片尺寸在mct_pipeline.c(路径:vendor/qcom/proprietary/mm-camera/mm-camera2/media-controller/mct/pipeline)中定义,如下图:

因此imx230的x_output和y_output参数设置是不能小于上图中的最大尺寸,同时要与实际sensor输出图像的尺寸一致。

Imx230中控制sensor输出图像尺寸的寄存器关系如下图:

由关系图可以看出,最终控制sensor图像输出尺寸的是寄存器X_OUT_SIZE和Y_OUT_SIZE,所以x_output和y_output的值要与这两个寄存器的值一致。

一般sensor提供商所提供的这些寄存器的设置,都是由寄存器X_ADD_STA ,Y_ADD_STA, X_ADD_END和Y_ADD_END所确定的尺寸就是sensor最后输出的尺寸,这样后面的bining、sub-sampling、digtal crop、scaling 处理都可以省去以节约拍照时间。

2.4 、Sensor输出寄存器地址设置

结构体 msm_sensor_output_reg_addr_t的定义如下:
struct msm_sensor_output_reg_addr_t {
uint16_t x_output; //寄存器X_OUT_SIZE地址
uint16_t y_output; //寄存器Y_OUT_SIZE地址
uint16_t line_length_pclk;         //寄存器LIN_LENGTH_PCK地址
uint16_t frame_length_lines; //寄存器FRM_LENGTH_LINES地址
};
 

2.5、 图像裁剪设置

图像裁剪设置主要用到的结构体为sensor_crop_parms_t和sensor_crop_params_arry, sensor_crop_params_t用于保存裁剪的位置信息。定义在sensor_lib.h中:

struct sensor_crop_parms_t {
  uint16_t top_crop; //距离顶部的距离
  uint16_t bottom_crop; //距离底部的距离
  uint16_t left_crop; //距离左侧的距离
  uint16_t right_crop;                    //距离右侧的距离
} ;

struct sensor_lib_crop_params_array{
  struct sensor_crop_parms_t *crop_params; //结构体指针
  uint16_t size; //结构数组长度
};

imx230对于2种分辨率的图像不裁剪。
 

2.6 、分辨率切换设置

imx230使用2种分辨率,枚举类型sensor_res_cfg_type_t说明了进行分辨率切换时所需要进行的操作,在sensor_lib.h中定义如下:

typedef enum {
  SENSOR_SET_STOP_STREAM, //停止数据传输
  SENSOR_SET_START_STREAM, //开始数据传输
  SENSOR_SET_NEW_RESOLUTION, //设置新的分辨率
  SENSOR_SEND_EVENT, //发送事件
  SENSOR_SET_CSIPHY_CFG, //CSIPHY参数设置
  SENSOR_SET_CSID_CFG, //CSID参数设置
  SENSOR_LOAD_CHROMATIX, //加载chromatix参数
} sensor_res_cfg_type_t;

imx230_res_cfg[]数组序列对应着切换分辨率的操作顺序:

停止数据传输 ----> 设置新的分辨率 ----> CSIPHY参数设置 ----> CSID参数设置

----> 加载chromatix参数 ----> 发送事件 ----> 开始数据传输.

3、Camera I2C寄存器设置

I2C寄存器的设置都会用到这两种结构体:msm_camera_i2c_reg_array 和msm_camera_i2c_reg_setting。其定义在media/msm_camera.h中:


struct msm_camera_i2c_reg_array {
uint16_t reg_addr; //寄存器地址
uint16_t reg_data; //寄存器数据
};

struct msm_camera_i2c_reg_setting {
struct msm_camera_i2c_reg_array *reg_setting;   //结构体指针
uint16_t size; //结构数组长度
enum msm_camera_i2c_reg_addr_type addr_type; //地址类型
enum msm_camera_i2c_data_type data_type; //数据类型
uint16_t dalay; //延时
};

其中枚举类型msm_camera_i2c_reg_addr_type在1.2中已经作过介绍了。 msm_camera_i2c_data_type的定义如下:


enum msm_camera_i2c_data_type {
MSM_CAMERA_I2C_BYTE_DATA = 1,
MSM_CAMERA_I2C_WORD_DATA,
MSM_CAMERA_I2C_SET_BYTE_MASK,
MSM_CAMERA_I2C_UNSET_BYTE_MASK,
MSM_CAMERA_I2C_SET_WORD_MASK,
MSM_CAMERA_I2C_UNSET_WORD_MASK,
MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA,
};

3.1、寄存器初始化设置

表现为在相机启动时一组一次性写入的寄存器。init_reg_array[],res0_reg_array[]和res1_reg_arry[]定义在头文imx230_lib.h中。分别对应excel表RegisterSetting中的全局设置和不同分辨率设置的数据。

寄存器初始化流程为:

上电 —> 外部时钟输入 —> XCLR关闭—> 外部时钟寄存器设置 —> 全局寄存器设置 —>  Load Setting

之后寄存器设置根据不同分辨率具有不同的设置。

Load Setting —> 模式设置 —> 输出格式设置 —> 时钟设置 —> Data rate设置 —> 曝光时间设置 —> Gain值设置 —> HDR设置 —> DPC2D设置 —> LSC设? —> Stats 设置
 

3.2 、Grouphold on设置

sensor工作时更新曝光设定需要操作许多寄存器(曝光时间,每帧行数,增益),这些必须在同一帧完成更新。这些寄存器都有双buffer,并具有按组更新的功能。表现为所有相关寄存器一起完成更新。

地址0x0104就是寄存器GRP_PARAM_HOLD的地址,当其寄存器的值设为1时,写入的寄存器数据被暂存的buffer寄存器中。
 

3.3 、Grouphold off设置

当寄存器GRP_PARAM_HOLD的值为0时,所需要寄存器的值会被同时更新,参数的变化会在同一帧生效。
 

3.4、 启动输出设置

MIPI数据包必须以在SoT(Start of Transmission)和EoT(End of Transmission)之间发送。根据参考手册7.1,在正确的时间设定寄存器MODE_SEL(地址0x0100)为1时,开始进行数据输出。

启动数据输出流程分为两种情况:
情况1:在上电之后
(1)准备上电序列时序
(2)PLL锁相环参数设置
(3)初始化设置
(4)设置读取模式(起始/结束位置,大小,曝光时间,gain值)
(5)设置MIPI接口参数
(6)设置寄存器MODE_SEL的值为1,准备数据输出
在经过MIPI唤醒时间和初始化时间之后,开始输出第一帧图像数据。

情况2:在经过一次数据输出之后
(1)设置寄存器MODE_SEL的值为0,进入待命状态
(2)等待MIPI的FE package
(3)设置下一次数据输出模式
(4)设置寄存器MODE_SEL的值为1,准备数据输出
在经过MIPI唤醒时间和初始化时间之后,开始输出第一帧图像数据。
 

3.5、停止输出配置

在正确的时间设定MODE_SEL为0时,结束数据传输。
 

4、曝光设置

4.1 、曝光寄存器地址

结构体msm_sensor_exp_gain_info_t定义在sensor_lib.c中:
struct msm_sensor_exp_gain_info_t {
uint16_t coarse_int_time_addr; //粗曝光时间寄存器地址
uint16_t global_gain_addr; //模拟增益寄存器地址
uint16_t vert_offset; //曝光行偏置
};

粗曝光时间单位为lines,用于计算曝光时间,计算关系如下:

Tsh = Tline * (COARSE_INTEG_TIME + FINE_INTEG_TIME / LINE_LENGTH_PCK)

其中细曝光时间单位为pixels,是定值,其寄存器为只读寄存器。Tline为行曝光时间,为时间单位。计算如下:

Tline = LINE_LENGTH_PCK * VTPXCK_period


曝光行偏置用于设定以下关系:

COARSE_INTEG_TIME ≤ frame_length_lines – vert_offset


4.2、 AEC参数设置

结构体sensor_aec_data_t定义在sensor_lib.h中:
typedef enum {
  SENSOR_MODE_SNAPSHOT, //快照模式
  SENSOR_MODE_RAW_SNAPSHOT, //raw图快照模式
  SENSOR_MODE_PREVIEW, //预览模式
  SENSOR_MODE_VIDEO, //视频录像模式
  SENSOR_MODE_VIDEO_HD, //高清视频录像模式
  SENSOR_MODE_HFR_60FPS, //60帧率HFR模式
  SENSOR_MODE_HFR_90FPS, //90帧率 HFR模式
  SENSOR_MODE_HFR_120FPS, //120帧率HFR模式
  SENSOR_MODE_HFR_150FPS, //150帧率HFR模式
  SENSOR_MODE_ZSL, //零秒快拍
  SENSOR_MODE_INVALID, //非法
} sensor_mode_t;


typedef struct {
  sensor_mode_t op_mode; //sensor 模式
  uint32_t pixels_per_line; //每一帧每一行多少个pixels
  uint32_t lines_per_frame;         //每一帧多少行
  uint32_t pclk; //vt_pixel_clk
  uint32_t max_fps; //最大帧率
  float digital_gain; //数字增益
  float stored_digital_gain;
  float max_gain; //最大数字增益
  uint32_t max_linecount; //最大曝光行数

} sensor_aec_data_t;

4.3 、曝光增益gain值设置

AEC算法中模拟增益gain用于曝光计算,实际上必须把gain转换成寄存器gain去设置sensor。以下是imx230的gain转换函数:

模拟增益real_gain值的范围是1至8, 对应到reg_gain的范围为0到448。real_gain与reg_gain的关系为:
real_gain = 512 / (512 - reg_gain)

结构体sensor_exposure_info_t定义在sensor_lib.h中:
typedef struct {
uint16_t reg_gain; //寄存器gain值
uint16_t line_count; //曝光行数
float digital_gain;
float sensor_real_gain; //sensor的模拟gain值
float sensor_digital_gain;         //sensor的数字gain值
} sensor_exposure_info_t;

5、镜头参数设置

结构体sensor_lens_info_t定义在sensor_lib.c中:
typedef struct {
float focal_length; //焦距
float pix_size; //像素大小
float f_number;         //光圈
float total_f_dist;
float hor_view_angle; //水平视角
float ver_view_angle; //垂直视角
} sensor_lens_info_t;
 

6、Chromatix参数

每一种分辨率都必须有对应的chromatix库文件。这里对应2种分辨率,设置的是相应的库文件名称。

结构体sensor_lib_chromatix_t定义在sensor_lib.h中:
struct sensor_lib_chromatix_t {
char *common_chromatix;
  char *camera_preview_chromatix;
  char *camera_snapshot_chromatix;
  char *camcorder_chromatix;
  char *liveshot_chromatix;
};
其数据成员都是字符型指针,用来记录不同分辨率下不同模式的库文件名称。
 

7. MIPI接收器配置

7.1 、CSI lane参数配置

结构体 csi_lane_params_t定义在media/msm_camera.h中:

struct csi_lane_params_t {
uint16_t csi_lane_assign;                //端口映射设置
uint8_t csi_lane_mask; //标识哪一个lane被使用
uint8_t csi_if; //未使用
uint8_t csid_core[2];         //csid硬件选择
uint8_t csi_phy_sel;        //csi-phy设备选择
};
csi_lane_assign —— 有时候用户的MIPI lanes可能使用不同与MSM参考设置的端口映射。比如,sensor的lane0连接到MSM的数据lane4等。对于这种情况,csi_lane_assign参数能设置正确的端口映射。csi_lane_assign是一个16bit的值,每位的含义参见下表。lane1用于MIPI时钟,客户不可用它来映射到任何数据lane。

csi_lane_mask —— 用于表示哪些lane被使用,这是一个8位值,每一位含义如下:

Bit position Represents
7:5 保留
4 数据lane4是否使用:
- 0 :不
- 1 :是
3 数据lane3是否使用:
- 0 :不
- 1 :是
2 数据lane2是否使用:
- 0 :不
- 1 :是
1 数据lane1是否使用:
- 0 :不
- 1 :是
注意:该位必须设置为1
0 数据lane0是否使用:
- 0 :不
- 1 :是

比如0x1F表示4条数据lane和时钟都被使用。

csi_if —— 暂不使用。
csid_core —— 设置哪个CSID硬件被该sensor使用。两个并发的sensor不能使用同一个CSID硬件。
csi_phy_sel —— 设置哪个CSI-PHY硬件被该sensor使用。对于每一个sensor来说必须是独一无二的,除非有额外的MIPI桥连接两个sensor到同一个PHY接口上。

7.2 、虚拟通道设置

CSI2传输的数据包包头部分的起始1byte为数据标志符(Data Identifier, DI),由VC[7:6](Virtual Channel)和DT[5;0](Data Type)组成。通过不同的VC和DT值来标志不同的数据流,占2个bit位的虚拟通道VC允许最多4个数据流交叉传输,其取值范围为0~3.

下表表示不同的TD的取值及对应的数据格式。

结构体 msm_camera_csid_vc_cfg用于保存虚拟通道的设置信息,在media/msm_camera.h中定义:


struct msm_camera_csid_vc_cfg {
uint8_t cid; //通道号
uint8_t dt; //数据类型
uint8_t decode_format; //解码格式
};


imx230的设置如下:


其数据类型和解码格式的值是宏定义的,其中数据类型的宏定义是根据上述DT表得来的。如下:


#define CSI_EMBED_DATA 0x12
#define CSI_RESERVED_DATA_0 0x13
#define CSI_YUV422_8 0x1E
#define CSI_RAW8 0x2A
#define CSI_RAW10 0x2B
#define CSI_RAW12 0x2C


#define CSI_DECODE_6BIT 0
#define CSI_DECODE_8BIT 1
#define CSI_DECODE_10BIT 2
#define CSI_DECODE_DPCM_10_8_10 5

7.3 、数据流设置

typedef struct _sensor_stream_info_t {
  uint16_t vc_cfg_size;
  struct msm_camera_csid_vc_cfg *vc_cfg;      //虚拟通道设置
  struct sensor_pix_fmt_info_t *pix_fmt_fourcc;//像素格式
} sensor_stream_info_t;


typedef struct _sensor_stream_info_array_t {
  sensor_stream_info_t *sensor_stream_info;
  uint16_t size;
} sensor_stream_info_array_t;

7.4、 CSID和CSI-PHY参数设置

struct msm_camera_csid_lut_params {
uint8_t num_cid; //虚拟通道个数
struct msm_camera_csid_vc_cfg *vc_cfg;             //虚拟通道参数
};
struct msm_camera_csid_params {
uint8_t lane_cnt; //使用lane的数目
uint16_t lane_assign;
uint8_t phy_sel;
struct msm_camera_csid_lut_params lut_params;
};
struct msm_camera_csiphy_params {
uint8_t lane_cnt;
uint8_t settle_cnt;
uint16_t lane_mask;
uint8_t combo_mode;
uint8_t csid_core;
};

struct msm_camera_csi2_params {
struct msm_camera_csid_params csid_params; //CSID参数
struct msm_camera_csiphy_params csiphy_params;                 //CSI-PHY参数
};

lane_cnt ——有多少数据 lane 用于数据传输. 该值必须在 sensor 最大能力范围内,而且sensor 寄存器设置必须与该 lane 数匹配.

settle_cnt ——该值须和 sensor 的特性匹配, 保证 sensor 的 MIPI 传输和 MSM 的 MIPI 接收能同步.

客户可以对不同的分辨率模式使用不同CSI 参数设置。imx230采用两种分辨率,但是使用相同的CSI设置。
 

8、imx230_ofilm_open_lib

在imx230_lib.c中,最后将所有的参数设置都放入sensor_lib_t类型的结构体sensor_lib_ptr中,定义函数imx230_ofilm_open_lib()来返回sensor_lib_ptr的地址,供外界调用。

结构体sensor_lib_t涵盖了关于camera设置的几乎全部信息。如下:
typedef struct {
  /* sensor slave info */
  struct msm_camera_sensor_slave_info *sensor_slave_info;
  /* sensor info */
  struct msm_sensor_init_params *sensor_init_params;
  /* name of the AF actuator (if any)*/
  char* actuator_name;
  /* name of the eeprom (if any)*/
  char* eeprom_name;
  /* sensor output settings */
  sensor_output_t *sensor_output;
  /* sensor output register address */
  struct msm_sensor_output_reg_addr_t *output_reg_addr;
  /* sensor exposure gain register address */
  struct msm_sensor_exp_gain_info_t *exp_gain_info;
  /* sensor aec info */
  sensor_aec_data_t *aec_info;
  /* sensor snapshot exposure wait frames info */
  uint16_t snapshot_exp_wait_frames;
  /* number of frames to skip after start stream info */
  uint16_t sensor_num_frame_skip;
  /* number of frames to skip after start HDR stream info */
  uint16_t sensor_num_HDR_frame_skip;
  /* sensor pipeline delay */
  uint32_t sensor_max_pipeline_frame_delay;
  /* sensor exposure table size */
  uint16_t exposure_table_size;
  /* sensor lens info */
  sensor_lens_info_t *default_lens_info;
  /* csi lane params */
  struct csi_lane_params_t *csi_lane_params;
  /* csi cid params */
  struct msm_camera_csid_vc_cfg *csi_cid_params;
  /* sensor port info that consists of cid mask and fourcc mapaping */
  sensor_stream_info_array_t *sensor_stream_info_array;
  /* csi cid params size */
  uint16_t csi_cid_params_size;
  /* init settings */
  struct sensor_lib_reg_settings_array *init_settings_array;
  /* start settings */
  struct msm_camera_i2c_reg_setting *start_settings;
  /* stop settings */
  struct msm_camera_i2c_reg_setting *stop_settings;
  /* group on settings */
  struct msm_camera_i2c_reg_setting *groupon_settings;
  /* group off settings */
  struct msm_camera_i2c_reg_setting *groupoff_settings;
  /* resolution config table */
  struct sensor_res_cfg_table_t *sensor_res_cfg_table;
  /* resolution settings */
  struct sensor_lib_reg_settings_array *res_settings_array;
  struct sensor_lib_out_info_array     *out_info_array;
  struct sensor_lib_csi_params_array   *csi_params_array;
  struct sensor_lib_crop_params_array  *crop_params_array;
  struct sensor_lib_chromatix_array    *chromatix_array;
  /* video_hdr mode info*/
  struct sensor_lib_meta_data_info_array *meta_data_out_info_array;
  /* exposure funtion table */
  sensor_exposure_table_t *exposure_func_table;
  /* exposure info */
  sensor_exposure_info_t exposure_info;
  /* flag to sync exp and gain */
  uint8_t sync_exp_gain;
  /* video hdr func table */
  sensor_video_hdr_table_t *video_hdr_awb_lsc_func_table;
  /* scale size tbl count*/
  uint8_t scale_tbl_cnt;
  /* function to get scale size tbl*/
  int32_t (*get_scale_tbl)(msm_sensor_dimension_t *);
  /* supported Scene mode */
  uint32_t *sensor_supported_scene_mode;
  /* supported effect mode */
  uint32_t *sensor_supported_effect_mode;
  /* sensor pipeline immediate delay */
  uint32_t sensor_max_immediate_frame_delay;
  /* library specific data */
  void *data;
} sensor_lib_t;
 

<think>首先,用户的问题是关于“如何分析高通Camera驱动日志以定位问题”。用户提到了高通Camera驱动相关日志查找bug的方法,所以我需要基于这个来构建回答。 从系统级指令中,我需要: - 所有行内数学表达式使用 $...$ 格式。 - 独立公式使用 $$...$$ 格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如 [^1]。 用户可见层指令: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 参考提供的引用: - 引用[1] 是关于高通Camera调试流程,包括相机无法启动的问题解决方案。 - 引用[2] 是关于高通Camera驱动调试要点,特别是VFE总线溢出日志的分析。 我的回答应该基于这些引用,但用户说“上述引用仅供参考,并不是用户真正的需求”,所以我需要专注于用户的问题:分析高通Camera驱动日志以定位问题。 结构化回答: 1. **介绍**:简要解释高通Camera驱动日志的重要性。 2. **步骤**:逐步指导如何分析日志。 3. **常见问题**:基于引用,讨论一些常见问题如相机无法启动或总线溢出。 4. **引用**:在相关部分添加引用标识。 5. **生成相关问题**:在最后添加相关问题部分。 关键点从引用中提取: - 从引用[1]:检查权限、硬件、日志错误信息。 - 从引用[2]:分析VFE总线溢出日志,找到具体来源,如写入主控和映射关系。 回答结构: - **步骤1: 收集日志** – 解释如何获取内核日志。 - **步骤2: 分析常见错误** – 如相机无法启动、总线溢出。 - **步骤3: 具体调试方法** – 如添加调试日志(如引用[2]中的代码修改)。 - **步骤4: 工具和技巧** – 使用工具分析日志。 确保使用中文。 生成相关问题:在最后添加几个相关问题,如: 1. 如何优化高通Camera驱动以减少总线溢出? 2. 高通Camera驱动中常见的日志错误有哪些? 3. 如何修改内核代码以添加调试日志? 最后,添加引用标识: - 在引用引用[1]的地方加 [^1] - 在引用引用[2]的地方加 [^2] 完整回答结构: 1. 引言 2. 分析步骤 3. 常见问题示例 4. 总结 5. 相关问题</think>### 如何分析高通Camera驱动日志以定位问题 分析高通Camera驱动日志是调试相机问题的关键步骤,尤其是在定位硬件兼容性、驱动错误或性能瓶颈时。以下我将基于高通平台的典型调试流程,逐步指导您如何有效分析日志。整个过程需要结合内核日志(dmesg 或 logcat)、错误信息以及可能的代码修改。请确保您已获取完整的日志文件(通常通过 `adb logcat` 或 `dmesg` 命令收集),并拥有 root 权限以访问详细输出。 #### 步骤1: 日志收集与初步筛选 - **收集日志**:使用 ADB 工具获取内核日志。例如: ```bash adb logcat -b kernel > camera_log.txt ``` 这会将内核缓冲区的日志输出到文件。如果问题发生在相机启动阶段,优先捕获启动时的日志(如相机应用崩溃瞬间)。 - **筛选关键字段**:高通Camera驱动日志通常包含特定标签,如 `msm_camera` 或 `VFE`(视频前端引擎)。使用 grep 命令过滤相关条目: ```bash grep -iE "camera|vfe|isp" camera_log.txt ``` 这能快速定位错误源头,避免信息过载[^1]。 #### 步骤2: 分析常见错误模式 高通Camera驱动日志中的错误通常分为几类,以下是典型问题及分析方法: - **相机无法启动**(如应用崩溃或界面不显示): - 检查日志中的权限错误:查找如 `permission denied` 或 `camera HAL error` 的条目。如果日志显示权限问题,需确保应用已正确申请相机权限(Android 中需动态请求)[^1]。 - 验证硬件状态:日志中出现 `hardware failure` 或 `sensor timeout` 时,可能是硬件故障。尝试重启设备并复现问题,如果日志持续显示驱动加载失败(如 `msm_camera: probe failed`),则需检查硬件连接或更换模块[^1]。 - 示例分析:如果日志包含 `camera open failed`,可能源于驱动初始化错误。追溯驱动加载序列(从 `probe` 函数开始),检查传感器配置是否正确。 - **VFE总线溢出**(常见于高分辨率或ZSL模式): - 识别溢出源头:日志中如 `VFE bus overflow` 表示数据流溢出。关键是要找到首个溢出实例(日志中的第一个相关错误),因为它指向问题根源。例如,引用[2]提到: > 内核日志显示的首个溢出实例就显得非常重要,可以帮助确认溢出来源[^2]。 - 映射数据流:分析日志中写入主控(WM)与输出帧的关联。例如,如果溢出发生在预览流(preview),则忽略快照流(snapshot)。日志中的 `WM[ ]` 条目(如 `WM[0] ENABLE`)可帮助确认数据流路径。添加调试日志(如下述代码修改)能增强可见性[^2]。 - 量化溢出原因:检查日志中的带宽参数,如 `max_width` 或 `frame rate`。如果 `max_width` 值过高(如 4K),可能导致总线饱和。计算总线带宽需求: $$ \text{带宽} = \text{分辨率} \times \text{帧率} \times \text{色彩深度} $$ 例如,1080p@30fps 的带宽约为 $1920 \times 1080 \times 30 \times 2 \times 8$ 位,超出硬件限制时会触发溢出日志。 #### 步骤3: 深入调试与代码级分析 如果初步分析无效,需结合代码修改添加详细日志: - **添加调试日志**:修改内核驱动文件(如 `msm_isp_axi_util.c`),插入打印语句以跟踪数据流状态。引用[2]提供了示例: ```c // 在驱动代码中添加错误日志 if (stream_info->state == START_PENDING) { pr_err("__debug__: WM[%d] ENABLE, src = %d, max_width = %u\n", ...); } else { pr_err("__debug__: WM[%d] DISABLE, src = %d, max_width = %u\n", ...); } ``` 重新编译内核并捕获日志,这能清晰显示每个WM(写入主控)的启用/禁用状态,帮助定位溢出或死锁点[^2]。 - **使用工具辅助**:结合高通提供的工具如 QXDM 或 Trepn Profiler,分析日志中的时间戳和中断延迟。如果日志显示 `IRQ latency` 过高,可能需优化驱动调度算法。 - **常见陷阱**:日志中连续出现 `timeout` 或 `watchdog reset` 时,检查电源管理(如 PMIC 日志)或时钟频率设置。高通平台中,时钟不稳定常导致数据丢失。 #### 步骤4: 验证与解决 - **复现与隔离**:在修改代码或配置后,复现问题并比较日志变化。如果溢出减少,说明优化有效。 - **性能调优**:基于日志分析,调整参数如降低分辨率(减少 $max_width$)或启用压缩。如果日志显示硬件限制,考虑更换模块。 - **参考文档**:高通提供 Camera HAL 文档和调试指南,结合日志中的错误码(如 `error 0x5`)查询官方手册。 #### 总结 分析高通Camera驱动日志的核心是:收集完整日志、筛选关键错误、映射数据流,并在必要时添加调试代码。通过首个错误实例定位根源(如VFE溢出),能高效解决相机无法启动或性能问题[^1][^2]。如果问题持续,建议分享日志到高通社区或使用 QPST 工具进行深度诊断。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

产品人卫朋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值