我是靠谱客的博主 刻苦心锁,最近开发中收集的这篇文章主要介绍展讯-sensor driver,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

展讯平台其既用于功能机也用于智能机。其65和66系列的平台主要用于功能机,例如6530、6531、6500、6610、6620、6600L;68和88系列的平台主要用于智能机,例如SC6810、SC6820、SC6800、SC8820、SC8810。目前我们使用的样机为SC8825,搭配GC2235。

         在进行平台下载时需要像高通平台一样进入fastboot mode才能进行下载烧录。烧录步骤:

1、 使用shell终端进入工程根目录,执行脚本copy.sh将img文件copy到上层文件夹sp_bin中。

2、 连接usb线,开机状态下使用adb命令adb reboot‐bootloader,进入fastboot mode。

3、 烧录boot、system、userdata文件,指令为:

fastboot flash boot d:boot.img

fastboot flash system d: system.img

fastbootflash userdata d: userdata.img

fastboot reboot    红色为文件路径,修改为自己文件所在路径

         编译展讯平台的步骤进行简化,以后编译驱动和库文件只需要在根目录下执行 .  mk.sh命令就可以进行编译。其中点(.)和mk.sh之间必须有空格,否则不能执行。

展讯平台的sensor驱动(我们提供的)主要存放于根目录下:

device/sprd/common/libs/libcamera/sensor/

分别为:

sensor_gcxxxx.c

sensor_gcxxxx_raw_param.c

sensor_gcxxxx_mipi_raw.c

sensor_gcxxxx_mipi_raw_param.c

而关于驱动中使用变量的定义在文件是

device/sprd/common/libs/libcamera/isp/inc/sensor_raw.h

其中sensor_gcxxxx.c、sensor_gc2235_raw_param.c是DVP接口的驱动,sensor_gcxxxx_mipi_raw.c、sensor_gcxxxx_mipi_raw_param.c是Mipi接口的驱动。关于sensor控制的函数、寄存器值的写入主要在sensor_gcxxxx.c中,例如_gc2235_write_gain()函数是写入平台gain;_gc2235_write_exposure是写入Shutter,数组gc2235_com_raw[]是存放sensor初始化寄存器值(如图1),前边是地址,后边的是值。

                     

                                                                          图1

展讯在出错的时候不同于MTK以LOG文件形式记录,它在出错的时候是直接显示在shell终端窗口上,出错时如果错误过多,将冲掉错误信息的前半部分(shell只记录有限长度的一段)。同时,在展讯上看手机活动的log的方法如下:

adb devices

adb logcat>D:ksng     (红色部分是windows下保存的log的路径)

       展讯平台中关于sensor的驱动底层部分平台提供的)位于devicesprdcommonlibslibcamera下的使用的平台文件夹下,例如样机用的是SC8825,那样机用的驱动就在sc8825问价夹下。驱动分为两个部分src(.c)、inc(.h),sensor中所有操作函数均在改这里实现。函数列表如图2所示。

                                    图2

         追踪了一下log,查看了手机调用sensor过程中的步骤。

android::HAL_camera_device_open(consthw_module_t*, const char*, hw_device_t**)

打开摄像头驱动

android::HAL_getNumberOfCameras()//获得当前camera数目

initDefaultParameters

//初始化参数(这些参数是app层的选项参数)   包括whitebalance、picture-size、preview-size、exposure等 .解析了一段,发现与kernel交叉太多,解不动了。(待续)

一、详解

         1、驱动中数据的认识与还原

1.1关于驱动中使用的数据多使用SENSOR_I2C_T_PTR、SENSOR_REG_T_PTR、SENSOR_REG_BITS_T_PTR样式的结构体,这些结构体一般都是定义响应的寄存器地址、寄存器值、寄存器个数、寄存器位数等信息。例如SENSOR_I2C_T_PTR的定义为:

typedef struct sensor_i2c_tag {

                                       uint8_t  *i2c_data;//指针,指向要写入的数据头

                                       uint16_ti2c_count;//要写入数据的个数

                                       uint16_tslave_addr;//i2c读写地址

} SENSOR_I2C_T, *SENSOR_I2C_T_PTR; 

这些结构体的定义均在sensor_druv.h中,需要的时候可以查询相应位的含义。

         1.2其他的一些功能结构体,例如SENSOR_REG_TAB_INFO_T、SENSOR_TRIM_T、SENSOR_IOCTL_FUNC_TAB_T、SENSOR_INFO_T等结构体。现在逐一对其分析,了解这些结构体,不要这这些掩盖了数据的真实含义。

