[海思]--Hi3516a--添加新Sensor

海思的sensor驱动大部分工作在应用层,即应用层驱动(非ko形式存在),这样一来在对sensor改动时,就不需要重新编译内核了。

   缺点是,不稳定,效率会比较低。纯应用层驱动是没办法操作硬件的,所以需要调用底层i2c驱动。

1、驱动源码路径
Hi3518E_SDK_V1.0.3.0\package\mpp\mpp\component\isp\sensor目录下。

2、sensor驱动调用

   sensor驱动编译完之后会生成xxx.a和xxx.so两个库,一个是静态链接用的,一个是动态链接用的。
   这两个文件会被放到Hi3518E_SDK_V1.0.3.0\package\mpp\mpp\lib目录下。

3、sensor驱动文件命名规则

   xxxx_cmos.c中定义回调和上层函数。
   xxxx_sensor_ctl.c中定义底层硬件相关的寄存器值配置函数。

4、sensor驱动在哪被调用

   从之前的sample_venc开始看,在第三部分step 3: start vi dev & chn to capture

   SAMPLE_COMM_VI_StartVi()

       SAMPLE_COMM_VI_StartIspAndVi()

               SAMPLE_COMM_ISP_Init()

                       sensor_register_callback()
   sensor_register_callback这个函数就在sensor驱动里面,这里会调用到kernel内的i2c驱动对sensor进行硬件操作。

5、sensor_register_callback

   这个函数就是对整个sensor初始化,内部封装了操作sensor所需要的函数,(ISP、AE(自动曝光)、AWB(白平衡))
   其中的cmos_init_sensor_exp_function函数将sensor操作时所需要的函数一一挂接起来,例如初始化调用的sensor_init。

6、sensor_init
初始化sensor,初始化的方式就是调用i2c函数接口来实现操作sensor内部寄存器。
在这里插入图片描述

7、黑电平

   黑电平(Black Level Correction)也就是黑色的最低点,以8bit数据来说,指在经过一定校准的显示装置上,没有一行光亮输出的视频信号电平。定义图像数据为0时对应的信号电平。
   sensor中的黑电平是可以调节的,就相当于标准值,就像零摄氏度这种概念。

8、sensor驱动编译实战

   (1)修改驱动源码

   以AR0130为例,修改mpp\component\isp\sensor\ar0130目录下的应用驱动源码。
   如果是调整黑电平,就修改ar0130目录下的ar0130_coms.c文件里面的cmos_get_isp_black_level函数中的au16BlackLevel数组。

在这里插入图片描述
(2)清除,并重新编译

   首次编译需要在mpp\component\isp目录下将整个isp进行编译。

   执行make clean指令。

   再执行make

   (3)确认mpp中lib目录下的libsnsxxx.a/so已经被更新。
   (4)重新编译sample并运行查看效果。

9、AR0130sensor寄存器
参考AR0130_RR_C.pdf文档的Register Behavior寄存器章节,了解各寄存器用途。


  1. sensor开发框图

wKiom1fSl5mwA2ESAABzoRmaSVU881.jpg

  1. 设备驱动加载及硬件系统配置

cd mpp/ko

default online

./load3518e -a -sensor sc2135 -osmem 32 -total 64

vi_vpss offline

./load3518e -a -sensor sc2135 -osmem 32 -total 64 -offline

load3518e脚本主要是用来配置硬件系统的参数(引脚复用、sensor时钟、VI时钟)加载驱动(.ko),包括访问sensor的I2C接口驱动。

离线模式时图像存入DDR中,在线模式时图像不存入DDR中。

在load3518e脚本中添加sensor的相关配置,这里使用smartsens的SC2135的200万像素的图像传感器。

insert_sns()
{
case $SNS_TYPE in
sc2135)
himm 0x200f0040 0x2; # I2C0_SCL
himm 0x200f0044 0x2; # I2C0_SDA

		#cmos pinmux
		himm 0x200f007c 0x1;    			# VI_DATA13
		himm 0x200f0080 0x1;    			# VI_DATA10
		himm 0x200f0084 0x1;    			# VI_DATA12
		himm 0x200f0088 0x1;    			# VI_DATA11
		himm 0x200f008c 0x2;    			# VI_VS
		himm 0x200f0090 0x2;    			# VI_HS
		himm 0x200f0094 0x1;    			# VI_DATA9
		
		himm 0x2003002c 0xb4001;			# sensor unreset, clk 27MHz, VI 148.5MHz

himm 0x20030104 0x1; # vpss 148.5MHz

		;;
	*)
		echo "xxxx Invalid sensor type $SNS_TYPE xxxx"
		report_error;;
esac

}

