RK3588交叉编译实战:从hello world到YOLOv5s部署

发布时间:2026/10/5 7:07:26

RK3588交叉编译实战:从hello world到YOLOv5s部署 1. 为什么交叉编译是RK3588开发绕不开的第一道坎搞香橙派5的兄弟大概率都有过这样的经历板子上跑着Ubuntu或者Debian想编译一个最简单的C程序测试环境结果发现板子自带的gcc编译一个hello world都要等好几秒稍微大一点的工程直接卡到怀疑人生。这不是板子性能不行RK3588这颗芯片本身是8核A76A55的架构性能放在ARM开发板里算是第一梯队了问题出在存储和散热上——你插的那张TF卡或者eMMC的随机读写速度跟PC上的NVMe固态完全不是一个量级编译过程中大量的小文件读写会把IO打满CPU反而在等IO。交叉编译就是解决这个问题的核心手段。简单说就是在你的x86_64电脑上用一套专门为ARM架构准备的编译器把代码编译成能在RK3588上运行的二进制文件然后通过scp或者U盘拷到板子上执行。这样编译速度取决于你PC的性能拷贝一个几KB的hello可执行文件也就是一瞬间的事。这一节是整套教程的第六篇前面几篇应该已经带着大家把香橙派5的系统烧录、串口登录、网络配置这些基础工作做完了。现在到了真正写代码的环节我选择从hello world开始不是因为它简单而是因为它能把交叉编译的完整链路跑通——工具链安装、环境变量配置、编译参数指定、文件传输、板端执行每一步都走一遍后面编译YOLOv5s的推理程序时就不会手忙脚乱。提示交叉编译工具链的选择非常关键选错了后面全是坑。香橙派官方和Rockchip原厂都提供了工具链但版本和配置方式有差异下面会详细对比。适合阅读这篇内容的人刚拿到香橙派5、已经能正常登录系统、准备开始写C/C程序或者部署AI模型的开发者。如果你连板子还没点亮建议先回去看前面的系统烧录教程。2. 交叉编译工具链的选型与安装2.1 三种主流工具链的对比给RK3588做交叉编译市面上能用的工具链主要有三类我分别用过踩过的坑不太一样。第一类是Rockchip原厂SDK里自带的工具链通常在SDK的prebuilts/gcc/linux-x86/aarch64/目录下名字类似gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu。这套工具链跟RK3588的BSP是配套的glibc版本、内核头文件都是对齐的理论上兼容性最好。但问题是它藏在SDK里如果你没下载完整的SDK单独去搞这套工具链比较麻烦。第二类是Linaro或者ARM官方发布的GNU工具链比如gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu这个跟Rockchip用的其实是同一个版本。ARM官方每季度会更新下载方便文档齐全。我目前用的就是这个稳定性和兼容性都经过验证。第三类是香橙派官方Wiki里推荐的工具链有时候会指向一个特定的下载链接。香橙派官方文档更新频率一般链接失效是常有的事而且不同批次的板子可能预装不同的系统版本工具链的glibc版本要对上。工具链来源优点缺点推荐场景Rockchip SDK自带与BSP完全配套需要下载完整SDK体积大深度定制系统、编译内核驱动ARM官方GNU工具链下载方便、版本清晰、文档全需要自己确认glibc兼容性应用层开发、AI模型部署香橙派官方推荐官方验证过链接易失效、更新慢新手按官方教程走我的建议是如果你只是做应用层开发比如编译YOLOv5s的推理程序、写一些测试工具直接用ARM官方的GNU工具链就行。如果你要编译内核模块或者修改系统底层那必须用Rockchip SDK自带的否则内核版本对不上会出各种诡异问题。2.2 下载与解压的实操细节我以ARM官方10.3版本为例这个版本对应的是glibc 2.33香橙派5默认的Ubuntu 22.04系统glibc版本是2.35向下兼容没问题。如果你用的是Debian 11glibc是2.31那就要注意了用10.3编译出来的程序在Debian 11上可能跑不起来因为依赖的glibc版本比系统自带的还高。下载地址去ARM开发者官网找搜索“GNU Toolchain for AArch64”找到gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz这个文件。文件大概100多MB下载完先校验一下MD5避免下载过程中损坏。# 下载完成后校验 md5sum gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz # 对比官网提供的MD5值解压到一个你习惯放工具的目录我一般放在/opt/toolchain/下面sudo mkdir -p /opt/toolchain sudo tar -xvf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/toolchain/解压完检查一下目录结构确认bin目录下有aarch64-none-linux-gnu-gcc这个可执行文件ls /opt/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/你应该能看到aarch64-none-linux-gnu-gcc、aarch64-none-linux-gnu-g、aarch64-none-linux-gnu-ld这些文件。如果没有说明解压不完整重新下载。2.3 环境变量配置的两种方式配置环境变量有两种方式临时生效和永久生效。临时生效就是直接在终端里export关掉终端就没了适合测试export PATH/opt/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH永久生效要写进~/.bashrc或者/etc/profile。我推荐写进~/.bashrc只对当前用户生效不会影响系统里其他用户。在文件末尾追加echo export PATH/opt/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH ~/.bashrc source ~/.bashrc验证是否配置成功aarch64-none-linux-gnu-gcc -v如果输出了gcc的版本信息说明配置成功。如果提示command not found检查路径是不是写错了或者用绝对路径试试。注意有些教程会让你把工具链的bin目录直接加到PATH最前面这没问题但如果你系统里已经装了其他交叉编译工具链比如arm-linux-gnueabihf那PATH的顺序就很重要了。建议用which aarch64-none-linux-gnu-gcc确认一下实际调用的是哪个。3. 从hello.c到板端运行的完整实操3.1 编写一个“不那么简单”的hello程序很多人觉得hello world太简单随便写两行就行。但我要用这个程序验证的东西不少编译器能不能正常工作、标准库链接有没有问题、生成的可执行文件架构对不对、板子上能不能跑起来。所以我写的hello.c会稍微加一点东西#include stdio.h #include stdlib.h int main(int argc, char *argv[]) { printf(Hello, Orange Pi 5!\n); printf(This binary is compiled for AArch64.\n); printf(argc %d\n, argc); for (int i 0; i argc; i) { printf(argv[%d] %s\n, i, argv[i]); } return 0; }加打印参数个数和参数内容是为了验证程序在板子上运行时能正常接收命令行参数后面调试YOLOv5s的时候经常需要传模型路径、图片路径这些参数提前验证一下没坏处。3.2 编译命令的每个参数都要说清楚编译命令看起来简单但每个参数都有讲究aarch64-none-linux-gnu-gcc hello.c -o hello -static-o hello指定输出文件名这个不用多说。关键是-static这个参数我强烈建议加上。动态链接的话板子上必须有对应的动态库而且版本要匹配。你编译时用的工具链glibc是2.33板子上是2.35动态链接可能没问题但如果是反过来板子上是2.31那就会报GLIBC_2.33 not found的错误。静态链接把所有依赖都打包进可执行文件体积会大一些但省去了库版本匹配的麻烦。编译完检查一下生成的文件file hello输出应该是类似这样的hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, for GNU/Linux 3.7.0, not stripped重点看ARM aarch64和statically linked这两个信息。如果是x86-64说明你调用的还是系统自带的gcc不是交叉编译器检查PATH。如果是dynamically linked说明-static没生效检查参数拼写。还可以用readelf看一下更详细的信息aarch64-none-linux-gnu-readelf -h hello输出里的Machine字段应该是AArch64Class是ELF64。3.3 传输到板子的三种方式编译出来的hello文件要传到板子上执行有三种常用方式。第一种是scp前提是板子和电脑在同一个局域网而且板子开了SSH服务。香橙派5默认的Ubuntu镜像一般已经装了SSH如果没有在板子上执行sudo apt install openssh-server。传输命令scp hello orangepi192.168.1.100:/home/orangepi/把192.168.1.100换成你板子的实际IP。传输速度取决于网络几KB的文件基本秒传。第二种是U盘适合板子没联网或者网络配置麻烦的情况。把hello拷到U盘插到板子上挂载U盘拷贝文件。挂载命令一般是sudo mount /dev/sda1 /mnt cp /mnt/hello /home/orangepi/ sudo umount /mnt第三种是通过NFS或者TFTP适合频繁传输大量文件的场景。配置稍微麻烦一点但一次配好后面就方便了。我平时调试YOLOv5s的时候用NFS比较多因为模型文件和测试图片经常要换。3.4 板端执行与权限设置文件传到板子上之后默认是没有执行权限的直接运行会提示Permission denied。先加权限chmod x hello然后运行./hello如果一切正常你会看到Hello, Orange Pi 5! This binary is compiled for AArch64. argc 1 argv[0] ./hello再试试带参数运行./hello test 123输出里应该能看到argc 3以及argv[1] test、argv[2] 123。实操心得如果运行时报No such file or directory但文件明明存在大概率是动态链接器的问题。用file hello确认是不是动态链接如果是要么重新用-static编译要么在板子上安装对应的库。还有一种可能是文件系统挂载时带了noexec选项用mount | grep noexec检查一下。4. 交叉编译常见问题与排查实录4.1 工具链版本与系统glibc不匹配这是最常见的问题没有之一。现象是编译时没问题板子上运行时报错./hello: /lib/aarch64-linux-gnu/libc.so.6: version GLIBC_2.33 not found原因是你编译时用的工具链glibc版本高于板子系统的glibc版本。解决办法有两个一是换用更低版本的工具链比如板子是Debian 11glibc 2.31就用gcc-arm-10.2或者更早的版本二是用-static静态编译把glibc打包进去。怎么查板子的glibc版本ldd --version输出第一行就是glibc版本号。怎么查工具链的glibc版本aarch64-none-linux-gnu-gcc -print-file-namelibc.so.6 # 然后用readelf查看 aarch64-none-linux-gnu-readelf -a /path/to/libc.so.6 | grep GLIBC4.2 找不到头文件或库文件编译时报fatal error: xxx.h: No such file or directory说明工具链的sysroot里没有这个头文件。交叉编译工具链自带一套sysroot里面是标准的C库头文件但如果你用了第三方库比如OpenCV、FFmpeg就需要自己交叉编译这些库然后把头文件和库文件路径通过-I和-L参数指定给编译器。比如你交叉编译了OpenCV到/opt/opencv-arm64/编译命令要写成aarch64-none-linux-gnu-gcc hello.c -o hello -static \ -I/opt/opencv-arm64/include \ -L/opt/opencv-arm64/lib \ -lopencv_core -lopencv_imgproc注意-I和-L的顺序以及-l参数要放在源文件后面否则链接器可能找不到符号。4.3 编译出来的程序在板子上跑不起来除了glibc版本问题还有几种可能。一是架构不对用file命令确认是ARM aarch64而不是x86-64。二是文件系统权限问题用ls -l看有没有执行权限。三是板子的内核版本太低编译时指定的--sysroot或者内核头文件版本高于板子实际内核版本。排查步骤可以按这个顺序来file hello确认架构chmod x hello确认权限ldd hello查看动态库依赖如果是动态链接uname -a查看板子内核版本dmesg | tail查看内核日志有没有报错4.4 常见问题速查表现象可能原因排查命令解决方法command not foundPATH未配置which aarch64-none-linux-gnu-gcc重新配置环境变量GLIBC_2.xx not foundglibc版本不匹配ldd --version换工具链或静态编译No such file or directory动态链接器缺失file hello静态编译或安装库Permission denied无执行权限ls -l hellochmod x hellocannot execute binary file架构不对file hello检查交叉编译器PATH编译时报头文件缺失sysroot不完整find / -name xxx.h指定-I路径或交叉编译依赖库避坑技巧我习惯在编译完第一时间用file和readelf检查生成的文件确认架构和链接方式正确再传到板子上。这样能把大部分问题挡在传输之前省得来回折腾。5. 从hello到YOLOv5s交叉编译的后续扩展hello world跑通之后交叉编译的链路就算打通了。接下来编译YOLOv5s的推理程序本质上就是把hello.c换成更复杂的C代码把依赖的库从标准C库换成RKNN API和OpenCV。工具链不变编译参数增加-I和-L指定RKNN和OpenCV的路径链接参数增加-lrknn_api -lopencv_core这些。我实际编译YOLOv5s推理程序时遇到的最大问题不是编译本身而是RKNN库的版本匹配。Rockchip的RKNN Toolkit2更新比较频繁不同版本生成的rknn模型文件跟板子上的librknnrt.so版本必须对应否则加载模型时会报错。这个后面讲到模型转换和部署的时候再细说。另外如果你要编译的C程序用了C17的特性记得把编译器换成aarch64-none-linux-gnu-g并且加上-stdc17参数。链接时如果用到数学库还要加-lm。交叉编译工具链的安装路径建议记下来后面写CMakeLists.txt或者Makefile的时候要用。我一般会在项目根目录放一个toolchain.cmake文件把编译器路径、sysroot路径、编译参数都写进去这样用CMake构建的时候直接-DCMAKE_TOOLCHAIN_FILEtoolchain.cmake就行不用每次手动敲一长串参数。这个hello程序虽然简单但它验证了从x86到ARM的完整工具链。后面不管编译什么程序流程都是一样的写代码、交叉编译、传输、板端执行。把这一步走稳了后面的YOLOv5s部署就是水到渠成的事。
延伸阅读