typedefstruct sensor_reg_tab_info_tag {

         SENSOR_REG_T_PTRsensor_reg_tab_ptr;//要初始化的寄存器(指针,指向链表、数组首地址)

         uint32_treg_count;//寄存器数目

         uint16_twidth;//出图的宽度

         uint16_theight;//出图的高度

         uint32_txclk_to_sensor;//Mclk

         SENSOR_IMAGE_FORMATimage_format;//输出图像格式

} SENSOR_REG_TAB_INFO_T,*SENSOR_REG_TAB_INFO_T_PTR;

 

                                                                             图3

例如在gc2235中:这是一个结构体数组(如图3所示),数组的每一个元素都是一个SENSOR_REG_TAB_INFO_T_PTR结构体(依旧不清楚为何前两个完全一样,后边的全是空的),在第一个元素中ADD_AND_LEN_OF_ARRAY是为了获得寄存器的头和个数。具体定义为:#define ADDR_AND_LEN_OF_ARRAY(a)        (SENSOR_REG_T*)a,NUMBER_OF_ARRAY(a),也就是获得gc2235_mipi_com_raw(图1所示)中寄存器的个数和首地址;1600为gc2235出图宽度;1200为高度;24为Mclk;sensor_TMAGE_FORMAT_RAW出图格式为raw。

typedef struct sensor_trim_tag {

         uint16_ttrim_start_x; //坐标x

         uint16_ttrim_start_y;//坐标Y

         uint16_ttrim_width;//宽

         uint16_ttrim_height;//高

         uint32_tline_time;//重要, Line Time =Period Pixel ÷ Pclk

         uint32_tpclk;//很明显了,但是和用表格算的不一样

} SENSOR_TRIM_T, *SENSOR_TRIM_T_PTR;

                                                              图4

         在gc2235中(图4):起始坐标(0,0);大小(1600*1200);line_time=36.9us;Pclk=48M计算line_time(也就是row_time)的过程:

          ( Win_width/2 + Hb + sh_delay + 4)/Pclk =

         SENSOR_IOCTL_FUNC_TAB_T:这个结构体比较负责,它包含了驱动sensor的所有过程,包括上电等一系列的操作。详细分析

typedef uint32_t(*SENSOR_IOCTL_FUNC_PTR)(uint32_t param);

 

