新闻详情

新闻详情

首页 / 资讯中心 / 详情

RK3588交叉编译入门:从hello程序打通YOLOv5s部署链路

发布时间:2026/9/28 1:19:42来源:尧图网络
RK3588交叉编译入门:从hello程序打通YOLOv5s部署链路
如果你跟我一样手里是一块香橙派5用的是RK3588这颗芯片刷好Ubuntu之后第一感觉是“板子性能还行”但一旦准备进入YOLOv5s部署阶段——把训练好的模型转成rknn再写C或者Python推理程序——板载编译会让你憋屈到怀疑人生。RK3588是8核听起来不差可编译大一点的项目CPU直接拉满风扇呼呼转内存也吃紧。这时候交叉编译就变成了躲不开的基本功。这篇是系列教程的第六篇目标很纯粹在你的X86电脑上用交叉编译工具链编译一个hello程序然后把这个ARM架构的可执行文件放到香橙派RK3588上运行。hello虽小但“编译→传输→运行”这条链路跟后面编译YOLOv5s的C推理代码完全一致。我把话放这儿看懂这一篇后面瑞芯微官方SDK里的CMake工具链脚本、rknn_model_zoo里的交叉编译示例你都不会觉得陌生。1. 为什么RK3588跑YOLOv5s必须搞懂交叉编译1.1 架构不同导致“不能直接跑”先解决一个最基础的问题明明都是Linux为什么不能把PC上编译好的程序直接拷到板子上跑因为CPU指令集不通用。PC上的主流CPU是x86_64香橙派RK3588是ARMv8-A架构的64位核心两者的机器码互不相识。程序编译出来以后是机器码机器码就是一套CPU能执行的“外语”x86的“英语”和ARM的“中文”不能互相替代。你在PC上用gcc编译的hello拷到板子上执行时内核会直接拒绝常见的报错是cannot execute binary file: Exec format error这个现象本质上不是文件权限问题而是文件里的机器码跟当前CPU架构不匹配。交叉编译说白了就是使用目标平台ARM的编译器在主机平台x86上产出ARM能直接执行的机器码。这个过程跟跨平台开发的其他环节无关唯一要解决的就是“让编译器生成对架构的机器码”。1.2 交叉编译在YOLOv5s部署链路中的位置你可能觉得奇怪前面教程里我们已经在香橙派上装好了Python和PyTorch环境直接把yolov5s.pt拿去推理也能跑通为什么非要折腾交叉编译因为部署的终点通常不是Python脚本。YOLOv5s要真正利用RK3588自带的NPU加速一般要用rknn-toolkit2把模型转换成.rknn格式然后通过librknnrt.so提供的API在C/C程序里做推理。你当然可以在板子上直接用gcc编译这个C程序但问题在于RK3588板载编译中等规模项目速度远不如PC尤其是OpenCV这种庞然大物。瑞芯微提供的很多SDK、预编译库默认面向交叉编译工具链直接在板子上编译反而容易遇到头文件不匹配。交叉编译可以在PC上统一管理源码、依赖库和构建脚本后期做自动化构建更方便。因此在第四章之前我们必须把“PC交叉编译→产物拷到板子→板子执行”这条链路打通。hello就是这条链路最短的回路测试不涉及任何第三方库却能暴露工具链、动态链接、权限、SSH传输等几乎所有常见问题。1.3 板载编译 vs 交叉编译怎么选方式优点缺点板载编译工具链和系统完全匹配依赖库直接可用适合小项目快速验证编译耗时吃内存长期使用容易污染系统环境交叉编译速度快资源充足构建环境干净适合复杂项目和持续集成需要自己管理头文件与依赖库工具链版本不匹配时坑很多我给新手的建议很简单如果是几十行的小程序直接在板子上编译也不是不行但既然目标是YOLOv5s部署那就趁早切换到交叉编译的工作流。早切早适应。2. 环境准备与交叉编译工具链选型2.1 准备一台Ubuntu主机并安装aarch64交叉编译器交叉编译不挑宿主机操作系统但我仍然推荐你用Ubuntu 20.04或22.04的x86_64桌面版或者服务器版。原因很功利后面YOLOv5s相关的大部分工具、脚本、预编译库都优先照顾Ubuntu遇到问题也最容易搜到答案。最省事的安装方式是直接用apt安装ARM交叉编译器sudo apt update sudo apt install -y gcc-aarch64-linux-gnu g-aarch64-linux-gnu安装完成后终端里会出现一系列以aarch64-linux-gnu-开头的命令aarch64-linux-gnu-gcc aarch64-linux-gnu-g aarch64-linux-gnu-ld aarch64-linux-gnu-readelf aarch64-linux-gnu-strip这一串前缀隐含了关键信息目标CPU架构是aarch64目标操作系统是Linux使用的是GNU工具链。只要看到这些命令能正常执行工具链就算装好了。2.2 确定目标架构RK3588是aarch64交叉编译的第一步是搞清楚目标平台到底是什么架构、什么系统。在香橙派板子上执行uname -m如果是aarch64说明板子上运行的是64位ARM Linux。香橙派5默认的Ubuntu镜像基本都走arm64路线所以我们的交叉编译目标就是aarch64。如果你拿到一块很老的小板子输出是armv7l那就要改用arm-linux-gnueabihf这个工具链。这里“gnueabihf”表示使用glibc和硬件浮点ABI。RK3588的A76/A55核心支持完整的64位指令集不存在这种纠结直接用aarch64即可。还需要注意一点目标系统的用户态库要跟工具链匹配。我们这里用的aarch64-linux-gnu是glibc工具链而香橙派Ubuntu镜像也是glibc的两者可以配合。如果板子上跑的是精简的musl系统再拿glibc编译出来的程序去跑就有可能出现库缺失的问题。2.3 用空程序验证工具链这一步只花三十秒装完工具链不要急着写业务代码先做一个最简单的空程序验证echo int main(){return 0;} | aarch64-linux-gnu-gcc -x c - -o /tmp/test_arm file /tmp/test_arm如果输出里有ELF 64-bit LSB executable, ARM aarch64说明编译器、汇编器、链接器这条链路是通的。这个验证看起来不起眼却能帮你把“工具链装坏了”这类问题从后续所有故障中提前排除掉。如果你后面要编译C项目记得确认g-aarch64-linux-gnu也安装成功aarch64-linux-gnu-g --version2.4 使用厂商SDK工具链的补充说明瑞芯微官方SDK里通常也会带一套预编译好的交叉编译器路径类似rk3588-sdk/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin使用方式是把bin目录加入PATHexport PATH/path/to/gcc-arm-10.3/bin:$PATH这套工具链的版本通常比较新rknn_model_zoo里的交叉编译脚本默认会去它指定的路径找编译器。我的建议是先别折腾厂商工具链用apt装好的版本把hello跑通等真正编译YOLOv5s RKNN C程序时再对照官方脚本决定要不要切换。因为hello阶段的核心是理解流程不是纠结某一个编译器版本。3. 手把手编写hello并进行交叉编译3.1 创建项目目录并编写hello.c在电脑上随便找个地方建目录我习惯把所有RK3588相关工程放在统一目录下mkdir -p ~/rk3588-cross/hello cd ~/rk3588-cross/hello创建hello.c#include stdio.h int main(void) { printf(Hello, RK3588! I am compiled by aarch64-linux-gnu-gcc.\n); return 0; }这里没有任何特殊技巧但有一个实用建议文件名、目录名都不要出现中文和空格。交叉编译过程中会涉及Makefile、脚本、SCP传输一旦路径里有空格各种转义问题会让你怀疑人生。养成用短横线或下划线的习惯。3.2 本地编译与交叉编译的产物差异先看本地编译gcc hello.c -o hello_x86 file hello_x86大概率输出ELF 64-bit LSB pie executable, x86-64再看交叉编译aarch64-linux-gnu-gcc hello.c -o hello_arm file hello_arm输出ELF 64-bit LSB pie executable, ARM aarch64看到没有同一个hello.c同样的基本编译命令只是编译器前缀不同产出的可执行文件架构就完全不同。这就是交叉编译最直观的体现。如果想再挖深一点可以用readelf查看ELF头部信息readelf -h hello_arm | grep -E Class|Machine|Type你会看到Machine一栏写着AArch64。这些信息在排错时非常有用因为很多“拷过去跑不了”的问题根源就是编译产物架构不对。3.3 交叉编译中的链接过程与readelf很多人只知道“编译”不知道“链接”。一个C程序从源码到可执行文件实际经历预处理、编译、汇编、链接四个阶段。前三个阶段把源码变成目标文件.o链接阶段负责把目标文件和C运行库链接到一起生成最终的可执行文件。交叉编译时链接器同样必须是支持ARM的链接器。apt安装的binutils-aarch64-linux-gnu会提供aarch64-linux-gnu-ld。默认链接的动态可执行文件其ELF头里会写死一个“程序解释器”路径作用就是告诉内核启动这个文件时先加载哪个动态链接器。aarch64-linux-gnu-readelf -l hello_arm | grep interpreter常见输出[Requesting program interpreter: /lib/ld-linux-aarch64.so.1]之所有要强调这个是因为后面你编译更复杂的程序时经常遇到这类问题明明库都在板子上但程序就是起不来检查一下interpreter路径和动态库依赖往往比无头绪地重装环境高效得多。3.4 把hello_arm拷贝到香橙派RK3588并运行这一步开始涉及板子和电脑的通信。先确保两块设备在同一局域网板子SSH服务正常。在板子上查看IPip a假设IP是192.168.1.100用户名是orangepi。在电脑上执行scp hello_arm orangepi192.168.1.100:~/输入板子密码文件就会出现在板子的用户目录下。如果你不想用scp用U盘拷贝也行但注意FAT32/exFAT格式识别更稳。接下来在板子上操作chmod x ~/hello_arm ./hello_arm看到Hello, RK3588! I am compiled by aarch64-linux-gnu-gcc.恭喜交叉编译的完整闭环已经打通。你可以把hello_arm删掉再传一次刻意试试不chmod会怎样顺便体验一下Permission denied报错。多踩一次坑印象深一次。4. 进阶动态链接、静态编译与部署思路4.1 为什么有时报No such file or directory这是交叉编译新手最常遇到的诡异问题文件明明在权限也对执行却提示No such file or directory。原因往往不在于文件自身不存在而在于动态链接器或动态库不存在。比如hello_arm的interpreter是/lib/ld-linux-aarch64.so.1内核加载这个文件时会先去找这个链接器。如果板子的文件系统被裁剪过或者路径不对就会报这个错。你可以用下面的命令查看hello_arm依赖了哪些动态库aarch64-linux-gnu-readelf -d hello_arm | grep NEEDED输出可能只有0x0000000000000001 (NEEDED) Shared library: [libc.so.6]这说明程序运行时需要libc.so.6。正常Ubuntu系统里都有但版本如果差太多或系统是纯静态文件系统一样会出问题。4.2 用-static避开动态库依赖如果你只想快速验证或者目标板子的文件系统不完整可以采用静态编译aarch64-linux-gnu-gcc hello.c -o hello_arm_static -static file hello_arm_static这回你会看到ELF 64-bit LSB executable, ARM aarch64, statically linked静态编译会把libc直接打包装进可执行文件不再依赖板子上的动态库。代价是文件体积从十几KB暴涨到接近1MB。hello无所谓但YOLOv5s项目如果全静态编译会有两个麻烦OpenCV、RKNN Runtime这类库的静态版本很难凑齐而且体积巨大。很多闭源库只提供动态库你没法静态链接。所以我的定位很明确-static是排查环境问题的工具不是部署方案。遇到动态库缺失优先检查板子系统有没有补齐库而不是十个程序全部静态编译。4.3 动态库思路才是YOLOv5s部署的主流后面真正做YOLOv5s部署时C推理程序一般要动态链接librknnrt.so、OpenCV等库。在PC上交叉编译这类程序需要让链接器能找到这些库的头文件和.so文件常见有两种做法使用--sysroot/路径/到/根文件系统让编译器以某个仿真根目录为参考去寻找头文件和库。在项目里通过-I指定头文件路径通过-L指定库路径再配合-l指定库名。rknn_model_zoo官方仓库中的交叉编译脚本就是围绕这几种方式展开的。你如果现在能理解动态链接的基本原理看那些cmake脚本就会顺畅很多。否则很容易陷入“照着复制却不知道在配什么”的状态。4.4 用带参数的hello模拟YOLOv5s命令行调用为了更贴近后续的实际场景可以把hello扩展成支持命令行参数的版本#include stdio.h int main(int argc, char **argv) { printf(argc %d\n, argc); for (int i 0; i argc; i) { printf(argv[%d] %s\n, i, argv[i]); } return 0; }交叉编译后传到板子上运行./hello_args --model yolov5s.rknn --image test.jpg程序会原样打印出参数。这块板子上的基础IO、参数传递、printf输出都验证过了后面YOLOv5s推理程序接收--model、--image这类参数时底层逻辑一模一样。只是把printf换成了各种推理API调用。5. 常见问题与排错实战5.1 问题速查表下面这张表覆盖了我见过的大部分交叉编译hello相关的问题现象原因解决办法cannot execute binary file: Exec format error编译产物架构不对比如编译成x86或ARM 32位用aarch64-linux-gnu-gcc重新编译再用file确认No such file or directory动态链接器或动态库不存在readelf查看interpreter补齐库或临时用-staticPermission denied文件没有可执行权限chmod x运行后Segmentation fault动态库版本不匹配或源码本身有内存问题检查库依赖用ldd/readelf对比版本printf中文乱码终端编码或locale问题先用纯英文输出确认链路后再处理编码新手最容易被第二个问题卡住一定要记住No such file or directory不代表文件不存在大多数时候是动态链接器或库缺失。5.2 file、readelf、ldd三板斧排错不要靠猜三板斧就能解决八成问题。第一步file查看文件架构file hello_arm看是不是ARM aarch64。不是架构问题继续往链接层排查。第二步readelf查看动态信息aarch64-linux-gnu-readelf -d hello_arm aarch64-linux-gnu-readelf -l hello_arm重点关注NEEDED和program interpreter字段。第三步在板子上用ldd查看运行时依赖ldd hello_arm如果在PC上直接运行ldd hello_arm往往会提示not a dynamic executable因为主机无法解释ARM格式。所以ldd要在板子上执行或者用aarch64-linux-gnu-readelf代替。三板斧走完很少有libc这种问题还能藏住。5.3 让构建过程脚本化跑通hello之后建议顺手做一个构建脚本后面会越来越香。我习惯用build.sh#!/bin/bash set -e CROSS_COMPILEaarch64-linux-gnu- ${CROSS_COMPILE}gcc hello.c -o hello_arm file hello_arm以后每次改动源码跑一下脚本就能重新构建。这个习惯延续到YOLOv5s项目里就是CMake里配置交叉编译工具链set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g)到了那种阶段你再回头看这个hello脚本就会明白它存在的意义让你提前把工具链、编译、传输这些前置动作全部熟练而不是等到模型转换成功之后才开始手忙脚乱学交叉编译。6. 下一步从hello到YOLOv5s RKNN推理hello这篇的内容到这里已经足够支撑你往后走。抛开具体命令我认为这课真正留下的方法论是每次只增加一个变量。刚接触RK3588和YOLOv5s部署时不要一上来就追求“在PC上编译出完整推理程序”。先在板子上跑通一个hello再跑通一个依赖libc标准库的带参程序然后再慢慢引入OpenCV、RKNN Runtime这些变量。每步只引入一个新问题出故障你能立刻定位到具体层。我自己的习惯是把所有交叉编译相关的东西收拢到一个固定目录比如~/rk3588-cross工具链说明、源码、build脚本、还有交叉编译好的库全放一起。后续项目多了这套目录就是你自己的知识库。下一步我会在这个系列里继续写YOLOv5s模型转换以及如何用同样的交叉编译工具链编译一个基于RKNN C API的推理程序。那部分涉及的库依赖和编译参数会比hello复杂不少但底层思路就是你在这一篇里已经跑通的这套东西。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