更多相关文章

2026/10/5 7:07:26

YOLOv11并非新版本:工业动态抓取中的6D位姿估计实战

简介:本资源是一份面向工业自动化工程师、机器人视觉开发者及高校相关专业研究者的深度技术文档,聚焦YOLOv11在动态抓取场景下的目标检测与位姿估计协同优化方案。文档系统梳理了工业机器人视觉架构、YOLOv11网络结构与检测原理,并针对性提出…

2026/10/5 7:07:26

方差迭代计算公式详解:Welford算法与流式数据的数值稳定性

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 7:02:26

基于深度学习的OFDM信号检测:从仿真到实网部署全解析

简介:无线通信物理层接收机的核心任务是在接收到的IQ样本中恢复出发送的调制符号。传统OFDM接收机采用信道估计、均衡、判决的分步处理流程,在快时变或多径环境下,误差沿链路逐级放大,性能明显退化。深度学习将检测建模为端到端学…

2026/10/5 7:57:28

Nuxt 3/4 路由实现 .html 后缀的三种方案与踩坑记录

做企业官网迁改的时候,甲方那边有一套老业务系统,所有落地页 URL 必须以.html结尾,否则后端解析逻辑直接不认。当时我们正把项目从 Nuxt 3 往 Nuxt 4 升,路由后缀这个需求一来,团队里立刻分成了两派:一派说…

