ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

无人机双路视频处理DDR3选型与调试:5个实战踩坑复盘

无人机双路视频处理DDR3选型与调试:5个实战踩坑复盘 做无人机图传和双路视频处理这个项目时我对DDR3这块存储的选择一开始真没太当回事。不就是DDR3、2G容量、1866频率这三个参数嘛照着写进BOM就行。结果从打样到软硬件联调一路踩坑踩到怀疑人生。前前后后折腾了将近两个月真正稳定跑起来之后我才意识到所谓DDR3 2G 1866这几个字背后藏着的是整个系统的带宽预算、时序余量、温度策略、PCB布局和供应链成熟度。这篇博文就把我实际踩过的5个坑完整复盘一遍从选型思路到读写控制实现、再到问题排查全部用我项目里的真实场景来说希望能帮正在做或准备做类似项目的朋友少走弯路。1. 项目需求与选型思路拆解双路视频系统为什么非它不可1.1 先算一笔带宽账双路视频到底需要多大的吞吐我做的这个无人机图传载荷核心任务是一路传感器实时采集、一路编码后通过无线链路回传同时地面站还需要能接收并显示。通俗点讲就是机载端两路视频流同时工作一路1080p60的原始视频要做ISP处理和编码另一路1080p30的预览流给飞手或地面站做实时显示。两路视频加起来每秒要处理的数据量相当可观。先来算一笔带宽账。1080p60的原始数据按RGB888算一帧是1920x1080x3约6.2MB60帧就是每秒373MB就算按YUV422算也要一帧2.6MB、每秒155MB。再加上双路并发、ISP算法里的多帧缓存和重排DDR3这条总线上的实际吞吐需求远远超过我觉得够用的水平。DDR3-1866的理论带宽可以这么算数据总线位宽16bit我这里的FPGA方案用的是x16颗粒每clock传2bit数据DDR就是Double Data Rate有效频率是933MHz。那么理论带宽就是933MHz x 16bit / 8 1.866GB/s。理论值看着很充裕但注意这只是理论峰值。实际还得扣除刷新开销、读写总线翻转开销、bank冲突等待以及仲裁器的切换损耗。实测下来DDR3-1866 x16的可用带宽大概在理论值的70%-80%左右也就是1.3GB/s到1.5GB/s。这个数字才是真正可以用来规划视频流量的。1.2 2G容量的真实价值不只是能存多少帧2Gbit也就是我们常说的2Gb颗粒注意是bit不是Byte的DDR3颗粒换算下来是256MB。有人可能觉得256MB在现在动辄几个GB的DDR4面前小得可怜。但在无人机图传这种场景里这个容量刚好卡在够用且成本可控的甜点上。我当时的缓存规划是这样的一路1080p60的ISP处理需要至少3帧的输入缓冲做3D降噪和HDR合成按YUV422算3帧就是7.8MB编码器需要参考帧和重建帧H.264/H.265编码一路1080p60大约需要6到8帧的参考缓冲区约20MB另一路预览流单独开一个4帧的环形缓冲2.6MB x 4约10MB。再加上系统跑Linux的DDR内存空间、DMA描述符、网络协议栈缓冲全部加在一起大概需要150MB到180MB。这时候就体现出2Gbit颗粒的优势了单颗256MB容量一颗就能覆盖全部需求不需要走多片并联的方案PCB面积和布线复杂度都降下来了。如果用1Gbit颗粒得两片并联地址线复用问题倒是不大但引脚多了一倍布局走线的压力就上来了。如果用4Gbit颗粒单颗512MB容量富余但成本上去而且小封装型号不好找。所以2Gbit这个容量在这个项目里是性价比最平衡的选择。1.3 为什么不上DDR2或DDR4综合考虑下的最优解这里顺便聊聊DDR2、DDR3、DDR4三代的区别很多做嵌入式的新手容易在这上面纠结。DDR2的工作电压是1.8V频率上限大概在800MT/s左右带宽明显不够双路视频用DDR4工作电压降到了1.2V频率轻松上到2400MT/s以上但控制器和PHY的设计复杂度更高而且FPGA中端型号对DDR4的支持一般只在高端系列里才有授权和License成本也高。DDR3卡在中间工作电压1.5V低电压版DDR3L是1.35V频率从800MT/s到2133MT/s都有覆盖关键是各类FPGA和SoC对DDR3的支持最成熟IP核稳定PCB设计参考资料多供应链上2Gbit的DDR3颗粒选择也非常丰富。在无人机这种对功耗、体积、成本都敏感的嵌入式场景里DDR3就是当前时间点综合性价比最高的选择没有之一。提示如果你的项目对功耗特别敏感可以关注DDR3L低电压版1.35V工作电压比标准DDR3的1.5V能省不少功耗。但要注意DDR3L和DDR3的引脚兼容但控制器端需要正确配置MR寄存器里的VDDQ等级这个细节后面还会提到。2. 五个大坑逐个拆解从选型到量产的完整复盘2.1 坑一标称1866的颗粒实际只能稳定跑1600这是我踩的第一个坑也是最隐蔽的一个。我最初选的是一颗某大厂的DDR3 2Gbit颗粒数据手册上清清楚楚写着支持DDR3-1866时序条目是CL11。打样回来之后我按1866的频率去配置FPGA的DDR3 IP核结果跑稳定性测试时发现长时间高负载下会出现偶发的数据校验错误。把频率降到1600同样一套配置跑24小时都没有问题。后来仔细查了数据手册里的小字才发现这颗颗粒跑到1866需要CL11而CL11对应的tRCD和tRP参数都相对紧张对电源噪声和PCB信号完整性非常敏感。我当时的PCB是4层板电源平面不完整DDR3供电直接用了一颗低压差线性稳压器LDO纹波指标一般。在这种供电条件下1866频率的时序余量被压缩得很厉害稍微有点温度漂移或电压波动就会出错。解决思路有两个方向。第一是硬件上优化供电把DDR3的VDD和VDDQ分开供电用开关电源加二级LC滤波实测纹波可以压到30mV以内第二是在固件上做降频保稳直接把控制器配置成1600MT/s用CL8的松时序换取稳定。我最终选择的是双管齐下硬件上重新设计了供电但固件里依然把默认频率定为16001866作为一个超频选项留给有特殊需求的场景。注意DDR3-1866的颗粒在嵌入式场景下的实际稳定运行频率往往要打八折。对于无人机这种振动大、温度变化剧烈的环境我更推荐把额定频率当宣传值以实测稳定值为准。选型时宁可选择标称2133的颗粒跑1866也不要选标称1866的颗粒跑1866。2.2 坑二双路读写并发导致的内存带宽假性不足第二个坑出现在双路视频真正同时工作的时候。单路视频推流测试一切正常但只要把第二路视频一起打开整个系统就开始出现周期性的掉帧——每到某个时间点编码器的输入缓冲就会突然空掉然后画面卡顿一下。我一开始以为是CPU/FPGA处理性能不够查了半天发现不是。后来用逻辑分析仪抓DDR3总线的读写请求才发现问题出在刷新Refresh上。DDR3颗粒需要周期性刷新来保持数据这个刷新操作会占用总线时间刷新期间所有读写请求都要等待。当双路视频同时高负载读写时总线利用率已经很高刷新操作一插入瞬时带宽就出现了缺口。这个问题在DDR3-1866的配置下尤其明显频率越高刷新间隔越短刷新开销占比越高。我当时的做法是调整刷新策略把默认的每隔tREFI刷新一行改成集中刷新Burst Refresh也就是把若干行刷新集中到一个时间窗口内完成虽然这个窗口期间总线会短暂完全不可用但窗口内的数据预取和缓冲可以掩盖这个间隙。同时我在读写仲裁器上做了QoS服务质量策略给编码器写通道分配高优先级给ISP读通道分配中等优先级给CPU访问分配低优先级。这样即使在刷新窗口附近出现瞬时带宽争抢最先被牺牲的也是非实时性任务视频链路不会中断。2.3 坑三PCB走线不等长DQS和DQ的时序偏差导致随机数据错误第三个坑是最让人头疼的一类——故障看起来毫无规律有时候跑几小时才出现一次有时候一上电就死。我最初怀疑是颗粒本身的体质问题换了好几片都一样。后来静下心来查PCB设计文件才发现问题出在DDR3走线的等长控制上。我用的FPGA是BGA封装引脚扇出之后去往DDR3颗粒的走线在BGA区域有一段不可避免的绕线。当时布线工程师为了赶进度DQ0-DQ7这组数据线做到了等长但DQS差分对和DQ组的走线长度差了大概400mil。在DDR3-1600下这个偏差对应的时延差大约是60ps左右看着不大但在高速信号下足以造成数据采样窗口的偏移。排查手段是用FPGA内部的调试工具对DDR3 PHY的读数据眼图做扫描发现眼图的张开度明显偏小而且采样点位置不稳定就是那种看着能过实际余量很小的状态。解决办法是把DQS和DQ的走线长度严格对齐到±20mil以内同时把DQS差分对的间距控制好保证差分阻抗100Ω。重新打样之后眼图质量有了明显改善读数据余量从原来的不到100mV提升到了300mV以上。提示高速DDR3走线不是能通就行。DQ组内等长、DQS与DQ等长、地址控制线与CLK等长这三组关系都要控制好。特别是DQS和DQ因为DQS是采样时钟它和数据的相对位置直接决定了能不能正确采到数据。如果PCB已经定型没法改可以尝试在控制器里调整读数据眼图的位置Read DQS Delay但这是治标不治本余量会小很多。2.4 坑四高温环境下数据保持时间缩短自刷新模式不稳定无人机在夏天户外飞行时机舱内温度可以轻松到70℃以上DDR3颗粒的数据保持时间Retention Time会随着温度升高而显著缩短。这个问题平时在常温下根本测不出来一旦到了高温环境就会出现飞行一段时间后图传画面花屏的诡异故障。刚开始我以为是无线链路问题查了射频部分没发现异常。后来在实验室用热风枪给机载板加热模拟高温环境发现温度升到75℃左右时DDR3控制器报出大量的ECC错误我才意识到是内存数据保持问题。DDR3的数据保持时间在85℃以下通常是64ms这个参数对应的是刷新周期tREFI。但在高温环境下电容漏电加快数据保持时间会大幅缩短。如果固件里还按照常温的刷新间隔去配置就会在两次刷新之间出现数据丢失。解决方案有两步。第一步是把刷新周期调短从默认的7.8us对应64ms/8192行调整到3.9us这样即使温度升高也能保证数据不会在两次刷新之间丢失。第二步是启用DDR3的自刷新温度补偿功能TCSR当温度传感器检测到芯片温度升高时自动提高自刷新频率。对于无人机这种工作温度范围跨度大的场景这两步都非常必要。注意在高温环境下DDR3的刷新功耗也会上升。刷新频率加倍意味着功耗也接近加倍。我当时实测刷新间隔从7.8us改成3.9us之后DDR3功耗增加了约150mW整个系统功耗从9.8W升到了10W左右。对于电池供电的无人机来说这个功耗增量要提前留出余量。2.5 坑五供应链里同型号不同体质的颗粒兼容性测试必须做第五个坑完全是我大意了。项目定型之后为了保证量产供货稳定我同时在两家代理渠道下了订单拿到的颗粒虽然型号一样但批次不同。结果在产线上调试时发现这批颗粒和上一批在同样的固件配置下稳定性表现差异很大——有一批用1866频率跑完全没问题另一批在1600下都会偶尔报错。后来查了颗粒上的Marking Code标识代码才发现两个批次的Die版本号不同一个版本较老一个是新制程的改版。虽然数据手册上的参数一样但实际的时序裕量和电气特性有细微差别。这件事给我最大的教训是对于DDR3这种高速存储器件选型阶段不仅要定型号还要锁定具体的Die版本和Marking Code并且在固件里预留多套时序配置文件在产测阶段自动检测颗粒版本并加载对应的配置。我后来还专门做了一个批量测试工装通过FPGA内部的BISTBuilt-In Self-Test模块对每颗DDR3做高温和低温扫频测试确保物料一致性。3. DDR3读写控制实现从时序配置到双路仲裁的完整方案3.1 DDR3初始化流程一个都不能少的状态机在FPGA里实现DDR3的读写控制第一步是正确完成初始化流程。这个流程ARM的Corex-A系列处理器可能已经帮你做完了但如果你用的是FPGA外部控制器的方案就必须要自己在RTL里实现。DDR3的初始化大致分为这么几步上电后保持CKE为低电平至少100us然后拉高CKE发送NOP命令等待至少500us接着执行复位命令RESET#引脚拉低至少100ns之后依次写入模式寄存器MR2、MR3、MR1、MR0配置CAS Latency、突发长度、读写延迟等参数再执行ZQ校准命令最后等待DLL锁定进入正常操作状态。这套流程里最容易出错的是模式寄存器的配置顺序和数值。比如MR0寄存器里的CLCAS Latency和突发长度是绑定在一起的不同频率下的合法组合不同。DDR3-1866一般推荐CL11BL8DDR3-1600则可以用CL8BL8。我当时就是用Verilog写了一个状态机来管理这套流程每个状态之间加了足够的延时计数器避免时序竞争。3.2 Bank管理与行激活策略为什么突发长度会拖累带宽DDR3内部被划分成8个Bank每个Bank是一个存储阵列。读写数据时要先激活ACT对应的行然后才能进行读写操作。如果连续访问同一个Bank的不同行就需要先预充电PRE关闭当前行再激活新行这个行切换的时间开销很大。我在调试中遇到的典型性能瓶颈就在这里我的ISP算法是顺序扫描图像帧访问模式是连续的地址但图像的行跨度和存储页的大小并不对齐经常出现访问到某个地址时所在Bank的行已经变了不得不等预充电激活的延迟。解决办法是修改地址映射策略。DDR3控制器里有一张地址映射表决定物理地址的哪几位作为Bank地址、哪几位作为行地址、哪几位作为列地址。默认配置下低位地址作为列地址高位作为行地址。但对于视频这种大块顺序访问的场景我更推荐把中间位作为Bank地址这样连续访问的时候可以自动在多个Bank之间交替减少行冲突概率。这个优化做下来实测有效带宽提升了约12%。3.3 双路视频的仲裁策略为什么牺牲CPU也不能牺牲编码器双路视频并发访问DDR3读写请求会同时涌向控制器仲裁器的设计直接影响系统的实时性。我这边的仲裁策略是固定优先级时间片轮转的混合方案。具体来说编码器写通道从ISP到DDR3拥有最高优先级因为编码器一旦出现输入缓冲空置就会导致编码中断直接影响输出码流。ISP读通道从DDR3读取原始帧做处理是第二优先级因为ISP的处理节奏是固定的延迟会导致处理链路阻塞。CPU访问通道的优先级最低但为了保证系统不因饥饿而死锁我用了一个加权轮询机制每16个时钟周期里CPU通道至少能获得2个周期的访问机会。这个策略的效果是双路视频流跑满时CPU访问会有一些延迟但视频链路完全不受影响。实测下来编码器写通道的等待时间从平均210ns降到了80ns以下总线利用率稳定在75%左右。3.4 关键时序参数配置表可直接抄作业的数值参考做DDR3读写控制最核心的就是时序参数。这里把我试验后稳定运行的配置列出来大家可以作为参考起点但最终还是要根据自己选的颗粒型号和实测结果来调整。参数DDR3-1600 CL8配置DDR3-1866 CL11配置说明tCK1.25ns1.07ns时钟周期CLCAS Latency811读命令到数据输出的延迟tRCD811行激活到列命令的延迟tRP811预充电命令到行激活的延迟tRAS2426行激活到预充电的最短时间tRC3237行激活到下一次行激活的最短时间tRFC128160刷新命令间隔tREFI7.8us7.8us刷新周期高温下调至3.9ustWTR46写命令到读命令的最短间隔tWR1214写数据到预充电命令的最短间隔这个表是我在Xilinx Artix-7 FPGA上验证过的配置控制器IP用的是Xilinx的MIG颗粒是镁光MT41K256M16HA-125。如果你用的是别的FPGA平台比如Intel Cyclone V或者国产FPGAIP核的配置界面可能不一样但底层时序参数是通用的对照着填就行。3.5 写数据掩码与字节使能视频帧边界处理的一个小经验最后一个实操细节是关于写数据掩码DM的。视频处理时经常需要做帧内局部更新比如OSD叠加、ROI裁剪这些操作往往不是整帧写入而是只写某几个像素块。如果每次局部更新都按整行突发去写带宽浪费很严重。正确的做法是控制器的写数据掩码信号按字节粒度屏蔽不需要写入的字节。我刚开始实现的时候没注意这个细节OSD叠加性能很差后来把掩码逻辑在DMA层面对齐到字节边界整个叠加操作的耗时降了一半以上。4. 选型与验证清单照着做能省两周时间4.1 颗粒选型的五个关键维度经历这一轮踩坑之后我总结出DDR3选型要看的五个维度缺一不可。第一是品牌和原厂渠道。DDR3颗粒市场鱼龙混杂拆机片、翻新片、Remark片到处都是。我的建议是只从原厂授权代理商拿货拿到货之后第一件事是查Marking Code到原厂官网验证真伪。第二是Die版本。同一型号的颗粒可能对应多个Die版本不同版本的时序特性和功耗表现有差异。选型时尽量选已经量产半年以上的成熟版本新版本上市初期往往有一些隐藏bug。第三是温度等级。工业级-40℃到95℃和商业级0℃到85℃的颗粒价格差不了太多但无人机这种应用场景高温是常态直接上工业级最稳妥。第四是封装形式。96-ball FBGA是标准封装但要特别注意球距和PCB焊盘的匹配。有些国产颗粒虽然信号定义一样但封装尺寸略有差别贴片时容易对不准。第五是供货稳定性和多源替代。关键物料一定要准备第二供应商但替代物料必须在设计阶段就做好兼容性验证而不是等到量产出问题再临时换。4.2 实测工具与方法如何快速判断DDR3是否稳定判断DDR3系统是否稳定不能只看能开机。我推荐三套测试方法覆盖从底层到应用层的验证。第一套是FPGA自带的BIST测试在MIG IP核里可以直接例化一个简单的数据校验模块对着固定地址写入、读出、比对。这个测试能快速发现地址线和数据线的连接错误但覆盖不到时序问题。第二套是伪随机数据测试用LFSR线性反馈移位寄存器产生伪随机数写入DDR3然后读出比对。这个测试比固定数据更接近真实使用场景能暴露一些数据相关的错误模式。第三套是系统级压力测试把双路视频流推到最大分辨率同时跑一个CPU密集型的校验任务模拟真实工况下DDR3的负载。这个测试要在高温和低温环境下都跑至少连续跑48小时以上。我个人的经验是如果这三套测试都能通过这款DDR3配置基本可以放心量产。如果任何一套测试出现偶发错误先不要急着换颗粒按照前面坑一和坑三的思路去检查供电和PCB走线问题往往出在那里。4.3 功耗与散热实测无人机场景下的真实数字最后分享一组我在实际项目中测到的功耗数据。整机在室温25℃、双路1080p视频全速工作时的功耗如下FPGA内核功耗2.1WDDR3颗粒功耗0.85W1.5V供电实测电流约0.56ADDR3 PHY功耗0.3W其余电路约5.5W整机功耗接近8.75W。在55℃的环境温度下DDR3功耗升到了1.1W整机功耗约9.2W。这个功耗增量主要来自刷新频率提高和漏电增加。如果机身没有主动散热要靠PCB铜箔和散热片被动散热DDR3颗粒的温度会比环境温度再高10℃左右。我当时在机壳里加了一块1mm厚的铝制散热片贴在DDR3颗粒上配合机臂底部的通风孔实测颗粒温度比裸奔状态低了8℃效果很明显。如果你在无人机上做类似的系统散热设计一定不要忽略DDR3这个看起来不起眼的器件。5. 常见问题与排查技巧实录从失败中总结的速查手册5.1 上电后DDR3初始化失败的排查思路DDR3初始化失败是所有问题里最好排查也最好解决的大部分情况下是硬件问题。先查CKE引脚是否正常拉高RESET#引脚时序是否符合要求再查时钟信号是否稳定最后用示波器抓一下模式寄存器配置命令的波形看DDR3颗粒有没有正确响应。软件方面的可能原因包括FPGA IP核的时钟频率配置错了、DLL没有锁定就开始了初始化流程、模式寄存器里的CL配置超出了颗粒的能力范围。用排除法一项项排查基本能在半小时内定位。5.2 偶发数据错误但系统能工作的玄学问题还有一种情况最让人抓狂系统能正常跑起来功能也正常但偶尔会出现一个像素花掉、或者某个数据校验不过。这种偶发错误通常指向三个方向供电纹波过大、走线串扰、时序余量不足。我的排查顺序是先看电源纹波DDR3的VDD纹波必须控制在50mV以内再看读数据眼图判断数据采样窗口还剩多少余量最后检查PCB走线特别是DQ和DQS的等长关系。按照这个顺序90%的偶发问题都能找到根因。5.3 一个快速定位DDR3问题的实用技巧如果你手头没有高端示波器或者逻辑分析仪这里分享一个土办法。FPGA的调试接口一般都能内部例化ILAIntegrated Logic Analyzer虽然没有外部探头但可以通过AXI接口或者Native接口实时观察DDR3控制器的内部状态信号。我当时就是通过ILA抓取MIG控制器的app_rdy和app_wdf_rdy信号观察读写请求是否经常处于等待状态。如果app_rdy长时间拉低说明控制器内部正在处理刷新或预充电你的访问请求被堵住了这时候就能判断是带宽不够还是时序配置不合理。5.4 双路视频项目DDR3调试的个人体会最后聊一点我在这个项目中的个人体会。DDR3在嵌入式项目里属于那种看起来简单、做起来复杂的器件。从选型到稳定运行问题往往不出在DDR3本身而是出在和DDR3配套的供电、PCB、时序配置和系统架构上。我最大的一个教训是不要在项目初期为了省几天时间跳过DDR3的详细仿真和验证。前期花三天时间把电源做好、把走线等长控制好、把时序参数配置对后期能省下三个星期去排查那些看起来随机、实际上有规律的诡异故障。DDR3这条总线你尊重它它就不会给你添乱。
返回列表