
搞过瑞芯微平台的兄弟应该都有同感芯片本身不算难难的是第一次把SDK跑起来的那几天。我第一次拿到RV1126B这颗料时看着一整套SDK代码心里其实是发怵的尤其是DDR初始化和USB烧录调试这两个环节教科书上写得云里雾里实际调起来才知道什么叫“差一个参数就起不来”。这篇文章不聊理论就聊我实际移植RV1126B SDK的完整路径从DDR配置到USB调试把关键节点、参数依据和踩过的坑一起写清楚给正在搞这颗芯片或者同类平台的朋友做个参考。1. 整体设计思路与SDK结构剖析1.1 拿到SDK后的第一件事先别急着编译RV1126B的SDK和RK其他平台的套路基本一致用repo管理拉下来之后会有一堆东西u-boot、kernel、buildroot、app、docs、tools等。很多新手上来就敲编译命令结果不是缺工具链就是缺依赖折腾半天。我的经验是先花半天时间把SDK的目录结构和README过一遍重点看三样东西第一是repo清单确认当前SDK版本默认对应的u-boot、kernel分支避免各个子仓库版本不匹配导致后面编译报一堆莫名错误第二是docs目录下的板级支持文档里面通常会写清楚当前SDK支持哪些板型、需要用哪个配置文件、烧录工具在哪个路径第三是交叉编译工具链的位置和版本RV1126B是ARM Cortex-A7双核带NPU工具链需要用SDK自带的那一套别自己到网上去乱下arm-none-eabi或者gcc-arm-linux-gnueabihf版本不对会有隐性问题。RV1126B的SDK在移植时要特别注意一个点这颗芯片虽然和RV1126同属一个家族但外设资源、DDR支持能力、电源时序是有差异的。你拿着RV1126的板级配置去适配RV1126B大概率会在启动阶段就卡住。所以我个人的习惯是不要基于旧工程的配置来修修补补而是以SDK中默认存在的RV1126B相关配置为底再把自定义外设的改动覆盖上去。这样能最大限度减少“历史包袱”导致的诡异问题。1.2 板级配置文件的层级关系瑞芯微的SDK中板级信息分散在多个地方搞懂它们的关系是移植的第一步。主要涉及u-boot中的rk1126b_defconfig和对应的dts文件kernel中的rv1126b-evb*dts和对应的defconfigbuildroot中的rv1126b_defconfigrockchip的BoardConfig-*.mk部分脚本会引用烧录工具所需的parameter分区表文件这几个文件之间是有依赖关系的。比如u-boot里的DDR配置决定了能否正常初始化内存kernel的dts决定了外设的复用、GPIO供电、USB phy等parameter文件决定了烧录时的分区布局buildroot决定了根文件系统里装了哪些应用和库。移植工作表面上是在改配置实际上是在梳理一条从上电到系统完全跑起来的链路。我在实际移植时会先画一张简化的启动链路图标注每个阶段由哪个配置/代码控制然后在动手改配置前先明确每个文件的作用和修改边界。这样即使某个环节出错也能很快判断问题出在哪个模块而不是漫无目的地乱试。2. DDR配置决定能不能点亮的关键一步2.1 DDR配置到底在配什么RV1126B移植中最容易“一夜回到解放前”的就是DDR配置。很多人不理解DDR初始化不是芯片内部自动完成的吗为什么还需要我们自己去配实际上任何SoC都需要一段引导代码来完成DDR控制器的初始化因为DDR控制器的时序参数、刷新周期、阻抗校准、驱动强度这些都要和具体DDR颗粒的规格匹配。RV1126B的DDR初始化代码在u-boot的SPL阶段执行由瑞芯微提供的基础代码加上一份ddr参数列表构成。DDR参数列表本质上是一张包含不同内存颗粒信息、不同容量、不同频率组合的表格每个条目里有几十个参数列地址位宽、行地址位宽、bank数、时序参数tRCD、tRP、tRAS、tRC等、刷新时间、片选配置等。RV1126B支持DDR3、DDR4、LPDDR3、LPDDR4不同颗粒类型对应不同的物理层配置。所以移植时你要做的第一步是明确我的板子上用的到底是哪颗DDR颗粒、什么类型、几颗组合、总容量多少。瑞芯微SDK自带的DDR配置一般覆盖了市面上常见的颗粒型号但你自己的PCB上用的颗粒如果不在默认清单里就需要手动添加或改参数。2.2 颗粒选型与参数来源如果你用的是DDR3 1GB常见的选择有南亚的NT5CC128M16IP、镁光的MT41K128M16JT、海力士的H5TQ1G63EFR等。SDK自带的DDR配置里通常能找到这些常见型号但型号后缀不同、生产批次不同DDR3的时序谱比如tCK、CL都会略有差异。最好的办法是直接向供应商要DDR颗粒的datasheet或者去官网下载对应的数据手册然后对照SDK里已有的相似配置逐个核对关键参数。最关键的几个参数内存类型DDR3还是DDR4对应控制器模式Row/Col/Bank地址位宽决定颗粒容量和地址映射数据总线位宽16bit还是32bitRV1126B一般用16bit×2颗或者16bit×1颗CL-tRCD-tRP最常见的时序三元组例如11-11-28刷新周期tREFIDDR3通常是7.8usDDR4不同频率等级比如1066/1333/1600这些对应不同的时序配置注意同样是标称“1GB DDR3”的颗粒不同厂家的地址位宽可能是不同的。有的用8个bank×8K row×1K col有的用8个bank×8K row×2K col在配置表里填错一个字位就会导致寻址错误表现就是DDR初始化卡住或者系统起来后内存测试大片报错。2.3 配置修改与验证瑞芯微SDK的DDR配置在u-boot/arch/arm/mach-rockchip/dram_para.c之类的文件中里面是一个一个的结构体数组结构体定义了几十个字段。如果你找不到完全匹配的颗粒可以找一个最相近的条目复制一份然后按照datasheet逐一修改参数。改完之后编译u-boot烧录然后看串口打印。正常初始化DDR后会打印类似OUT of DDR或者ddr_init相关的信息接着进入后续的启动流程。如果参数不对常见表现是SPL阶段反复重启、串口无输出、或者输出乱码。这个时候不要急着去乱调参数先确认几个基础项供电电压是否正确。DDR3一般1.5VDDR3L是1.35VRV1126B的PMIC或DCDC配置里如果没有设置正确的电压DDR颗粒根本不会正常工作。内存颗粒的片选信号和地址线有没有接反。这类硬件异常会直接表现为初始化失败。DQS/DQ的等长布线是否合理。如果硬件布线很差单纯调软件参数救不回来。2.4 DDR稳定性测试DDR初始化通过不等于DDR稳定。我见过不少板子能开机但跑一段时间就随机重启、打开摄像头崩溃、神经网络推理结果错误最后定位到DDR时序余量不足。所以DDR配置改完之后一定要跑稳定性压力测试。瑞芯微SDK提供了DDR压力测试工具一般在u-boot阶段可以用ddr_test命令来测试不同的地址段和读写类型。建议设置不同的频率等级分别运行测试比如1333MHz跑一轮、1600MHz跑一轮对比稳定性。如果高温环境下测试不稳定可能需要在时序参数上适度放宽或者降低运行频率。另外提醒一点如果板子上的DDR频率需要做到标称最高频率请务必确认PCB对DDR信号的阻抗控制和走线长度是达标的。我在调试一块Mini板时DDR2层板走线绕来绕去结果1600MHz怎么加压测都过不了降到1333MHz才稳定。这种问题靠改配置是解决不了的。2.5 手写DDR参数的经验分享如果你的颗粒在SDK里确实找不到相近的配置需要从零手写参数我建议按以下顺序来先查颗粒datasheet里的AC特性表把所有时间参数tCK、tAA、tRCD、tRP、tRAS、tRC、tRFC等整理到一张Excel里。对照SDK里已有的同类型颗粒配置模板理解每个字段对应的实际意义不要机械地照搬数值。先用保守的低频率比如DDR3跑800MHz把系统调通再逐步提高频率。每个频率点都跑一遍稳定性测试记录结果做成一张表方便以后排查问题。这个过程很耗时但一旦走通你对控制器和颗粒之间的配合关系会有很直观的理解。以后再换颗粒、换板子效率会高很多。3. SDK编译与烧录从源码到可运行系统3.1 编译流程和关键配置DDR配置搞定之后就是整套SDK的编译。RV1126B的SDK编译流程和瑞芯微其他平台是一脉相承的在SDK根目录下执行./build.sh lunch选择板型然后执行./build.sh开始编译u-boot、kernel、buildroot等。编译过程中比较常见的问题是网络依赖。buildroot在构建时会去下载很多源码包如果网络环境不好往往会在某个包上下载超时导致构建中断。强烈建议在完全编译之前先执行make进行源码包预下载或者配置好内网镜像源。另外要确认的是分区表。瑞芯微的平台默认有两套分区方案一套是uboot专用的大分区一套是传统按功能划分的分区。SDK里的parameter文件控制实际烧录时的分区布局。如果你的板子要支持OTA升级、A/B分区、或者需要独立的cache分区需要在parameter中提前规划好。我在第一次移植时就因为直接使用SDK默认的parameter文件导致rootfs分区大小不够系统起来后只读。后来改成自定义parameter把rootfs大小调大顺带把/userdata分区独立出来才彻底解决存储空间管理的问题。3.2 烧录工具的选用RV1126B支持两种常见的烧录方式Windows下的RKDevTool和Linux下的upgrade_tool。两者本质都是利用瑞芯微的USB下载协议把固件烧录到Flash中。板子进入下载模式的方式一般是按住板子上的恢复按键RECOVERY再上电或者通过命令让系统进入loader模式。烧录之前需要先安装好驱动。Windows下RKDevTool第一次插上设备时会提示安装驱动如果识别不到设备多半是驱动没装好。Linux下则需要确认udev规则是否包含了瑞芯微的设备ID。烧录时我习惯把update.img下载好然后直接做整体烧录。对于开发调试阶段其实也可以用分区方式逐个烧录。比如只改了kernel就只烧boot分区只改了u-boot就单独烧loader。这样能大幅缩短调试周期。3.3 烧录后的启动日志分析如果一切顺利烧录完成重启后串口工具比如minicom、putty、或者瑞芯微的串口调试助手里应该能看到完整的启动信息。RV1126B的串口默认是UART2波特率15000001.5Mbps。注意别用默认的115200否则打印出来的是一堆乱码。从启动日志里我们要重点看几个标志性节点DDR初始化打印确认DDR参数有没有正确加载U-Boot版本号和编译时间Kernel解压的地址和大小文件系统挂载是否成功出现init进程的启动标志说明用户态已经开始跑起来了任何一个节点卡住都可以用二分法定位。比如卡在DDR初始化那就是SPL阶段的DDR配置问题卡在Kernel加载阶段可能是kernel镜像本身有问题也可能是FIT image打包时的校验不过到了文件系统阶段就检查分区表和rootfs的格式是否匹配。4. USB调试把串口之外的另一扇窗打开4.1 USB模式的切换逻辑RV1126B的USB控制器支持多种工作模式device模式比如RNDIS、ADB、UVChost模式接U盘、鼠标键盘以及OTG模式。在开发阶段最常用的其实是USB device模式通过USB线把板子连接到PC可以实现adb调试、网络共享RNDIS、文件传输等功能。瑞芯微的USB配置在设备树dts中主要是usbdrd3节点或usb2phy节点的状态控制。RV1126B的USB2.0 OTG口在dts中对应u2phy0、usbdrd3等节点。如果你想让USB口在默认状态下以设备模式工作需要确保dts中这两个节点的status都是okay并且外部VBUS控制GPIO的电平逻辑正确。另外USB控制器在u-boot阶段就会初始化。这也是为什么烧录工具能通过USB识别到设备。如果u-boot阶段USB初始化失败板子连接PC后通常只会显示“未知设备”或者毫无反应。4.2 配置ADB调试RV1126B的SDK自带Android调试桥ADB但默认配置不一定会开启。在buildroot中需要确认是否选择了相关软件包或者在rockchip_defconfig中启用adb相关的配置。如果你用的是纯Linux根文件系统buildroot而不是Android系统那么要启用ADB需要单独安装adbdADB daemon。瑞芯微SDK中有一个adbd包开启后会在系统启动时以服务方式运行。启用后把USB线连到PC执行adb devices应该能看到设备。我实际遇到过一种情况adbd已经启动但PC端始终识别不到设备。排查后发现是USB gadget配置有问题——设备没有正确向PC枚举出ADB接口。瑞芯微的USB gadget是基于configfs实现的需要检查/sys/kernel/config/usb_gadget/下的配置是否正确。SDK一般会在init脚本里自动配置但如果你使用了自己定制的rootfs这块很容易漏掉。4.3 用USB做串口解决无串口调试的困境有时候板子的调试串口没有引出来或者手头没有USB转串口工具这时候可以用USB gadget模拟串口。Linux内核支持g_serial模块把USB device口模拟成一个虚拟COM口。在buildroot的配置中启用相应内核模块并在menuconfig中勾选USB_GADGET和USB_G_SERIAL然后加载模块PC端就会出现一个新的虚拟串口。这个功能看起来很不起眼但在一些紧凑结构的板卡上非常实用。我曾经调试一款只留了Type-C接口的RV1126B核心板就是靠g_serial模拟串口完成了整个系统的调试工作。打印信息照样看shell照样敲效率完全不输物理串口。4.4 USB枚举异常和驱动问题USB调试阶段最常见的坑就是设备枚举失败。表现是插上USB线后PC端提示无法识别的设备或者能识别到设备但驱动安装失败。原因通常有这几个硬件层面USB D/D-走线质量差或者VBUS供电不足。RV1126B的USB口供电需要外部5V输入如果供电电流不够枚举时设备会反复掉线。PHY配置错误USB2.0 PHY的时钟配置、信号摆率配置不对也会导致枚举失败。内核日志里一般会有dwc3或者phy相关的报错。DTS节点里VBUS GPIO和实际硬件不匹配比如dts里配置了某个GPIO控制VBUS使能但实际板子上这个GPIO没有接到VBUS使能脚就会导致USB口一直处于无电源状态。遇到这类问题先用示波器量一下USB口的VBUS和D/D-波形确认硬件信号没问题再去查软件配置。千万别一上来就怀疑内核usb驱动有问题。4.5 把USB Host模式配置出来除了device模式RV1126B还支持USB Host模式可以接U盘、4G模块、摄像头等外设。在dts中把对应的usbdrd3节点的dr_mode改为host或者通过驱动动态切换。国产化替代项目中USB Host口接4G模块的案例特别多。RV1126B的USB Host口需要配置好电源控制和过流保护。在dts里有专门的vbus-supply和usb-role-switch配置。如果你的板子支持OTG自动切换还需要配置好extcon驱动的GPIO检测逻辑。5. 常见问题与排查技巧实录5.1 问题速查表以下这些是RV1126B移植过程中我遇到过的以及在技术社区里看到的高频问题整理成表格供参考问题现象可能原因排查方向上电后串口无输出DDR初始化失败、boot引脚配置错误、电源时序异常先用示波器查DDR供电、复位时序再用串口工具看是否有任何波形串口输出乱码波特率不对默认1.5Mbps、串口电平不匹配把波特率调整到1500000检查ttl电平是否到3.3VDDR初始化反复重启DDR参数不匹配、供电电压错误、地址位宽填错用SDK默认参数起机再逐步调整确认DDR类型和电压U-Boot阶段卡住不动配置文件选择错误、u-boot部分外设初始化死循环打开u-boot的早期printk观察最后一条可识别信息Kernel启动panicdts外设冲突、解压地址错误、内核驱动bug检查kernel log的PC指针通常在驱动加载阶段核对内存地址布局系统启动后USB无法识别gadget配置缺失、VBUS供电问题、驱动未启用确认configfs配置检查/var/log/messages中的usb相关日志烧录工具提示“下载失败”分区表不匹配、固件损坏、Flash型号不支持重新生成update.img换一根USB线看烧录工具的详细报错信息内存压力测试不稳定时序余量不足、PCB走线质量差、散热不佳降低DDR频率验证优化时序参数检查PMIC供电纹波5.2 一个经典案例USB识别成“未知设备”我在调试一块搭载RV1126B的工业主控板时遇到一个很折磨人的问题板子进入loader模式后Windows下RKDevTool能看到设备但插上跑Linux系统后USB口只能识别为“未知设备”。看内核日志USB gadget已经注册成功configfs配置也正常但PC端就是枚举不过来。后来一步步排查发现是dts中的usbdrd_dwc3节点缺少phys和phy-names属性导致DWC3控制器没有正确绑定对应的USB PHY。理论上说如果PHY没绑定控制器初始化应该报错才对但实际驱动对这种情况的容错处理很“安静”日志不仔细看根本发现不了。补上属性、重新编译内核后USB口马上恢复识别。这个经历让我养成了一个习惯遇到USB问题先把dr_mode、phys、phy-names、maximum-speed这些属性逐个核对。看起来是小事但每次都能把排查时间缩短一半以上。5.3 排查技巧和工具推荐嵌入式调试最讲究效率我这里分享几个提高排查效率的工具和思路串口工具的自动滚屏和日志保存minicom或SecureCRT都要开启日志保存方便后续回看启动输出也方便在群里和社区里发日志让别人帮忙分析。内核动态调试RV1126B的SDK默认开启CONFIG_DYNAMIC_DEBUG可以使用echo file drivers/usb/* p /sys/kernel/debug/dynamic_debug/control来动态打开USB子系统的调试输出不用重新编译内核。保存内核panic现场在debugfs或者串口工具里开启pstore/ramoops如果系统意外crash重启后能把前一次的kernel panic信息读出来。搭配RD_IMG_BACKUP还能做在线调试。二进制拔出对比遇到“应该能工作但实际不工作”的问题找一块官方EVB板跑同样的固件做对比测试能很快定位是硬件设计问题还是软件配置问题。6. 额外补一句移植工作做到最后拼的其实是心态和习惯。RD团队做RV1126B项目时前两周几乎天天在DDR和USB之间折腾吃亏最多的就是没有形成自己的排查清单。后来我把自己常看的检查点做成了一个简易的表格放到项目文档里每遇到一次问题就往里补一条越到后面调试越顺手。说到实际经验最后再补充一个不太起眼但很实用的小技巧在调试早期就顺手把VSCode或YouCompleteme这类代码补全环境配好因为SPL阶段的DDR配置和USB gadget配置经常要反复翻代码、反复改参数代码跳转和自动补全能节约大量时间。另外建议把DDR参数表里每个字段和datasheet里的对应关系做成注释方便以后换板子换颗粒时快速对照。这些东西在文档里看不到但做多了自然就会形成自己的“移植工具箱”。