Hi3519DV500开发板适配新sensor的详细流程(最新版)
所需环境:
1.虚拟机与主机之间的交互的环境:VMware17.6 + Ubantu22.04
2.开发板与主机之间的交互环境:MobaXterm
其他软件工具:
Visual Studio Code:采用SHH方式与虚拟机尽心链接,方便对相关SDK文件的修改
Xshell:可以进行相关版级命令操作
1.首先需要将官方给出的SDK包从主机端传输到虚拟机端,可以将主机文件夹复制后在虚拟机端直接进行粘贴或者可以通过建立虚拟机与主机之间的共享文件夹进行文件的传输,可以借助copy to操作。在Home目录下,执行以下命令对hi3519dv500.tar.tgz文件进行解压缩,进入SDK工程目录下展开SDK包内容。
tar xf hi3519dv500.tar.gz
cd Hi3519DV500_SDK_V2.0.2.0/
./sdk.unpack
2.修改sensor驱动
在“Hi3519DV500_SDK_V2.0.2.0/smp/a55_linux/source/mpp/cbb/isp/user/sensor/hi3519dv500”中找到各个版本sensor的驱动文件夹
寻找与目标sensor详尽的sensor驱动进行修改,这里以os08a20sensor为例进行修改,将oso8a20文件夹,重新复制一份,命名为sensor_pts001。以后的修改直接在sensor_pts001文件夹中进行。
修改过程中遵循非必要不修改的原则,重点是修改寄存器数值和一些参数值,如果所选传感器与新传感器的差异较大的时候,还需修改相应的函数值。(对于自研sensor来说,改动的往往比较多)
首先看一下目录结构,一共有以下5个文件,我们依次对相关文件进行解析,分析其中需要修改和需要重点关注的部分
1.os08a20_cmos_ex.h文件
可以看出os08a20_coms_ex.h程序,大部分函数都与ISP有关,如果要求先出图,则该部分可暂时忽略。
2.对于os08a20_cmos.c主要是对以下部分内容的修改:
对照sensor的.ini文件对方框内参数进行修改,ID暂不修改(主要是对ID的修改规则还不明晰,建议将多个sensor的ID进行对比发现规律)
修改后的代码如下:
对于曝光时间的寄存器地址定义:
曝光控制寄存器
寄存器地址 | 功能说明 | 位宽设计原理 |
---|---|---|
OS08A20_EXPO_H_ADDR (0x3501) | 曝光时间高8位 控制曝光时长的高字节部分,与低字节组合形成16位曝光值 | 高位寄存器存储曝光值的高权重比特 |
OS08A20_EXPO_L_ADDR (0x3502) | 曝光时间低8位 存储曝光时长的低字节,值域0-255调节精细度 | 低位寄存器存储低权重比特 |
OS08A20_SHORT_EXPO_H_ADDR (0x3511) | 短帧曝光高8位 WDR模式下短帧曝光的高字节控制(用于高亮区域) | 支持宽动态范围的双曝光控制 |
OS08A20_SHORT_EXPO_L_ADDR (0x3512) | 短帧曝光低8位 配合高字节实现短帧曝光的精细调节 | 双曝光机制需独立 |
增益控制寄存器
寄存器地址 | 功能说明 |
---|---|
OS08A20_AGAIN_H_ADDR (0x3508) | 模拟增益高8位 控制传感器模拟放大电路增益(直接影响信噪比) |
OS08A20_AGAIN_L_ADDR (0x3509) | 模拟增益低8位 提供模拟增益的精细调节步进(典型值0.125dB/步) |
OS08A20_DGAIN_H_ADDR (0x350a) | 数字增益高8位 控制ISP数字放大系数(会引入量化噪声) |
OS08A20_DGAIN_L_ADDR (0x350b) | 数字增益低8位 实现数字增益的平滑过渡 |
OS08A20_SHORT_AGAIN_H_ADDR (0x350c) | 短帧模拟增益高8位 WDR短帧专用模拟增益控制 |
OS08A20_SHORT_AGAIN_L_ADDR (0x350d) | 短帧模拟增益低8位 短帧模式下的增益微调 |
OS08A20_SHORT_DGAIN_H_ADDR (0x350e) | 短帧数字增益高8位 避免长/短帧增益干扰的双寄存器设计 |
OS08A20_SHORT_DGAIN_L_ADDR (0x350f) | 短帧数字增益低8位 保证WDR模式下两帧图像增益独立可调 |
帧同步控制寄存器
寄存器地址 | 功能说明 |
---|---|
OS08A20_VMAX_H_ADDR (0x380e) | 垂直帧长高8位 设定帧总行数的高字节(决定帧率:Frame Rate = 时钟基准 / VMAX) |
OS08A20_VMAX_L_ADDR (0x380f) | 垂直帧长低8位 提供帧长的精细调节(最小步进=1行) |
#define OS08A20_MARGIN 4 // 曝光安全边界值
//作用:曝光时间设置上限 = VMAX - MARGIN
//原理:预留4行时间作为消隐区(Blanking),防止曝光跨越帧边界导致图像撕裂
可以发现os08a20参数,主要在以下三个函数中进行了使用
这个函数名为cmos_inttime_update_linear,看起来是用于设置图像传感器的曝光时间。先看一下函数参数:vi_pipe应该是指视频输入管道,int_time是曝光时间值。函数开头通过os08a20_sensor_get_ctx获取传感器上下文,如果获取失败则直接返回,这里有个sns_check_pointer_void_return宏应该是做空指针检查。接着看到value = int_time,这里直接保存传入的曝光时间值。然后函数分成两个分支:如果g_quick_start_en[vi_pipe]为真,表示需要快速更新,就直接调用os08a20_write_register函数向传感器的两个寄存器地址(OS08A20_EXPO_L_ADDR和OS08A20_EXPO_H_ADDR)写入曝光时间的低8位和高8位。如果不走快速更新路径,就将曝光时间值写入到sns_state->regs_info数组的对应位置(EXPO_L_IDX和EXPO_H_IDX),这里是先缓存起来,可能后续会批量写入。这个函数主要实现了对图像传感器曝光时间的设置,根据不同的工作模式选择立即写入或缓存设置。其中曝光时间被拆分为高低8位分别存储,符合常见图像传感器寄存器设计。
这个函数明显是用于图像传感器控制的底层代码,涉及到CMOS传感器的参数配置。从函数名和内容来看,这应该是用于设置像素检测模式的函数,可能在图像质量校准或测试时使用。函数有两个参数,vi_pipe表示视频输入管道,enable表示是否启用像素检测模式。函数内部首先获取传感器上下文,然后根据传感器的工作模式计算特定参数,最后根据enable的值分别配置两组不同的寄存器设置。当enable为真时,函数配置了增益寄存器(AGAIN和DGAIN)、垂直最大值寄存器(VMAX)和曝光寄存器(EXPO)。这些值被硬编码为特定值或基于fps计算的值。当enable为假时,函数恢复"正常模式"的设置,使用保存在传感器状态中的标准值。
函数开头获取了传感器上下文sns_state,这是操作传感器的基础。然后检查传感器是否处于线性WDR模式(OT_WDR_MODE_2To1_LINE),如果是则直接返回,说明此模式不支持该功能。接着判断传感器是否处于特定的8M 30fps线性模式,如果是则计算5fps对应的全行数(full_lines_5fps)。当enable为真时,设置固定的模拟增益(0x8000,即128倍)和数字增益(0x0400,即4倍),这可能是为了校准目的而设置的固定增益值。然后设置VMAX寄存器为full_lines_5fps,这控制了帧率。设置EXPO寄存器为full_lines_5fps - 10,确保曝光时间略小于帧周期。当enable为假时,恢复正常的VMAX设置,并从sns_state中获取标准值,同时重置同步初始化标志。
这个函数的主要作用是在需要执行像素级校准或测试时,将传感器配置到一个特定的工作状态(固定增益、固定曝光、低帧率),以便进行精确测量或校准。完成后又能恢复正常的拍摄模式。
先看函数名cmos_comm_sns_reg_info_init,拆解后可知这是用于初始化传感器寄存器信息的函数。参数vi_pipe指定视频输入通道,sns_state是传感器状态结构体指针。
函数首先设置传感器类型为I2C(OT_ISP_SNS_TYPE_I2C),符合CMOS传感器常见的控制接口。通过g_os08a20_bus_info获取对应通道的I2C设备信息,这里体现了多路摄像头支持的设计。
注意到有个关键标志g_quick_start_en,这决定配置生效速度:快速模式延迟帧数设为1(立即生效),常规模式为2(等待两帧)。这种设计在需要实时调整参数的场景很重要,比如高速连拍时曝光必须即时响应。
随后处理WDR(宽动态范围)模式的特殊逻辑:当处于OT_WDR_MODE_2To1_LINE时,寄存器数量增多(WDR_REG_MAX_IDX),且强制延迟帧数为2。这是因为WDR需要多帧合成,寄存器更新时序更复杂。
循环初始化部分值得关注:为每个寄存器设置update标志(TD_TRUE允许更新)、I2C地址(OS08A20_I2C_ADDR)及地址/数据字节数。这里采用统一初始化模板提高效率,避免重复代码。
重点在于具体寄存器的定制化配置:
- 曝光(EXPO)和增益(AGAIN/DGAIN)寄存器delay_frame_num=0,说明这些关键参数需要立即生效
- 帧长寄存器(VMAX)却设为1,因为修改垂直消隐会影响帧时序,延迟一帧生效可避免画面撕裂
这种差异化的延迟策略非常专业——实时参数立即生效,影响时序的参数等待垂直同步。类似设计在显示驱动中也常见,比如修改分辨率需要等待vblank。
而在新的sensor的.ini文件中,与曝光时间相关的寄存器配置仅有以下两个,即曝光时间高位与曝光时间低位地址的赋值。
这部分的代码修改后的结果为
对于短曝光设置,仅有一个函数进行了调用,如下所示
初始化 OS08A20 传感器在 2:1 线性 WDR 模式 下的关键寄存器配置表,构建宽动态场景的底层控制框架。
先看函数参数:vi_pipe表示视频输入管道,用于多路摄像头区分;sns_state是传感器状态结构体指针,用于存储寄存器配置信息。有趣的是第一行就调用了ot_unused(vi_pipe),这说明在这个特定函数里vi_pipe参数未被使用。
接下来是核心的寄存器配置部分。这里分为几个关键组:
曝光控制部分设置了短帧曝光的寄存器和生效策略。OS08A20_SHORT_EXPO_L_ADDR(0x3512)和OS08A20_SHORT_EXPO_H_ADDR(0x3511)分别对应短帧曝光的低8位和高8位地址。delay_frame_num=0表示这些参数修改后立即生效,这对需要快速响应光照变化的场景很关键。增益控制部分配置了短帧的模拟增益和数字增益寄存器。OS08A20_SHORT_AGAIN_L_ADDR(0x350d)等地址是WDR模式特有的,与普通线性模式的分开。同样设置0帧延迟,确保增益调整实时生效。帧长控制部分比较特殊,VMAX寄存器(0x380e/0x380f)被设置为1帧延迟生效。这是为了防止画面撕裂,因为改变帧长会影响整个传感器的时序,需要等待垂直同步周期结束后再切换。注意到所有配置都放在regs_info[0]这个数组的第一个元素里,结合之前海思平台的信息,这应该对应mipi0接口的配置。在WDR模式下,短帧参数和长帧参数是分开控制的,这也是为什么需要这么多专用寄存器。
WDR (宽动态范围,Wide Dynamic Range)模式专用控制(这几个寄存器在新sensor的.ini文件中并未出现,暂时不予修改)
参数类型 | 寄存器地址 | 作用 | 生效策略 |
---|---|---|---|
短曝光时间 | 0x3511/0x3512 | 控制短帧曝光时长(捕捉高亮区域) | 立即生效 |
短曝光模拟增益 | 0x350c/0x350d | 独立调节短帧模拟放大系数(抑制高光噪声) | 立即生效 |
短曝光数字增益 | 0x350e/0x350f | 独立调节短帧数字放大系数(避免长/短帧干扰) | 立即生效 |
帧长 (VMAX) | 0x380e/0x380f | 控制总帧行数(决定帧率) | 延迟1帧生效 |
这里有全局增益和帧长那个,但是无法与上面定义参数进行匹配。
目前仅修改了图像的长宽以及曝光时间,其它的参数暂时不进行修改。
3.对于os08a20_cmos.h函数
这里需要修改的是I2C地址:
由sensor的Datasheet手册可知,此处I2C_ADDR要修改为0x3e
修改后的代码如下:
4.对于os08a20_sensor_ctl.c函数来说:
os08a20_linear_8m30_12bit_init_part5
是 OS08A20 图像传感器驱动初始化流程的第五阶段,专用于配置 8M分辨率、30FPS帧率、12bit线性模式 的关键寄存器参数。其核心作用是通过寄存器写入完成传感器启动前的最终配置,并激活传感器输出图像数据。
同理,利用新sensor的.ini文件,完成该部分寄存器的初始化,初始化文件如下:
修改后的代码如下所示:
到这基本改完了。下面就是生成so文件
在该文件夹下执行make命令,即可库文件.a和.so文件。
将lib文件从虚拟机传到主机然后加载到开发板中
记得也要把虚拟机中的ko文件拷贝到卡发版中
在SDK文件夹中,修改这两个文件的初始化程序。
这里的i2C根据开发板P1口的版图进行修改,这里是4不用进行修改
查看load3519dv500,把隔离这里设置为0
运行上述脚本
打开PQstream软件与开发板建立连接,连接成功但没出图
PQTools也是异常
目前就做到这种程度希望有大佬进行指点一下。