尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

RK3568接入AHD摄像头:XS9922B转MIPI桥接芯片驱动调试全解析

RK3568接入AHD摄像头:XS9922B转MIPI桥接芯片驱动调试全解析 简介瑞芯微RK3568平台调通并实测通过的xs9922b驱动源码面向嵌入式驱动开发、视频采集或AHD摄像头方案选型的工程师。该驱动完成AHD转MIPI桥接支持4路AHD camera同时接入并正常取流可直接参考移植或集成到RK3568项目中免去从零调试传感器驱动的过程。资源包为rar压缩格式共2个文件包含核心驱动源码.c与寄存器配置头文件.h两者配套使用便于快速理解初始化配置与数据通路。压缩包仅约12KB结构精简适合对照源码学习驱动框架和AHD芯片配置流程。目前已有156人学习下载适合正在调试RK3568 MIPI接口或希望快速验证AHD转MIPI方案的开发者参考。1. 为什么RK3568的接入方案里会需要一颗XS9922B先说结论如果你正在做一个车载记录仪、工程机械监控或者低成本多路安防方案主控选了RK3568但前端感光设备不是那种直出MIPI的数字Sensor而是用一根同轴线传模拟高清AHD信号的摄像头那中间就必然要加一颗AHD转MIPI的桥接芯片。XS9922B就是这个角色而且它在RK3568平台的适配方案网上零散资料不少、能直接照抄的完整驱动却不多所以我把调通的经验和源码结构整理出来。为什么会有这种需求AHD摄像头的成本比同规格MIPI摄像头低不少同轴线又比排线抗干扰、传输距离远在商用车上用得非常普遍。而RK3568的摄像头接口只接受MIPI CSI-2这类数字差分信号ISP单元根本不认模拟信号。换摄像头不现实换主控更不现实唯一的出路就是在物理链路上加一颗转换芯片把同轴线上的模拟波形解调成RK3568能吃进去的MIPI数据流。XS9922B这颗芯片比较典型的特点是支持多通道输入。它内部集成了AHD信号解码器可以同时接入四路AHD摄像头通过虚拟通道Virtual Channel的方式复用到一路MIPI CSI-2输出上。这样一来一颗芯片就能撑起四路环视/监控画面对RK3568这种自带强大ISP的处理器来说非常合拍硬件面积也小板级设计不用堆太多器件。1.1 从模拟线缆到MIPI信号的数据流路径把整条链路打开看其实这个过程可以拆成四段AHD摄像头端把图像传感器采集到的视频数据按AHD协议编码调制到同轴线上传输。XS9922B接收端通过同轴线输入接口接收AHD信号完成均衡、解调、解码还原出数字视频流。XS9922B发送端将解码后的视频数据打包成MIPI CSI-2协议格式通过D-PHY物理层发出去。RK3568接收端MIPI CSI控制器接收数据送往ISP做降噪、HDR、3A计算、色彩校正最后输出到视频节点。这条链路里最容易被忽略的地方是XS9922B不是简单的协议转换器它还要负责把模拟信号里的时钟恢复出来再转换到MIPI的字节时钟域。所以驱动里如果只配了通道格式、没配好D-PHY的时钟参数出来的画面要么没信号要么会有偶发性的丢帧。实际调试时我觉得最值得花时间的就是这部分。1.2 XS9922B在RK3568板卡上的典型接法硬件接法上XS9922B和RK3568的接口连接相对固定。芯片的MIPI TX端口通常以4 lane方式接到RK3568的MIPI CSI D-PHYI2C控制信号挂在任意空闲I2C总线上供电一般是一路1.8V核电压加一路3.3V IO电压部分板子还会单独做一路1.2V给MIPI PHY。电源和复位顺序需要看芯片手册的时序要求实测中发现如果复位信号释放得太早芯片内部PLL可能没有稳定起来之后I2C读取ID时会偶发失败或者图像输出一切正常但会间歇性报MIPI CRC错误。驱动里最好在probe阶段加一个固定的延时控制复位脚不要完全依赖板级上电默认逻辑。2. RK3568的V4L2分层结构与XS9922B驱动挂载方式RK3568的Camera链路走的是标准V4L2 Media Controller框架驱动必须按这个框架来组织否则ISP根本不会理你。整个拓扑从上到下大致是video节点用户空间取流 └── rkispISP └── mipi_dphyMIPI物理层 └── xc9922bsensor/sensor桥接芯片XS9922B在驱动模型里被当作一个V4L2 subdev来注册而不是自己注册字符设备。我们通过media-ctl把各个实体链接起来之后RKISP驱动会负责调用每个subdev的s_stream回调按从下往上的顺序把链路打开。如果哪个节点没接上打开video设备时就会报pipeline错误。2.1 subdev驱动要实现的几个核心回调在RK3568平台上一个能正常工作的XS9922B驱动至少要实现这几个v4l2_subdev_opsinit_cfg / set_fmt配置输出格式比如设置MIPI data type、lane数、分辨率。s_stream视频流开启和关闭的总开关这里要处理AHD通道锁定、内部PLL配置、MIPI输出使能。s_power管芯片上下电一般会配合复位引脚操作。get_mbus_config / set_mbus_config告诉上层当前MIPI总线是几lane、是连续时钟还是非连续时钟、是否支持virtual channel。有一个常见误区是只在s_stream里把寄存器值写一遍就完事。实际上在rkisp的启动流程里先调用s_power(1)上电再调用set_fmt约定格式然后才轮到s_stream。如果s_power里真的做了硬复位芯片在后续set_fmt阶段寄存器就全丢了所以复位时序放在s_power里要注意和s_stream的配合。我这边把硬件复位和寄存器初始化都放在s_stream里做s_power只负责电源使能和解除复位保持这样能减少很多状态错乱问题。2.2 为什么必须走Media Controller而不是自己开设备有人会问直接用I2C把寄存器配一遍再用DMA把MIPI数据端到端搬运出来不行吗对于单片机开发来说确实可以这么想但在RK3568上这不是最优解。RK3568的ISP和MIPI D-PHY都是独立硬件模块MIPI接收到的数据要先进入ISP的虚拟通道ISP内部还有Crop、Scale、3A统计等一连串处理模块这些模块的工作模式完全由media控制器统一管理。你不注册subdev、不建立拓扑链接ISP就不知道数据从哪来自然也就出不了图。另外用户态工具也依赖这套框架v4l2-ctl、media-ctl、libcamera都是基于media拓扑工作的。把XS9922B的驱动做成标准subdev相当于整套调试工具链全部打通后面排查问题会轻松很多。3. 设备树选型与XS9922B节点配置别在DTS上浪费一下午RK3568的设备树文件在社区里确实出了名的乱各厂商板子、OpenHarmony分支、Android分支、主线内核分支文件名五花八门有些甚至同名文件内容还不一样。很多新手第一步就是在dts树里迷路。我选设备树的思路很简单先看板子上的实际核心板型号和RAM颗粒规格再找对应config里默认编译目标最后对比dts里pinctrl和GMAC这类关键外设节点是否和原理图对得上。千万不要凭文件名猜测。对XS9922B来说需要配置的设备树节点有三个地方I2C从设备节点、MIPI D-PHY的端口连接、以及ISP pipeline的默认链路。I2C节点是核心其他节点配置得好不好会直接影响能不能搜到实体。3.1 I2C从设备节点怎么写我这里挂的是I2C3总线芯片从机地址由硬件地址脚决定多数板卡默认是0x40个别的会配到0x36具体看原理图上的上拉下拉。下面是一段可用的节点写法i2c3 { status okay; xc9922b: xc9922b40 { compatible vendorname,xc9922b; reg 0x40; pinctrl-names default; pwdn-gpios gpio3 RK_PC5 GPIO_ACTIVE_HIGH; reset-gpios gpio3 RK_PC6 GPIO_ACTIVE_HIGH; rockchip,camera-module-index 0; rockchip,camera-module-facing back; rockchip,camera-module-name default; rockchip,camera-module-isp default; port { xc9922b_out: endpoint { remote-endpoint mipi_dphy0_input; >csi2_dphy0_hw { status okay; }; csi2_dphy0 { status okay; ports { #address-cells 1; #size-cells 0; port0 { reg 0; mipi_dphy0_input: endpoint0 { reg 0; remote-endpoint xc9922b_out; >static int xc9922b_check_chip_id(struct xc9922b *dev) { int ret; u8 id 0; ret xc9922b_read_reg(dev, 0x00, id); if (ret 0) return ret; dev_info(dev-dev, xc9922b chip id: 0x%02x\n, id); if (id ! XC9922B_CHIP_ID) return -ENODEV; return 0; }读不到ID时不要急着改地址先用示波器量一下电源、时钟、复位引脚波形。特别是复位引脚很多模块在上电瞬间需要保持一段固定低电平然后在外部电源稳定之后再拉高。如果板级PMIC的默认输出顺序不对芯片可能一直处于undefine状态I2C读写没有任何应答。4.2 s_stream回调里的关键三步配置s_stream是驱动里最复杂、也最容易出问题的回调。我梳理的配置顺序是固定的三步先配置AHD输入通道和制式再配置MIPI输出格式最后使能MIPI传输并把芯片状态置为running。第一步AHD输入通道配置。XS9922B每个输入通道都要单独设置信号类型和分辨率。AHD常见的是1080p25fps和720p30fps。这一步要和前端摄像头的实际输出严格对应如果摄像头输出1080p但芯片里配成720p芯片的自动均衡和同步检测会一直锁定失败驱动里读到的状态寄存器会显示No Signal。这里可以先做一个寄存器dump把每个通道的同步锁定状态位打出来对照。第二步MIPI输出配置。这里要指定data type、lane数量和输出时钟。MIPI data type会根据像素格式变化XS9922B本来的输出可能是YUV422或者BT656格式通过MIPI CSI-2发送时一般用YUV422-8bit格式。RK3568的ISP端会对这个格式做进一步处理最终送到用户空间的格式可以由ISP的video节点决定但中间MIPI链路上的data type必须一致否则出来的颜色会整体错乱。第三步使能MIPI输出。写完寄存器后最好延时几个毫秒再读一次MIPI状态寄存器确认发送端已经进入正常发送状态。实测中发现如果使能后立刻读寄存器某些芯片版本会有一次假状态延时后再读才稳定。4.3 寄存器初始化表应该怎么维护寄存器的值我强烈建议整理成一张静态配置表而不是散落在代码各处的裸写寄存器操作。表的结构类似static const struct reg_sequence xc9922b_init_table[] { { 0x01, 0x86 }, { 0x02, 0x05 }, { 0x03, 0x87 }, ... { 0xff, 0xff }, /* end */ };初始化时循环写入即可。这样做的好处是摄像头制式、MIPI lane修改时只需要改表里的值不用动代码逻辑。调试AHD不同制式时我基本就是切一张配置表重编驱动、加载、抓图验证效率比改代码重新编译高很多。5. 调试实录我从黑屏到出图的完整排查链路这段是真正的踩坑过程。我把整个调试过程复盘一遍分三种典型现象附带排查顺序这样你遇到问题时可以照着走一遍。5.1 现象一media-ctl里看不到XS9922B实体第一步先确认I2C地址能不能探测到芯片i2cdetect -y 3如果扫描不到芯片检查电源、复位、I2C地址。如果扫描到了但没有subdev实体看内核日志里subdev驱动有没有probe成功。经常出现的情况是compatible不匹配驱动模块没和I2C设备绑定另外还要确认驱动有没有编译进内核或者以模块方式挂载后有没有正确insmod。这一步有一次特别容易忽略如果设备树里加了pwdn-gpios但GPIO控制器在probe时还没准备好驱动probe会用EPROBE_DEFER返回内核会在后续重试。日志里如果看到probe deferred字样不要慌等它重试就行真正的问题是重试几次之后依然没有成功那就要查GPIO编号对应的实际引脚对不对。5.2 现象二实体有了但抓图一直报no signalmedia-ctl的链路已经全部打通v4l2-ctl也能打开video节点但持续抓不到有效画面。这时候优先看XS9922B内部的AHD解码状态寄存器。状态寄存器里面有几个位是表示每个通道的同步锁定状态的某一位为1通道信号锁定AHD数据正常恢复。所有位都是0芯片没有收到有效的AHD信号问题基本出在物理链路或者制式配置。我先用示波器量MIPI clock lane的输出频率如果clock lane在流开启后有连续翻转说明芯片上层逻辑已经工作问题在AHD侧如果clock lane没有任何翻转说明芯片的MIPI发送端根本没拉起来问题在驱动初始化顺序。AHD侧最常见的原因是摄像头供电不对。同轴线传输的摄像头有些是12V供电带载波有些是内置隔离电源。XS9922B的输入口如果期望的是内部供电而摄像头端是外部独立供电地电位不一致会有很微弱的干扰表现在画面上就是偶尔闪一下或者完全黑屏。我遇到过一次摄像头端电源纹波偏大导致AHD解码器一直处于重新训练状态信号时而锁定时而丢失。5.3 现象三画面出来了但花屏、偏色、滚动条纹能出画面说明整体链路已经通了花屏大概率是时序不对。先查MIPI lane的data lanes映射开发板上MIPI connector的lane物理顺序和芯片输出顺序不一样是常事所以RK3568的D-PHY驱动会带lane mapping的配置能力。如果物理lane反了画面会出现一条条斜向撕裂的花屏并且噪声分布很有规律。偏色问题则要回到格式上。MIPI链路里的data type如果和ISP端解析格式不一致YUV分量会被错误解释成RGB颜色看起来就会非常奇怪。另外AHD本身是压缩域传输芯片解码后还要做一次色彩空间转换如果内部寄存器里白平衡或增益配置不对整个画面会出现整体偏绿或者偏红。遇到这种情况建议先用一条短的同轴线直接接一颗已知正常的摄像头排除线缆质量引起的解码异常。5.4 排查链路总结把上面的过程表格化现象优先检查点工具/方法无实体I2C探测、compatible匹配、上电复位i2cdetect、dmesg无信号AHD锁定状态寄存器、复位时序读取状态寄存器、示波器量CLK花屏MIPI lane mapping、lane数量查看dts配置、调整lane映射偏色MIPI data type、ISP端格式media-ctl --set-fmt、寄存器配置表偶发丢帧时钟稳定度、电源纹波示波器、长时抓帧测试这个表格基本覆盖了我调试RK3568外接Sensor和桥接芯片时的大多数场景不只是XS9922B调试OV5695、GC2053这类MIPI直出Sensor也适用。6. 源码使用指南和移植注意事项驱动源码的完整工程包括三个部分xc9922b.c/xc9922b.h存放V4L2 subdev逻辑和寄存器读写接口xc9922b_init.c存放寄存器配置表另外附一份dts补丁。编译时把它放到kernel/drivers/media/i2c/目录下在Kconfig里增加对应的配置项config VIDEO_XC9922B tristate XC9922B AHD to MIPI bridge support depends on VIDEO_V4L2 I2C help Support for XC9922B as a V4L2 sub-device.然后make menuconfig里勾选编译出ko后insmod即可。建议把驱动编成模块而不是编进内核调试阶段少烧几次固件。移植到其他RK3568板子时需要改的地方不多但都很关键。一是I2C设备树节点的总线和地址二是MIPI D-PHY节点对应的lane数量和端口号三是AHD制式配置表。其他逻辑基本可以复用因为RK3568的ISP驱动框架是统一的。最后分享一个经验正式调AHD转MIPI方案先不要直接跑整套ISP流程绕开用户态的3A库先用v4l2-ctl以最朴素的YUV格式抓一帧验证链路是否通。很多时候问题出在ISP参数和Sensor的联动配置上基础链路不通就过早调3A会浪费大量时间。链路通了之后再去调白平衡、调曝光心情会顺畅很多。本文还有配套的精品资源点击获取
返回列表