LSTM外汇预测实战:USDJPY分钟级数据从数据管线到滚动回测 2026/9/28 2:07:56

LSTM外汇预测实战:USDJPY分钟级数据从数据管线到滚动回测

简介:这份资源是一套基于LSTM网络的外汇预测模型Python实现,面向计算机相关专业学生、教师及企业员工,可用于深度学习与时间序列分析的学习实践,也可作为课程设计、毕业设计或作业的参考方案。压缩包共31个文件,约13.4…

阅读更多 →
基于YOLOv8的芒果实例分割实战:453张训练图从数据到部署 2026/9/28 2:07:56

基于YOLOv8的芒果实例分割实战:453张训练图从数据到部署

简介:这是一份面向深度学习与计算机视觉方向的芒果实例分割数据集,采用YOLOv8标注格式,可直接用于YOLOv8的实例分割训练与验证,适合从事目标检测、实例分割研究的学生、算法工程师及农业智能化应用开发者。资源包共1088个文件&…

阅读更多 →
跨时钟域设计必修课:组合逻辑毛刺与CDC同步器的正确用法 2026/9/28 2:07:56

跨时钟域设计必修课:组合逻辑毛刺与CDC同步器的正确用法

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

阅读更多 →
台达E3伺服脉冲控制5大参数陷阱与实战避坑指南 2026/9/28 2:07:56

台达E3伺服脉冲控制5大参数陷阱与实战避坑指南

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

阅读更多 →
芒果实例分割数据集YOLOv8实战:544张图从训练到部署 2026/9/28 2:07:55

芒果实例分割数据集YOLOv8实战:544张图从训练到部署

简介:这是一份面向深度学习与计算机视觉方向的芒果实例分割数据集,采用YOLOv8标注格式,可直接用于YOLOv8的实例分割训练与验证。资源包含453条训练数据与91条验证数据,覆盖精准农业、自动化采摘、质量分级、病虫害检测及储运监控等…

阅读更多 →
2026最新找人做网站需要什么?搞懂域名服务器不踩坑 2026/9/28 2:07:49

2026最新找人做网站需要什么?搞懂域名服务器不踩坑

2026最新找人做网站需要什么?搞懂域名服务器不踩坑 域名选错服务器配错,网站上线前就崩了一半。很多新手一上来就问“找人做网站需要什么”,其实这俩底层逻辑没理顺,后面全是坑。2026年最新的技术环境对基础设施要求更严,阿里云官方文档里关于H…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