typedef struct sensor_ioctl_func_tab_tag {

         /*1:Internal IOCTL function */    //

         uint32_t(*reset)(uint32_t param);//复位

         uint32_t(*power)(uint32_t param);//上电

         uint32_t(*enter_sleep) (uint32_t param);//睡眠模式?

         uint32_t(*identify)(uint32_t param);//识别sensor id

         uint32_t(*write_reg)(uint32_t param);//写寄存器

         uint32_t(*read_reg)(uint32_t param);//读寄存器

         /*Customfunction */

         uint32_t(*cus_func_1) (uint32_t param);//?

         uint32_t(*get_trim) (uint32_t param);//这个函数入口在gc2235中是函数_gc2235_mipi_GetResolutionTrimTab的入口,该函数完成了gc2235的line_time、Pclk等也就是在结构体SENSOR_TRIM_T_PTR中定义的参数的写入。

         /*ExternalIOCTL function *//   这些模块与BLK中的相应模块对应,通过函数控制功能的实现,在GC2235中没有用到,它的ISP参数集中在sensor_gc2235_mipi_raw_param.c中,但在GC0309中一下函数入口均有与之对应的函数实现。具体功能不在分析

         uint32_t(*ae_enable) (uint32_t param);//AEC使能?

         uint32_t(*hmirror_enable) (uint32_t param);//?

         uint32_t(*vmirror_enable) (uint32_t param);//?

         uint32_t(*set_brightness)(uint32_t param);//

         uint32_t(*set_contrast)(uint32_t param);//

         uint32_t(*set_sharpness)(uint32_t param);//

         uint32_t(*set_saturation)(uint32_t param);//

         uint32_t(*set_preview_mode)(uint32_t param);//设置预览格式

 

         uint32_t(*set_image_effect)(uint32_t param);//

         //low16bits is resolution table index,hight 16bits is cap mode containing normal andHDR.

         uint32_t(*before_snapshort)(uint32_t param);//拍照前设置,更改模式等信息,跟踪代码发现这是拍照的入口程序,进入以后通过驱动的CMR模块(搞什么的我还弄明白)与上层app互动(发message),到图5所示的地方,就不明白他在干啥了,可能与kernel的某些线程相关。总之就是拍照前可以在该函数中进行设置

                                                                            图5

         uint32_t(*after_snapshort)(uint32_t param);//拍照后,将模式改回预览。不懂的是gc2235的这个函数中又将fa写00,难道是拍照过程中分频了吗?(待续)

         uint32_t(*flash)(uint32_t param);//

         uint32_t(*read_ae_value)(uint32_t param);//

         uint32_t(*write_ae_value)(uint32_t param);//

         uint32_t(*read_gain_value)(uint32_t param);//读gain

         uint32_t(*write_gain_value)(uint32_t param);//

         uint32_t(*read_gain_scale)(uint32_t param);//

         uint32_t(*set_frame_rate)(uint32_t param);//

         uint32_t(*af_enable)(uint32_t param);//

         uint32_t(*af_get_status)(uint32_t param);//

         uint32_t(*set_wb_mode)(uint32_t param);//

         uint32_t(*get_skip_frame)(uint32_t param);//

         uint32_t(*set_iso)(uint32_t param);//

         uint32_t(*set_exposure_compensation)(uint32_t param);//

         uint32_t(*check_image_format_support)(uint32_t param);//

         uint32_t(*change_image_format)(uint32_t param);//

         uint32_t(*set_zoom)(uint32_t param);//

         /*CUSTOMERFUNCTION */

         uint32_t(*get_exif)(uint32_t param);//

         uint32_t(*set_focus)(uint32_t param);//

         uint32_t(*set_anti_banding_flicker)(uint32_t param);//

         uint32_t(*set_video_mode)(uint32_t param);//

         uint32_t(*pick_jpeg_stream)(uint32_t param);//

         uint32_t(*set_meter_mode)(uint32_t param);//

         uint32_t(*get_status)(uint32_t param);//

         uint32_t(*stream_on)(uint32_t param);// 主要控制MIPI的端口的使能,开mipi_en

         uint32_t(*stream_off)(uint32_t param);//主要控制MIPI的端口的使能,关mipi_en

} SENSOR_IOCTL_FUNC_TAB_T,*SENSOR_IOCTL_FUNC_TAB_T_PTR;

其既用于功能机也用于智能机。其65和66系列的 平台主要用于功能机,例如6530、6531、6500、6610、6620、6600L;68和88系列的 平台主要用于智能机,例如SC6810、SC6820、SC6800、SC8820、SC8810。目前我们使用的样机为SC8825,搭配GC2235。

         在进行平台下载时需要像高通平台一样进入fastboot mode才能进行下载烧录。烧录步骤:

1、 使用shell终端进入工程根目录,执行脚本copy.sh将img文件copy到上层文件夹sp_bin中。

2、 连接usb线,开机状态下使用adb命令adb reboot‐bootloader,进入fastboot mode。

3、 烧录boot、system、userdata文件,指令为:

fastboot flash boot d:boot.img

fastboot flash system d: system.img

fastbootflash userdata d: userdata.img

fastboot reboot    红色为文件路径,修改为自己文件所在路径

         编译展讯平台的步骤进行简化,以后编译驱动和库文件只需要在根目录下执行 .  mk.sh命令就可以进行编译。其中点(.)和mk.sh之间必须有空格,否则不能执行。

展讯平台的sensor驱动(我们提供的)主要存放于根目录下:

device/sprd/common/libs/libcamera/sensor/

分别为:

sensor_gcxxxx.c

sensor_gcxxxx_raw_param.c

sensor_gcxxxx_mipi_raw.c

sensor_gcxxxx_mipi_raw_param.c

而关于驱动中使用变量的定义在文件是

device/sprd/common/libs/libcamera/isp/inc/sensor_raw.h

其中sensor_gcxxxx.c、sensor_gc2235_raw_param.c是DVP接口的驱动,sensor_gcxxxx_mipi_raw.c、sensor_gcxxxx_mipi_raw_param.c是Mipi接口的驱动。关于sensor控制的函数、寄存器值的写入主要在sensor_gcxxxx.c中,例如_gc2235_write_gain()函数是写入平台gain;_gc2235_write_exposure是写入Shutter,数组gc2235_com_raw[]是存放sensor初始化寄存器值(如图1),前边是地址,后边的是值。

                     

                                                                          图1