2026/10/5 7:57:28

C#值相等与null==null:运算符重载与Equals实现完整指南

接手这个需求之前, 我先把背景说清楚:我们在 C# 里讲"值相等"(value equality),指的是两个不同对象只要内部关键数据相同,业务上就视为同一个对象;而默认情况下类(class)的…

2026/10/5 7:57:28

TMC stealthChop步进电机静音驱动:原理到寄存器配置全解析

1. 为什么被步进电机噪音烦了这么久,才遇到stealthChop玩步进电机的人应该都有过这种经历:3D打印机一开机,整个房间都是蜂鸣一样的“滋滋”声;CNC雕刻机走直线时,高频啸叫让人戴耳机都嫌吵;做个相机滑轨&am…

2026/10/5 7:57:28

TMC stealthChop步进电机静音驱动原理与STM32配置实战

用过步进电机驱动的朋友应该都有那个瞬间:把板子上的A4988或者DRV8825拆下来,换上TMC2209,通电,电机从那种尖锐的“嘶嘶”声变成几乎只有转子转动的机械声。再开stealthChop,连那点机械声都像是被蒙了一层棉被。这个从…

2026/10/5 7:57:28

26年论文AI率太高实测报告:功能、效果与短板

论文AI率太高,成了这届毕业生躲不过的坎。学校查重系统升级后,AI检测结果直接和答辩资格挂钩,身边好几个同学初稿提交后被判定AI率超40%,被迫连夜返工。市面上号称能降AI的工具不少,但效果参差不齐。我花了两周时间&am…

2026/10/5 7:52:28

MySQL索引失效全解析:8种场景与排查实战

直接开始聊聊索引失效这件事。做后端开发的,就没有不被索引失效坑过的。明明查询走了索引,结果一夜之间接口变慢,或者你可能都不知道那条慢SQL压根儿没用上索引——等DBA找上门的时候,数据量已经涨到几千万,再想改&…

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