去年年中,我们团队接了一个工业边缘计算网关的项目,需求很明确:要有双千兆、4路以上RS485、CAN、DI/DO,还得跑轻量级视觉检测,尺寸控制在工业壳体能装下的范围。评估了一圈,最后定在RK3568上。当时觉得这颗芯片资料多、生态成熟,应该比之前用全志、NXP的时候舒服很多,结果从设备树到NFS调试,再到摄像头驱动,一路踩了不少坑。我把印象最深的5个问题整理出来,附带一份可以直接照着做的实操清单,给正准备拿RK3568做边缘计算网关的朋友做个参考。
这篇文章适合正在做方案选型或已经拿到核心板开始调试的人。如果你只是刚听说RK3568,也可以先看第一部分选型逻辑,后面踩坑的部分能帮你避开很多开发中的隐藏问题。我尽量把每个问题的背景、现象、排查过程和最终解法写清楚,不绕弯子。
1. 方案选型:为什么是RK3568,而不是别的
1.1 需求驱动的选型逻辑
边缘计算网关这个品类,核心需求通常可以拆成几块:计算能力、外设接口、网络能力、环境适应性和成本。我们当时的产品需求表大概是这样的:
- CPU需要支持工业级宽温(-40℃到85℃),不能只用商业级芯片做筛选
- 至少一路千兆网口,最好是两路,方便做内外网隔离
- 4路RS485,2路CAN,若干DI/DO,串口资源要够多
- 要能跑轻量级AI模型,比如简单的安全帽检测、区域入侵检测,不需要大算力,但不能没有NPU
- 可扩展4G/5G模块和WiFi模块,需要有PCIe或USB3.0接口
- 10年以上的供货预期
逐个对照之后,RK3568确实是个很合适的选择。这颗芯片是四核Cortex-A55,主频最高2.0GHz,内部带0.8 TOPS算力的NPU,接口资源相当丰富:双GMAC、PCIe 3.0、SATA、USB3.0、MIPI CSI/DSI、8路UART、3路CAN(部分复用),RK3568J版本支持工业级温度范围。对比同价位的方案,这套外设组合拳打下来基本没有对手。
我见过不少团队在这个选型阶段就直接拍脑袋,只看了CPU频率和内存大小就定了,后面做硬件设计时发现串口不够、CAN口不够、网口只有一个,被迫外扩USB转串口,稳定性又出问题。选型这件事,真的得先把需求矩阵列出来,一个格子一个格子去比对。
1.2 和几个主流平台的实际对比
我当时认真对比了几个备选平台,各有各的坑,但综合下来RK3568的问题是“坑多但可解”,其他有些平台是“坑深且资料少”。
| 平台 | CPU核心 | NPU | 关键接口 | 工业级 | 生态完整度 | 我们Pass掉的原因 |
|---|---|---|---|---|---|---|
| RK3568J | 四核A55 2.0GHz | 0.8T | 双千兆/8 UART/3 CAN/PCIe | 支持 | 较高,资料多 | 最终选择 |
| i.MX8M Plus | 四核A53 1.6GHz | 2.3T | 双千兆/多UART | 支持 | Yocto学习曲线陡 | BSP定制难度高,价格偏贵 |
| 全志T507 | 四核A53 1.5GHz | 无 | 双千兆/多UART | 支持 | 一般 | 没有NPU,视觉检测没法本地做 |
| STM32MP157 | 双核A7 650MHz | 无 | 接口较少 | 支持 | 较好 | 性能太弱 |
| RK3588J | 四核A76+四核A55 | 6T | 全部拉满 | 支持 | 较高 | 算力溢出,成本高出一大截 |
另一个容易被忽略的点是SDK完整度。瑞芯微的BSP虽然不算完美,但网上案例多,遇到问题搜得到答案。i.MX8M Plus的Yocto环境相当劝退,一个meta-layer的依赖问题就够折腾一周。全志的T507资料相对封闭,出问题只能找原厂FAE。RK3568胜在社区活跃、第三方核心板厂商多、文档相对开放,对中小团队来说,这本身就是巨大的成本节省。
1.3 选型时的三条经验
第一,不要只盯芯片本身,要盯核心板生态。同一个RK3568,核心板厂商的硬件设计水平差距很大,BSP的维护质量、资料齐备程度、甚至售后响应速度,都会直接影响项目进度。我们后来选了国内一家专注工业核心板的厂商,BSP做得相当规范,这也为后面省了不少事。
第二,算力需求要留余量但不要盲目上探。很多团队看到RK3588就觉得“一步到位”,但散热、功耗、布局面积全部要跟着变,成本翻倍。边缘网关这种设备,往往部署在配电箱、路边机柜这种散热条件很差的地方,RK3568的功耗大概在3W到5W左右,被动散热就能压住,这是比算力更宝贵的优势。
第三,物流料的供货周期和生命周期必须提前确认。RK3568上市时间比较久了,属于瑞芯微的常青树型号,但“久”也意味着可能过几年进入生命周期末期。如果你做的是生命周期很长的工业设备,下单前建议和代理确认一下当前批次和未来供货计划。这一条没法写在芯片datasheet里,只能靠和渠道的沟通。
2. 我踩过的5个坑,每个都值得单独写一篇
2.1 坑一:设备树“一抓一大把”,到底该选哪棵?
RK3568的SDK里,设备树文件的数量多到让人头皮发麻。随便打开一个官方SDK,kernel/arch/arm64/boot/dts/rockchip/下面就是几十个dts文件:rk3568-evb1-ddr4-v10.dts、rk3568-evb2-lp4x-v10.dts、rk3568-nas.dts、rk3568-pc.dts,甚至还有一个专门给OpenHarmony用的设备树目录。很多新手第一反应是“选一个名字里带evb的就行”,然后编译烧录,结果启动一半就panic了。
我当时犯的错误是直接拿主线的rk3568-evb2.dts来用,因为我们开发板是LPDDR4的配置,觉得EVB2应该没错。但核心板厂商给我的BSP是基于另一个基线做的,里面改了很多外设引脚定义和PMIC配置。用官方EVB的dts去驱动厂商的核心板,本质上等于用A板的配置文件去跑B板的硬件,出问题的概率极高。
排查过程很痛苦。启动日志打印到“Synchronous Abort”或者“Unable to handle kernel paging request at virtual address”,第一反应总是怀疑内核配置有问题,反复编了五六次内核,最后才意识到是设备树选错。后来我总结了一个判断方法:看启动日志开头的机器型号。RK3568的dts里都有一个model字段,比如“Rockchip RK3568 EVB2 LP4X V10 Board”,如果你板子的实际型号和这个字符串对不上,比如硬件PCB丝印写的是V1.2,而model写的是V10,那就是dts拿错了。
正确的做法:以核心板厂商提供的SDK为准,不要自己从主线或者别的地方随便拉设备树。如果厂商给的BSP里没有完全匹配你底板外设的dts,需要自己改dts,改的时候一定要对照原理图逐项核对:DDR类型、PMIC型号、以太网PHY型号及地址、串口引脚、CAN引脚、GPIO扩展芯片I2C地址等。
关于OpenHarmony那套设备树,我单独提醒一句:OpenHarmony在RK3568上有自己专门适配的kernel和设备树,路径、节点命名、config和Linux SDK的差异很大。如果你想在OpenHarmony上跑标准Linux,或者反过来把OpenHarmony的dts拿来给Linux SDK用,基本上是不可行的。网上不少帖子说“OpenHarmony的rk3568设备树好多”,我看到不少人的困惑就是在这里。别混用,除非你真的很清楚每一步在改什么。
2.2 坑二:eth0_refclko_25m,以太网PHY时钟方向别搞反
这个坑非常隐蔽,症状表现为网口“插入网线不识别”或者“偶尔识别,但数据传输一多就丢包”。搜日志的时候会看到dmesg里提示gmac的clk相关报错,也会在很多技术社区看到类似的提问,关键词就是eth0_refclko_25m。
RK3568的GMAC接口,硬件设计上有两种常见接法:一种是PHY自己带25MHz晶振,MAC只接收PHY提供的参考时钟;另一种是28M或者25M的参考时钟由SoC的GMAC引脚直接输出给PHY,也就是refclko这个信号。对应的设备树配置是&gmac0或&gmac1节点里的clock_in_out字段,这个字段只有两个选择:“input”或者“output”。
我遇到的情况是,核心板参考设计里PHY的时钟是由RK3568的MAC输出的,但BSP里默认的dts配置写的是“input”。结果就是MAC一直在等PHY给它时钟,PHY也在等MAC发时钟过来,两个设备互相“谦让”,谁也没动,网卡自然link不上。
这个问题的排查思路是这样的:先ifconfig eth0 up,然后ethtool eth0看link状态,如果一直是no,用示波器量PHY的XI/XO引脚或者REF_CLK引脚,看有没有25MHz或50MHz的波形。没有波形,大概率就是时钟方向配置反了。此时打开dts,找到对应的gmac节点,把clock_in_out改成与实际硬件一致的值,重新编译内核(或者如果uboot里也有gmac初始化,需要同步检查)。
改完dts后还要注意另一个隐藏问题:RGMII接口的TX delay和RX delay。RK3568的dts里通常会有一组像rgmii_rx_delay、rgmii_tx_delay这样的延时配置,范围是0到15或0到30(取决于驱动解析)。这个延时调得不对,现象就是link起来了,但一直ping不通,或者ping的时候丢包率极高。需要根据PHY型号和PCB走线长度一点一点试,我最终是把tx_delay设成0x30、rx_delay设成0x20才稳定的。这块没法直接抄参考设计,必须结合自己板子的实际情况来。
2.3 坑三:NFS挂载rootfs看似简单,卡住你三天的那种
开发初期,最烦的事情就是反复烧写eMMC。改一个内核配置就要重新烧一次,一次几分钟,一天下来一半时间在等烧录。所以我很早就计划用NFS挂载rootfs,让内核起来以后直接从服务器加载文件系统。
听起来很简单:uboot设置root=/dev/nfs nfsroot=192.168.x.x:/opt/nfs rw ip=dhcp,然后重启。实际上我在这一步卡了整整三天。
第一个问题是内核rootfs挂载路径报错“VFS: Unable to mount root fs via NFS”。出现这个,最大的原因是内核配置里根本没开NFS挂载rootfs的支持。很多SDK默认配置只开启了initramfs启动,没有开CONFIG_ROOT_NFS。你需要在内核配置里确认以下选项全部为y:
- CONFIG_ROOT_NFS=y
- CONFIG_NFS_V3=y
- CONFIG_NFS_V3_ACL=y
- CONFIG_IP_PNP=y
- CONFIG_IP_PNP_DHCP=y
- CONFIG_IP_PNP_BOOTP=y
还必须确认gmac和PHY驱动是直接编进内核(=y),而不是编译成模块(=m)。内核在挂载rootfs的时候,网卡驱动必须已经就绪,它可不会帮你modprobe。
第二个问题是NFS server的exports配置。Ubuntu默认的/etc/exports如果只写了一个目录,没有加no_root_squash,NFS客户端以root身份读写时,服务器会把它映射成nobody,文件权限就全乱了。我当时看到的症状是文件系统挂上了,systemd启动到一半,各种“Permission denied”报错刷屏,根本没法进系统。最终配置是:
/opt/nfs/rootfs *(rw,sync,no_root_squash,no_subtree_check,insecure)配完之后还要sudo exportfs -r让配置生效。
第三个问题是最坑的:RK3568的官方SDK在默认编译时,会生成一个initrd或initramfs。uboot启动时会优先加载这个ramdisk,导致你命令行里写的root=/dev/nfs根本不会生效,系统会从ramdisk启动到一个小根文件系统,看起来像卡住了,实际上是被initramfs接管了。解决办法是在uboot的环境变量里增加一个跳过initramfs的设置,或者在SDK配置里把initramfs支持关掉。在uboot里我用的方案是:
setenv bootargs 'root=/dev/nfs nfsroot=192.168.1.10:/opt/nfs/rootfs rw ip=192.168.1.20:192.168.1.10:192.168.1.1:255.255.255.0::eth0:off'同时要确保bootcmd里没有把ramdisk地址传进去。
这些配置都打通之后,NFS调试是真香。改文件系统内容、拷贝新编译的模块,几秒钟就能生效,省下的时间足够把之前踩坑的损失补回来。如果有条件,我建议直接在开发阶段把NFS和TFTP一起配好,内核用TFTP下载、rootfs用NFS挂载,整个编译-调试循环能控制在几十秒内。
2.4 坑四:OV5695摄像头,从i2cdetect到出图的过程
项目里有一个版本需要做视觉检测,选了OV5695这颗500万像素的MIPI传感器。RK平台对这颗sensor有现成的驱动,理论上应该很容易。实际上,从硬件上电到Linux出图,我经历了“i2cdetect检测不到”到“能检测但不出图”两个阶段。
先说第一个阶段。上电后直接在板子上跑i2cdetect -y -r 3,发现0x36地址(OV5695的SCCB地址)没有设备。按照优先级排查:
第一,查供电。OV5695需要三路电压:AVDD 2.8V、DOVDD 1.8V、DVDD 1.2V。核心板转接板上如果有一路电压没输出,传感器就是死的。用万用表量一下最直接。
第二,查MCLK主时钟。OV5695模组通常需要24MHz的xvclk。在RK3568的dts里,这个时钟源来自cru的CLK_CAM0_OUT,对应的pinctrl节点也必须配置好。我遇到的情况是MCLK引脚被复用成了GPIO,导致clock没有输出。示波器一量,锁相环那里完全没有波形,问题一目了然。
第三,查reset和powerdown引脚。OV5695模组通常有PWDN和RESET,两个引脚默认状态必须正确,否则传感器一直处于关断或复位状态。RK3568的dts里一般会把这两个引脚配成GPIO控制。如果引脚复用冲突,比如某路GPIO被别的外设占用了,传感器就永远上不了电。
过了检测关,进入第二个阶段:i2cdetect能看到0x36设备了,但是v4l2-ctl --list-devices里看不到任何video节点,或者有节点但抓图全是黑的。
这个问题的根源通常在设备树里camera节点和ISP管线的连接关系没有配好。RK3568的MIPI CSI链路是sensor -> csi2_dphy -> rkcif -> rkisp,每个环节都需要在dts里使能并建立endpoint连接。我的dts里sensor节点写好了,但csi2_dphy0和rkcif_mmu这些节点没有正确引用sensor的port,导致驱动probe时找不到实体。
一个可以用的参考片段(具体要看你的SDK版本):
&i2c3 { status = "okay"; clock-frequency = <400000>; ov5695: ov5695@36 { compatible = "ovti,ov5695"; reg = <0x36>; pinctrl-names = "default"; pinctrl-0 = <&ov5695_mclk>; clocks = <&cru CLK_CAM0_OUT>; clock-names = "xvclk"; assigned-clocks = <&cru CLK_CAM0_OUT>; assigned-clock-rates = <24000000>; rockchip,camera-module-name = "NC22"; rockchip,camera-module-lens-name = "default"; rockchip,camera-module-index = <0>; rockchip,camera-module-facing = "back"; port { ov5695_out: endpoint { remote-endpoint = <&csi2_dphy0_input>; >