展讯在出错的时候不同于MTK以LOG文件形式记录,它在出错的时候是直接显示在shell终端窗口上,出错时如果错误过多,将冲掉错误信息的前半部分(shell只记录有限长度的一段)。同时,在展讯上看手机活动的log的方法如下:

adb devices

adb logcat>D:ksng     (红色部分是windows下保存的log的路径)

       展讯平台中关于sensor的驱动底层部分平台提供的)位于devicesprdcommonlibslibcamera下的使用的平台文件夹下,例如样机用的是SC8825,那样机用的驱动就在sc8825问价夹下。驱动分为两个部分src(.c)、inc(.h),sensor中所有操作函数均在改这里实现。函数列表如图2所示。

                                    图2

         追踪了一下log,查看了手机调用sensor过程中的步骤。

android::HAL_camera_device_open(consthw_module_t*, const char*, hw_device_t**)

打开摄像头驱动

android::HAL_getNumberOfCameras()//获得当前camera数目

initDefaultParameters

//初始化参数(这些参数是app层的选项参数)   包括whitebalance、picture-size、preview-size、exposure等 .解析了一段,发现与kernel交叉太多,解不动了。(待续)

一、详解

         1、驱动中数据的认识与还原

1.1关于驱动中使用的数据多使用SENSOR_I2C_T_PTR、SENSOR_REG_T_PTR、SENSOR_REG_BITS_T_PTR样式的结构体,这些结构体一般都是定义响应的寄存器地址、寄存器值、寄存器个数、寄存器位数等信息。例如SENSOR_I2C_T_PTR的定义为:

typedef struct sensor_i2c_tag {

                                       uint8_t  *i2c_data;//指针,指向要写入的数据头

                                       uint16_ti2c_count;//要写入数据的个数

                                       uint16_tslave_addr;//i2c读写地址

} SENSOR_I2C_T, *SENSOR_I2C_T_PTR; 

这些结构体的定义均在sensor_druv.h中,需要的时候可以查询相应位的含义。

         1.2其他的一些功能结构体,例如SENSOR_REG_TAB_INFO_T、SENSOR_TRIM_T、SENSOR_IOCTL_FUNC_TAB_T、SENSOR_INFO_T等结构体。现在逐一对其分析,了解这些结构体,不要这这些掩盖了数据的真实含义。

typedefstruct sensor_reg_tab_info_tag {

         SENSOR_REG_T_PTRsensor_reg_tab_ptr;//要初始化的寄存器(指针,指向链表、数组首地址)

         uint32_treg_count;//寄存器数目

         uint16_twidth;//出图的宽度

         uint16_theight;//出图的高度

         uint32_txclk_to_sensor;//Mclk

         SENSOR_IMAGE_FORMATimage_format;//输出图像格式

} SENSOR_REG_TAB_INFO_T,*SENSOR_REG_TAB_INFO_T_PTR;

 

                                                                             图3

例如在gc2235中:这是一个结构体数组(如图3所示),数组的每一个元素都是一个SENSOR_REG_TAB_INFO_T_PTR结构体(依旧不清楚为何前两个完全一样,后边的全是空的),在第一个元素中ADD_AND_LEN_OF_ARRAY是为了获得寄存器的头和个数。具体定义为:#define ADDR_AND_LEN_OF_ARRAY(a)        (SENSOR_REG_T*)a,NUMBER_OF_ARRAY(a),也就是获得gc2235_mipi_com_raw(图1所示)中寄存器的个数和首地址;1600为gc2235出图宽度;1200为高度;24为Mclk;sensor_TMAGE_FORMAT_RAW出图格式为raw。

typedef struct sensor_trim_tag {

         uint16_ttrim_start_x; //坐标x

         uint16_ttrim_start_y;//坐标Y

         uint16_ttrim_width;//宽

         uint16_ttrim_height;//高

         uint32_tline_time;//重要, Line Time =Period Pixel ÷ Pclk

         uint32_tpclk;//很明显了,但是和用表格算的不一样

} SENSOR_TRIM_T, *SENSOR_TRIM_T_PTR;

                                                              图4

         在gc2235中(图4):起始坐标(0,0);大小(1600*1200);line_time=36.9us;Pclk=48M计算line_time(也就是row_time)的过程:

          ( Win_width/2 + Hb + sh_delay + 4)/Pclk =

         SENSOR_IOCTL_FUNC_TAB_T:这个结构体比较负责,它包含了驱动sensor的所有过程,包括上电等一系列的操作。详细分析

typedef uint32_t(*SENSOR_IOCTL_FUNC_PTR)(uint32_t param);

 

