赞
踩
展讯平台其既用于功能机也用于智能机。其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的驱动底层部分(平台提供的)位于device\sprd\common\libs\libcamera下的使用的平台文件夹下,例如样机用的是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;
总体上来说,这个机构体就是提供了给上层调用的API接口,我们将所使用到的所有功能函数在这里声明,不需要该功能就在相应功能的位置写PNULL。在.c文件只需要定义我们需要的功能即可。
具体过程参照 :http://blog.csdn.net/zhu85564043/article/details/8698002
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。