insert_ko()
{
# sys config
sys_config;

# driver load
insmod mmz.ko mmz=anonymous,0,$mmz_start,$mmz_size anony=1 || report_error
insmod hi_media.ko
insmod hi3518e_base.ko

insmod hi3518e_sys.ko vi_vpss_online=$b_arg_online sensor=$SNS_TYPE

insmod hi3518e_tde.ko
insmod hi3518e_region.ko
insmod hi3518e_vgs.ko

insmod hi3518e_isp.ko
insmod hi3518e_viu.ko detect_err_frame=10;
insmod hi3518e_vpss.ko rfr_frame_comp=1;
insmod hi3518e_vou.ko
#insmod hi3518e_vou.ko transparentTransmit=1 #enable transparentTransmit
insmod hifb.ko video="hifb:vram0_size:1620"     # default pal

insmod hi3518e_rc.ko
insmod hi3518e_venc.ko 
insmod hi3518e_chnl.ko ChnlLowPower=1
insmod hi3518e_h264e.ko
insmod hi3518e_jpege.ko
insmod hi3518e_ive.ko save_power=0;

insmod hi3518e_ive.ko

insmod extdrv/sensor_i2c.ko
echo "==== Your input Sensor type is $SNS_TYPE ===="
insmod extdrv/pwm.ko
insmod extdrv/piris.ko

#insert_sns > /dev/null
insert_sns
insert_audio

insmod hi_mipi.ko
echo "==== Your input Sensor type is $SNS_TYPE ===="

}

  1. sensor的库文件生成(.so)

sensor的库文件需要在Linux服务器中的SDK包中编译得到,将生成的.so文件放到SDK包中的stream软件包中的Hi3518E_Stream_xxx/libs目录下。

wKiom1fSrKWSwkQLAAB-bfCJ3DQ706.jpg

sensor_ctl.c实现sensor的读写初始化。

sensor_cmos.c主要实现ISP需要的回调函数,包括ISP、AE、AWB等。

//ISP function
HI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc)
{
memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S));

pstSensorExpFunc->pfn_cmos_sensor_init = sensor_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = sensor_exit;
pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init;
pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode;
pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode;

pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default;
pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_isp_black_level;
pstSensorExpFunc->pfn_cmos_set_pixel_detect = cmos_set_pixel_detect;
pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info;

return 0;

}

//AE function
HI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs)
{
memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S));

pstExpFuncs->pfn_cmos_get_ae_default    = cmos_get_ae_default;
pstExpFuncs->pfn_cmos_fps_set           = cmos_fps_set;
pstExpFuncs->pfn_cmos_slow_framerate_set= cmos_slow_framerate_set;    
pstExpFuncs->pfn_cmos_inttime_update    = cmos_inttime_update;
pstExpFuncs->pfn_cmos_gains_update      = cmos_gains_update;
pstExpFuncs->pfn_cmos_again_calc_table  = cmos_again_calc_table;
pstExpFuncs->pfn_cmos_get_inttime_max   = cmos_get_inttime_max; 

return 0;

}

//AWB function
HI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs)
{
memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S));

pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default;

return 0;

}

  1. 修改stream软件包的.ini文件

sc2135_1080p_line.ini文件在Hi3518E_Stream_xxx/configs目录下,改文件主要指定.so文件的位置、输入视频的接口(LVDS/MIPI/DVP)、视频格式(分辨率、同步方式、目标帧率等)等系统配置。

  1. 运行stream软件

运行stream软件包中的HiIspTool.sh脚本,通过以太网卡与上位机的PQTools建立通信。

cd /Hi3518E_Stream_V1.0.2.0

./HiIspTool.sh -a -p sc2135_1080p_line.ini

ittb_control进程是基于TCP的服务端,负责控制信号的传输。

ittb_stream进程也是基于TCP的服务端,负责播放H.264或YUV视频流。

wKioL1fSsq-wXKC9AADRHXJoipc306.jpg

  1. 运行PQ Tools

双击PQ Tools图片,弹出如下对话框,设置IP地址。

wKiom1fStgiBOLd5AABV6TYUyy8974.jpg

在下拉菜单中选择TTP_Stream.exe选项

wKiom1fStkDxwy9rAADdoeFseIU165.jpg

  1. 最终结果

本文来自 什么鬼__ 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_36164813/article/details/52620112?utm_source=copy

问题1:
由于是新sensor,跑海思自带的测试代码肯定会提示“This sensor type is not surpport!”
解决方案:
添加新sensor的枚举类型 到typedef enum sample_vi_mode_e {}SAMPLE_VI_MODE_E;
并根据自己sensor的参数正确命名。

问题2:
最棘手的问题,get venc stream time out, exit thread
既然是新添加sensor,那么能出现这个超时问题一定就是视频摄入有问题了,最主要的结构在sample_common_vi.c 的combo_dev_attr_t结构体。
你要对照sensor厂商给的ini配置,参照其他厂商的形式为你的sensor写一个此结构体的初始化代码。当然我们的是CMOS3V3的,直接使用如下初始化结构:
combo_dev_attr_t MIPI_CMOS3V3_ATTR =
{
/* input mode */
.input_mode = INPUT_MODE_CMOS_33V,
{

}

};

猜你喜欢

转载自blog.csdn.net/whereisdog/article/details/82493827