typedef struct sensor_ioctl_func_tab_tag {

         /*1:Internal IOCTL function */    //

         uint32_t(*reset)(uint32_t param);//复位

         uint32_t(*power)(uint32_t param);//上电

         uint32_t(*enter_sleep) (uint32_t param);//睡眠模式?

         uint32_t(*identify)(uint32_t param);//识别sensor id

         uint32_t(*write_reg)(uint32_t param);//写寄存器

         uint32_t(*read_reg)(uint32_t param);//读寄存器

         /*Customfunction */

         uint32_t(*cus_func_1) (uint32_t param);//?

         uint32_t(*get_trim) (uint32_t param);//这个函数入口在gc2235中是函数_gc2235_mipi_GetResolutionTrimTab的入口,该函数完成了gc2235的line_time、Pclk等也就是在结构体SENSOR_TRIM_T_PTR中定义的参数的写入。

         /*ExternalIOCTL function *//   这些模块与BLK中的相应模块对应,通过函数控制功能的实现,在GC2235中没有用到,它的ISP参数集中在sensor_gc2235_mipi_raw_param.c中,但在GC0309中一下函数入口均有与之对应的函数实现。具体功能不在分析

         uint32_t(*ae_enable) (uint32_t param);//AEC使能?

         uint32_t(*hmirror_enable) (uint32_t param);//?

         uint32_t(*vmirror_enable) (uint32_t param);//?

         uint32_t(*set_brightness)(uint32_t param);//

         uint32_t(*set_contrast)(uint32_t param);//

         uint32_t(*set_sharpness)(uint32_t param);//

         uint32_t(*set_saturation)(uint32_t param);//

         uint32_t(*set_preview_mode)(uint32_t param);//设置预览格式

 

         uint32_t(*set_image_effect)(uint32_t param);//

         //low16bits is resolution table index,hight 16bits is cap mode containing normal andHDR.

         uint32_t(*before_snapshort)(uint32_t param);//拍照前设置,更改模式等信息,跟踪代码发现这是拍照的入口程序,进入以后通过驱动的CMR模块(搞什么的我还弄明白)与上层app互动(发message),到图5所示的地方,就不明白他在干啥了,可能与kernel的某些线程相关。总之就是拍照前可以在该函数中进行设置

                                                                            图5

         uint32_t(*after_snapshort)(uint32_t param);//拍照后,将模式改回预览。不懂的是gc2235的这个函数中又将fa写00,难道是拍照过程中分频了吗?(待续)

         uint32_t(*flash)(uint32_t param);//

         uint32_t(*read_ae_value)(uint32_t param);//

         uint32_t(*write_ae_value)(uint32_t param);//

         uint32_t(*read_gain_value)(uint32_t param);//读gain

         uint32_t(*write_gain_value)(uint32_t param);//

         uint32_t(*read_gain_scale)(uint32_t param);//

         uint32_t(*set_frame_rate)(uint32_t param);//

         uint32_t(*af_enable)(uint32_t param);//

         uint32_t(*af_get_status)(uint32_t param);//

         uint32_t(*set_wb_mode)(uint32_t param);//

         uint32_t(*get_skip_frame)(uint32_t param);//

         uint32_t(*set_iso)(uint32_t param);//

         uint32_t(*set_exposure_compensation)(uint32_t param);//

         uint32_t(*check_image_format_support)(uint32_t param);//

         uint32_t(*change_image_format)(uint32_t param);//

         uint32_t(*set_zoom)(uint32_t param);//

         /*CUSTOMERFUNCTION */

         uint32_t(*get_exif)(uint32_t param);//

         uint32_t(*set_focus)(uint32_t param);//

         uint32_t(*set_anti_banding_flicker)(uint32_t param);//

         uint32_t(*set_video_mode)(uint32_t param);//

         uint32_t(*pick_jpeg_stream)(uint32_t param);//

         uint32_t(*set_meter_mode)(uint32_t param);//

         uint32_t(*get_status)(uint32_t param);//

         uint32_t(*stream_on)(uint32_t param);// 主要控制MIPI的端口的使能,开mipi_en

         uint32_t(*stream_off)(uint32_t param);//主要控制MIPI的端口的使能,关mipi_en

} SENSOR_IOCTL_FUNC_TAB_T,*SENSOR_IOCTL_FUNC_TAB_T_PTR;

最后

以上就是刻苦心锁为你收集整理的展讯-sensor driver的全部内容,希望文章能够帮你解决展讯-sensor driver所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部