从做工业项目到现在,我前后接触过不少嵌入式开发板。早期用单片机做数据采集,后来逐步过渡到带 Linux 系统的应用处理器平台,最近在智能工控方案选型时,把 RK3572 开发板作为主控评估了一圈。这篇文章就结合我自己的评估和实操经验,围绕 RK3572 开发板展开,聊聊它在智能工控场景里的定位、交叉编译环境的搭建,以及如何把 Qt 程序部署到板子上运行。过程会涉及环境准备、系统烧录、网络配置和常见坑点,适合准备入门嵌入式 Linux 开发,或者正在做工控项目选型的开发者参考。
1. 为什么智能工控需要 RK3572 这类开发板
1.1 传统工控方案的痛点
传统工控现场最常见的是“PLC + 触摸屏 + 传感器”组合。PLC 稳定可靠,擅长逻辑控制和时序控制,但面对图像识别、AI 推理、复杂协议解析、远程可视化监控这类需求时,就会显得力不从心。因为 PLC 的算力有限,生态相对封闭,扩展 HMI 虽然能解决显示问题,但要实现边缘计算、数据上云、算法联动,往往需要额外增加一台工控机,成本和功耗都会上涨。
另一个痛点是开发效率。传统单片机方案资源受限,跑不了复杂的应用框架,很多业务逻辑要自己从头写,通信协议、文件系统、网络栈都要一点点去啃。对于智能产线、能源管理、环保监测这类场景,项目交付周期往往很紧,如果底层基础能力都要重复造轮子,效率就很难提上去。
1.2 RK3572 开发板在智能工控里的定位
RK3572 属于瑞芯微 RK35 系列,定位是面向 AIoT 和智能工控场景的应用处理器。它相比传统 MCU 最大的区别是能够运行完整的 Linux 系统,这意味着你可以直接使用标准的网络协议栈、文件系统、数据库、Python/C++ 应用框架,以及各类工业通信库。
我把 RK3572 开发板在智能工控里的角色简单梳理了一下:
- 边缘计算节点:承担数据采集、协议转换、本地逻辑判断,把处理结果上传到云端或上级系统。
- HMI 人机交互终端:通过 HDMI 或 LVDS 接口连接显示屏,运行 Qt 应用,替代传统触摸屏。
- 工业网关:利用多网口和串口资源,把 Modbus RTU、Modbus TCP、CAN、串口设备统一接入,完成协议转换。
- 视觉检测设备:借助 GPU 和 NPU 能力,在本地完成图像预处理、简单分类或缺陷检测。
相对传统工控机,开发板方案的功耗更低,体积更小,成本也更可控;相对单片机方案,性能和生态优势非常明显。所以在中等复杂度的智能工控项目里,RK3572 这类平台是一个很合适的平衡点。
1.3 开发板与单片机的区别
很多刚接触嵌入式的开发者会把“开发板”和“单片机”混为一谈。简单来说,单片机是芯片级别的控制器,开发板则是围绕某颗处理器做出来的完整硬件平台,包括内存、存储、电源管理、接口、连接器等。RK3572 开发板本身就相当于一台小电脑,用户可以给它烧录 Linux 系统,像操作服务器一样进行开发和部署。
单片机擅长的是实时性要求极高的简单控制任务,开发板适合跑 Linux 这样的复杂系统。二者不是替代关系,而是互补关系。在很多智能工控设备里,主控是 RK3572 开发板,底层还有几颗 MCU 负责电机控制、温度采集等实时任务,两者通过串口或 SPI 通信。理解了这个区别,选型时就不会走弯路。
2. 环境准备:硬件与主机开发环境
2.1 开发板硬件清单
在开始之前,建议先把开发板相关硬件准备齐全。不同厂家提供的 RK3572 开发板接口会有差异,但下面的清单基本通用:
| 设备 | 用途 | 说明 |
|---|---|---|
| RK3572 开发板 | 主控硬件 | 建议配套官方散热片或风扇 |
| USB Type-C 数据线 | 烧录镜像、ADB 调试、串口调试 | 部分开发板使用 USB 转串口线 |
| 12V/2A 或 5V/3A 电源适配器 | 供电 | 具体规格以开发板丝印或说明书为准 |
| microSD 卡 / eMMC 烧录工具 | 存放系统镜像 | 如果从 SD 卡启动,建议使用 Class 10 以上标准 |
| HDMI 显示器 | 查看图形界面 | 用于 Qt 界面调试 |
| 网线 | 连接路由器或交换机 | 用于 SSH 登录和程序部署 |
如果没有显示器,纯命令行操作也是可以的,开发板通过串口或者 SSH 都能完成管理和程序部署。工控项目通常推荐使用串口和 SSH 双通道管理,方便现场排障。
2.2 主机开发环境
主机的作用是编写代码、交叉编译、制作镜像,然后把产物部署到开发板。可以选用 Ubuntu 20.04/22.04 这类 Linux 发行版,也可以使用虚拟机。需要注意,RK3572 的交叉编译工具链可以在 Ubuntu 上运行,Windows 环境一般通过 WSL 或 Docker 完成同类工作。
建议安装以下基础工具:
sudo apt update sudo apt install -y git ssh vim net-tools cmake build-essential \ libncurses5-dev libssl-dev bc flex bison libssl-dev \ qemu-user-static这里有几个工具的作用说明一下:
build-essential:提供 gcc、g++、make 等编译基础工具。cmake:很多现代 C++ 项目使用 CMake 构建。flex和bison:编译内核或部分系统组件时可能用到。qemu-user-static:用于在 x86 主机上模拟运行 ARM 程序,验证文件系统时比较方便。
主机上还需要准备 SDK 或交叉编译工具链。如果使用开发板厂商提供的 SDK 包,解压后通常已经包含工具链、内核源码、U-Boot 源码和 rootfs 构建脚本。不建议自行从零构建工具链,因为版本匹配问题会消耗大量时间。
2.3 烧录系统镜像
开发板出厂时一般会预装系统,但如果需要重新烧录,常见有两种方式:使用瑞芯微的RKDevTool烧录工具,或者写入 microSD 卡。
使用 SD 卡启动的思路如下:
- 下载官方提供的系统镜像,一般包含
update.img或分区镜像。 - 使用
dd命令将镜像写入 SD 卡。 - 把 SD 卡插入开发板,设置启动拨码开关为 SD 卡启动。
以 Linux 主机为例,写入镜像的命令大致如下:
sudo dd if=rk3572_ubuntu_fs.img of=/dev/sdX bs=4M status=progress sync注意/dev/sdX需要替换为 SD 卡实际设备节点,千万不要写错,否则可能覆盖主机硬盘数据。写入前可以用lsblk确认设备名。
烧录完成后,开发板接上电源和显示设备,正常启动后就会进入系统登录界面。首次登录可以使用默认账号,具体账号密码以开发板文档为准。
2.4 与开发板建立连接
开发板启动后,推荐优先通过串口终端登录,因为串口不依赖网络,即使网络配置有问题也能排查。连接方式:
- 使用 USB 转串口模块,连接开发板的调试串口。
- 主机使用 minicom 或 picocom 打开对应串口。
sudo picocom -b 1500000 /dev/ttyUSB0波特率根据开发板文档设置,常见的有 115200 和 1500000。如果串口终端能正常看到系统启动日志,说明系统已经正常引导。
网络连接方面,可以把开发板用网线连接到路由器,然后登录路由器后台查看开发板获取到的 IP。也可以直接在串口终端执行ip addr查看。
ip addr看到eth0上分配了 IP 之后,就可以在主机使用 SSH 登录开发板:
ssh user@192.168.1.100SSH 登录成功后,日常开发和文件传输就可以全部在远程终端完成,不需要每次都接显示器。
3. 核心概念:交叉编译与开发板部署
3.1 为什么不能直接在开发板上编译
很多第一次接触嵌入式 Linux 的开发者会问:开发板都跑 Ubuntu 系统了,为什么不能在开发板上直接执行 CMake、qmake 编译?理论上确实可以,但实际项目中基本不会这么做。原因主要有三点:
- 编译速度:开发板的 CPU 性能虽然够用,但与主流 x86 主机相比仍有差距,编译大型 Qt 工程时耗时非常明显。
- 存储空间:开发板上的存储空间通常有限,安装完整编译工具链和中间文件会占用大量空间。
- 工具链一致性:在主机交叉编译,工具链版本、依赖库、头文件都是可控的;在开发板上直接编译,依赖管理和工程复现都会麻烦一些。
正确的工作流程是:在主机上准备好交叉编译工具链,把源码编译成 ARM 架构的可执行文件或动态库,然后通过 SSH、NFS 或 USB 拷贝到开发板运行。
3.2 交叉编译工具链的工作原理
交叉编译工具链的本质是“在一种架构上编译另一种架构的程序”。例如 x86 主机使用aarch64-linux-gnu-gcc编译出 ARM64 架构的可执行文件。工具链不仅包含编译器,还包含目标系统的头文件、链接库和调试工具。
一个典型的交叉编译工具链前缀可能是:
aarch64-linux-gnu-gcc aarch64-linux-gnu-g++ aarch64-linux-gnu-objcopy aarch64-linux-gnu-strip使用方式与普通 gcc 一样,只是指令前缀不同。对于结合了 Qt 的项目,除了编译器还需要 Qt 的交叉编译库,通常由开发板的 SDK 或 openstlinux 等 BSP 提供。
查看当前编译环境的默认目标架构,可以在主机上执行:
aarch64-linux-gnu-gcc -v执行结果中会显示Target字段,如果前缀是aarch64,说明编译目标为 64 位 ARM 架构。
3.3 Qt 程序交叉编译的流程
Qt 程序在开发板上运行,需要经历以下几个阶段:
- 源码编写:在主机上编写 Qt C++/QML 代码。
- 交叉构建:使用交叉编译好的 qmake 或 CMake 工具链构建可执行文件。
- 部署第三方库:如果使用了 Qt 的模块,需要把对应的 Qt 运行库一起拷贝到开发板。
- 目标板运行:在开发板上设置
QT_QPA_PLATFORM等环境变量,启动程序。
Qt 在嵌入式 Linux 下的显示后端是linuxfb或eglfs。linuxfb通过 Linux 的 framebuffer 直接绘制;eglfs基于 OpenGL ES,适合带 GPU 的开发板。RK3572 这类平台带有 Mali GPU,优先考虑eglfs。
下面我们就用一个实际完整的 Qt 小案例,把交叉编译到开发板运行的流程走一遍。
4. 完整实战:Qt 程序交叉编译并部署到 RK3572 开发板
4.1 创建项目结构
首先在主机上创建一个简单的 Qt Widgets 工程。这个工程不需要复杂功能,只在窗体上显示一个按钮和一个标签,点击按钮后标签内容更新。这样可以测试基本的事件响应、Qt Widgets 库和显示后端是否正常工作。
项目结构如下:
rk3572_qt_demo/ ├── CMakeLists.txt # CMake 构建脚本 ├── main.cpp # 程序入口 └── mainwindow.h # 主窗口头文件 └── mainwindow.cpp # 主窗口实现如果你更习惯 qmake,后面我也会给出.pro文件的参考写法。这里先使用 CMake,因为新版 Qt 对 CMake 支持更完善,也便于在脚本里配置交叉编译工具链。
4.2 编写 Qt 程序
先写main.cpp:
#include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow w; w.show(); return app.exec(); }再写mainwindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> class QLabel; class QPushButton; class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); private slots: void onButtonClicked(); private: QLabel *m_label; QPushButton *m_button; }; #endif // MAINWINDOW_H然后是mainwindow.cpp:
#include "mainwindow.h" #include <QLabel> #include <QPushButton> #include <QVBoxLayout> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { auto *centralWidget = new QWidget(this); auto *layout = new QVBoxLayout(centralWidget); m_label = new QLabel("Hello RK3572", centralWidget); m_label->setAlignment(Qt::AlignCenter); m_button = new QPushButton("Click Me", centralWidget); layout->addWidget(m_label); layout->addWidget(m_button); centralWidget->setLayout(layout); setCentralWidget(centralWidget); setWindowTitle("RK3572 Qt Demo"); connect(m_button, &QPushButton::clicked, this, &MainWindow::onButtonClicked); } void MainWindow::onButtonClicked() { m_label->setText("Button clicked on RK3572"); }这段代码逻辑很简单:创建一个垂直布局,把标签和按钮放进去,点击按钮后修改标签文本。重点在于验证跨平台编译环境和 Qt 基础控件是否正常工作。
CMakeLists.txt内容如下:
cmake_minimum_required(VERSION 3.16) project(rk3572_qt_demo) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 REQUIRED COMPONENTS Widgets) set(SOURCES main.cpp mainwindow.cpp ) set(HEADERS mainwindow.h ) qt_add_executable(rk3572_qt_demo ${SOURCES} ${HEADERS}) target_link_libraries(rk3572_qt_demo PRIVATE Qt6::Widgets)这里使用了 Qt6 的 CMake API。如果你的开发板 SDK 提供的是 Qt5,可以将find_package(Qt6 ...)改为find_package(Qt5 ...),并把qt_add_executable换成add_executable或者安装qt5-default工具链。
4.3 使用交叉编译工具链配置 CMake
在主机上交叉编译,需要告诉 CMake 使用哪个编译器以及去哪里找目标平台的 Qt 库。下面是一份交叉编译工具链文件,实际使用时需要把路径替换成你本机 SDK 的实际路径。
创建一个名为rk3572-toolchain.cmake的文件:
set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(TOOLCHAIN_PREFIX /opt/rk3572/toolchain/bin/aarch64-linux-gnu-) set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) set(CMAKE_SYSROOT /opt/rk3572/sysroot) set(CMAKE_FIND_ROOT_PATH /opt/rk3572/sysroot) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)在这份文件里,CMAKE_SYSROOT指向目标板的根文件系统,CMAKE_FIND_ROOT_PATH让 CMake 从 sysroot 里查找依赖库,而不是从主机系统找。交叉编译时这一步很关键,否则 CMake 会找到主机上的 x86 库,导致链接失败。
如果 Qt 库安装在/opt/rk3572/sysroot/opt/Qt-6.x.x这种自定义路径,还需要在 CMake 里额外指定 Qt 的路径:
cmake -S . -B build \ -DCMAKE_TOOLCHAIN_FILE=../rk3572-toolchain.cmake \ -DCMAKE_PREFIX_PATH=/opt/rk3572/sysroot/opt/Qt-6.x.x/lib/cmake这里CMAKE_PREFIX_PATH告诉 CMake 去哪里找Qt6Config.cmake。不同 SDK 的目录结构不同,需要灵活调整。
4.4 使用 qmake 方式交叉编译(备用方案)
如果你的项目使用的还是 qmake 构建体系,也可以直接用交叉编译版的 qmake 构建:
/opt/rk3572/qt/bin/qmake rk3572_qt_demo.pro make -j$(nproc)对应的.pro文件如下:
QT += core gui widgets TARGET = rk3572_qt_demo TEMPLATE = app SOURCES += \ main.cpp \ mainwindow.cpp HEADERS += \ mainwindow.hqmake 和 CMake 选一种就行,不建议混用。新项目更推荐 CMake。
编译完成后,在build目录里会生成可执行文件rk3572_qt_demo。可以用file命令确认架构:
file build/rk3572_qt_demo预期输出里应该包含ARM aarch64字样,说明交叉编译成功。
4.5 部署到开发板运行
把编译好的可执行文件拷贝到开发板上。如果开发板已经通过 SSH 连接,可以使用scp:
scp build/rk3572_qt_demo user@192.168.1.100:/home/user/如果开发板没有联网,也可以用 U 盘或 SD 卡拷贝。
在开发板上运行之前,需要先确认两件事:
- Qt 运行库是否齐全:如果开发板系统里没有 Qt 运行库,需要在主机交叉编译一份完整的 Qt 并部署到开发板的
/usr/lib或/opt/qt目录。 - 显示环境变量是否正确:使用
eglfs后端时,需要设置QT_QPA_PLATFORM=eglfs。
在开发板上执行:
export QT_QPA_PLATFORM=eglfs ./rk3572_qt_demo如果开发板连接了 HDMI 显示器或 LCD 屏,屏幕上会出现一个窗口,点击按钮后标签文字变为 “Button clicked on RK3572”。
如果开发板没有显示设备,可以临时改用linuxfb并用QT_QPA_PLATFORM=linuxfb启动,程序不会报错,但因为没有显示设备,窗口不会显示在物理屏幕上。也可以通过 offscreen 平台做无界面测试:
export QT_QPA_PLATFORM=offscreen ./rk3572_qt_demo这种方式适合验证程序本身能否启动,不验证界面效果。
5. 智能工控常用功能配置
在 RK3572 开发板上跑通 Qt 程序只是第一步。工控项目通常还需要配置网络、串口、GPIO、开机自启等基础能力。下面把几个高频配置梳理一下。
5.1 双网口配置与第二个网口开启
很多 RK3572 开发板会引出两个千兆网口,一个用于连接工业现场设备,一个用于连接上级网络或云端。默认情况下,第二个网口可能没有启用,需要手动配置。
在开发板上使用ip命令查看当前网络接口:
ip addr如果看到eth0和eth1,说明两个网口都被识别。如果只有eth0,可以通过设备树或系统配置文件启用eth1。先不用急着改设备树,先确认驱动是否存在:
ls /sys/class/net/在 Ubuntu 系统里,可以通过 netplan 配置文件设置两个网口的静态 IP。配置文件位置一般在/etc/netplan/下,例如01-netcfg.yaml:
network: version: 2 ethernets: eth0: dhcp4: true eth1: dhcp4: false addresses: - 192.168.10.10/24修改完成后:
sudo netplan apply再次执行ip addr,就能看到eth1已经配置成功。生产环境中建议将两个网口划分在不同网段,避免工业现场广播数据影响管理网络。
5.2 开发板挂载 Ubuntu 根文件系统(NFS)
开发阶段如果频繁修改程序或系统文件,反复烧录镜像效率太低。一个很实用的方式是配置 NFS 服务,把主机上的 Ubuntu 根目录或用户目录共享给开发板挂载。
在主机上安装并配置 NFS 服务:
sudo apt install -y nfs-kernel-server编辑/etc/exports文件,添加共享目录:
/home/user/rk3572_rootfs *(rw,sync,no_root_squash,no_subtree_check)然后重启服务:
sudo exportfs -ra sudo systemctl restart nfs-kernel-server在开发板上临时挂载:
sudo mount -t nfs 192.168.1.100:/home/user/rk3572_rootfs /mnt/nfs挂载完成后,开发板上的/mnt/nfs就对应主机上的共享目录,可以直接运行主机上编译好的程序,省去反复拷贝文件的时间。不过需要注意的是,NFS 在真实工业现场一般不推荐作为长期运行依赖,它主要用于开发调试。
5.3 GPIO 与串口控制
智能工控设备经常需要控制继电器、读取传感器状态。RK3572 开发板上的 GPIO 可以通过两种方式访问:传统的 sysfs 接口(老内核)和新的 gpiod 接口(新内核)。
如果内核支持 gpiod 工具,建议使用gpioset和gpioget:
# 查看 GPIO 控制器 gpiodetect # 将 GPIO 输出高电平 gpioset gpiochip0 17=1 # 读取 GPIO 输入状态 gpioget gpiochip0 18如果是传统 sysfs 方式,则需要手动导出 GPIO,再操作value文件:
echo 17 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio17/direction echo 1 > /sys/class/gpio/gpio17/value串口操作在 Linux 下比较直接,使用/dev/ttyS*节点。如果开发板上有多个串口,不同串口可能对应不同的设备节点,需要查看设备树或开发板原理图确认。测试串口可以使用echo重定向,也可以使用 Python 的pyserial库。
一个简单的 Python 串口测试脚本:
import serial import time ser = serial.Serial('/dev/ttyS1', 115200, timeout=1) ser.write(b'hello rk3572\n') time.sleep(0.1) data = ser.readline() print(data) ser.close()需要注意的是,Qt 程序访问串口时,建议通过QSerialPort模块,避免在 GUI 线程中做阻塞读写。
5.4 开机自启服务
工控设备通常要求上电后自动运行业务程序,不需要人工登录。方案是使用 systemd 服务,把 Qt 程序配置成开机自启。
在开发板上创建一个 service 文件/etc/systemd/system/rk3572-qt.service:
[Unit] Description=RK3572 Qt Demo After=network.target [Service] Type=simple User=root Environment=DISPLAY=:0 Environment=QT_QPA_PLATFORM=eglfs ExecStart=/home/user/rk3572_qt_demo Restart=always RestartSec=3 [Install] WantedBy=multi-user.target然后启用服务:
sudo systemctl daemon-reload sudo systemctl enable rk3572-qt.service sudo systemctl start rk3572-qt.serviceRestart=always表示程序异常退出后会自动重启,这个配置对于工控设备非常重要,能提高程序层面的容错能力。
6. 常见问题与排查思路
在实际开发中,交叉编译和部署阶段最容易踩坑。下面我整理了几个高频问题。
6.1 编译报错:找不到 Qt 头文件
这个问题的根本原因是 CMake 使用了主机上的 Qt 而不是交叉编译版本的 Qt。可以使用以下命令确认:
cmake --build build --verbose查看输出中编译器路径是否为aarch64-linux-gnu-g++,以及头文件搜索路径是否指向 sysroot。修复方式是在 CMake 中设置CMAKE_PREFIX_PATH,指向目标板 Qt 的安装目录。
6.2 scp 拷贝后运行报错:No such file or directory
这个报错比较迷惑,因为文件明明存在。常见原因有两个:一是动态库找不到;二是 ELF 解释器路径不对。可以使用ldd检查动态库依赖:
ldd ./rk3572_qt_demo如果输出中出现not found,说明目标板上缺少对应的.so文件。另一个原因可能是编译器使用ld-linux-aarch64.so.1路径不在目标板上,需要把工具链的 sysroot 与开发板的根文件系统对齐。
6.3 程序启动后黑屏或崩溃
这种情况多半是显示后端不匹配。尝试切换到linuxfb或offscreen平台:
export QT_QPA_PLATFORM=linuxfb ./rk3572_qt_demo如果程序能启动但显示异常,可能是环境变量QT_QPA_EGLFS_INTEGRATION设置不对,或者 fb 设备节点不对。检查/dev/fb0是否存在:
ls -l /dev/fb06.4 串口终端乱码
串口终端乱码通常是波特率不匹配。确认开发板调试串口波特率是 115200 还是 1500000,然后在主机侧设置相同速率。另外还要检查串口工具的流控设置,一般调试串口会禁用硬件流控。
6.5 开发板无法识别第二个网口
如果eth1完全没有出现,先从硬件层面排查:确认网口电路是否被设备树使能,电源是否正常,网线是否插紧。其次检查内核日志:
dmesg | grep -i eth如果日志里完全没有分配 MAC 地址,说明设备树中没有配置对应网口,需要修改设备树。
下面用表格汇总一下:
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 编译找不到 Qt 头文件 | CMake 用了主机 Qt | 设置 CMAKE_PREFIX_PATH 指向交叉 Qt |
| 运行时 No such file or directory | 动态库缺失或 ELF 解释器不对 | 使用 ldd 检查依赖,补齐 .so |
| 程序无法连接显示 | 显示后端不匹配 | 切换 eglfs/linuxfb/offscreen |
| 串口乱码 | 波特率不一致 | 统一两侧波特率,关闭流控 |
| eth1 未出现 | 设备树未使能或驱动未加载 | 修改设备树,查看 dmesg |
| 上电程序不自启 | systemd 服务未启用 | 检查服务状态和 ExecStart 路径 |
7. 最佳实践与工程建议
7.1 稳定性优先
智能工控设备往往长时间运行在高温、高湿、强电磁干扰的现场环境。开发阶段跑通功能只是第一步,稳定性设计才是交付的关键。
电源供电不要依赖 USB 口,尽量使用开发板要求的直流电源适配器。系统层面建议开启看门狗,防止程序死锁后系统长期无响应。Linux 下可以启用内核看门狗模块:
devmem 0xff668000 32 0x00000001不过更推荐使用 RTOS 或者用户态看门狗服务,定时喂狗,策略更灵活。
7.2 程序日志要规范
工控现场出问题,开发者往往不在现场,只能靠日志定位。日志至少要包含时间戳、模块名、级别、关键变量值。C++ 项目可以直接使用syslog,也可以封装一个简易日志类。
下面是一个简单的日志宏:
#include <QDateTime> #include <QDebug> #define LOG_INFO(msg) \ qInfo() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz") \ << "[INFO]" << msg #define LOG_ERROR(msg) \ qCritical() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz") \ << "[ERROR]" << msg日志文件建议写到/var/log或独立的 data 分区,避免 rootfs 只读导致写入失败。
7.3 安全边界与最小权限
工控设备接入网络后,会面临一定的安全风险。建议默认关闭不必要的远程登录方式,只保留 SSH,并修改默认密码。如果设备直接暴露在公网,务必配置防火墙,只开放必要的端口。
在处理串口、GPIO、网络配置时,尽量遵循最小权限原则。普通业务程序不要用 root 运行,可以单独创建一个系统用户,只赋予它操作必要的设备节点和目录的权限。
7.4 镜像与版本管理
开发过程中,频繁改动内核、设备树和 rootfs 会导致板子状态不一致。建议每完成一个稳定版本,就导出一份完整的系统镜像备份。这样即使开发板系统损坏,也能快速恢复现场。
常用做法是使用dd备份 SD 卡或使用瑞芯微的打包工具重新生成镜像,并在仓库里记录对应的 SDK commit、补丁和编译配置。这一点在项目交付和后期维护时价值非常大。
7.5 避免高频轮询
很多工控程序喜欢用while (1) + sleep(1)去轮询传感器或网络数据。这种写法在资源紧张的单片机上很常见,但在 Linux 环境下并不是最优选择。推荐使用事件驱动,例如 Qt 的定时器、信号槽,或者使用 epoll 管理网络事件。
定时轮询的潜在问题是 CPU 占用高、事件响应延迟不稳定。改成事件驱动后,程序运行更平稳,CPU 占用更低,也更便于后续扩展。
7.6 建立持续集成
如果团队多人协作,建议在主机上搭建 Git + CI 环境,每次提交代码后自动触发交叉编译,生成可烧录的镜像或安装包。这样可以避免“在我机器上能编译,在服务器上就失败”的尴尬情况。
8. 总结与学习路线
RK3572 开发板作为智能工控方案的主控平台,优势在于算力与生态的平衡。它能运行完整 Linux 系统,支持 Qt 界面、工业总线、网络通信和边缘计算,同时功耗和体积又优于传统工控机。对开发者来说,掌握开发板的基本使用、交叉编译和部署流程,是快速进入智能工控领域的实用技能。
如果你刚接触这个方向,我建议按下面的顺序学习:
- 先熟练使用 SSH、串口和基本 Linux 命令。
- 再搭建一次完整的交叉编译工具链,跑通一个最小 Qt 程序。
- 然后尝试配置 GPIO、串口、双网口,把开发板当成一个真正的工业控制器来使用。
- 最后再深入了解设备树、内核编译和系统定制。
在真实项目中,建议把系统稳定性、日志规范、安全和版本备份放在比功能开发更高的优先级上。技术本身并不复杂,复杂的是如何让设备在现场长期可靠运行,这一点值得在生产环境里反复打磨。希望这篇文章能帮助你在 RK3572 开发板上的智能工控开发少走一些弯路。