低成本嵌入式Linux开发方案:RV1106入门
需求分析
传统MCU开发效率太低,代码移植性弱,如何做到一次开发永久使用?答案就是操作系统
从MCU到实时操作系统,例如RTOS。实时操作系统虽然可以简化用户代码,增强操作逻辑,但是依然需要依赖组件模块,需要用户根据硬件去调试模块,遇到特别复杂的项目gg
Linux操作系统把底层的硬件资源都抽象成了软件资源,大大提升了开发效率。但是传统MCU没有MMU,RAM、Flash太小,无法运行嵌入式Linux。
STM32MP系列支持了嵌入式Linux,但是硬件外围比较复杂,增加了硬件成本,适合工业客户,但是对于成本敏感型客户来说比较鸡肋
放眼望去,要想寻找低成本解决方案,只能将目光投向国产处理器了。
目标处理器最好能够做到低成本够用的性能,硬件电路尽可能简单,开发资料最好稍微丰富一些。这对于芯片厂家来说,只需要提供底层的硬件配置,然后对接到现有的嵌入式Linux平台(例如Buildroot、Yocto等)即可。软件上的资源经过漫长的积累要丰富很多
选型思路
主要考虑过两款处理器,全志V3S
vs 瑞芯微RV1106
特性 | 全志V3S | 瑞芯微RV1106 |
---|---|---|
CPU架构 | 单核ARM Cortex-A7@1.2GHz | 单核ARM Cortex-A7@1.2GHz |
AI算力 | 无专用NPU | 第四代NPU,0.5TOPS(int8)/1.0TOPS(int4) |
内存支持 | DDR3/DDR3L(最高2GB) | 内置64MB~256MB DRAM,可选外接DDR3L |
网络 | 内置百兆以太网PHY(网传有bug) | 内置百兆以太网PHY |
开发资源 | 社区资源丰富 | 提供官方资源 |
集成DDR | 64MB | 128MB / 256MB |
全志的V3S在行车记录仪上用得很多,主打一个低成本,自2015年上市以来,已经积累了庞大的用户群体,开发资料也相对齐全。瑞芯微RV1106集成了AI处理单元,28nm的工艺也带来了更优秀的功耗。两款处理器都集成了DDR
嵌入式Linux操作系统
嵌入式Linux操作系统主要有三大主线,Buildroot
vs Yocto
vs Ubuntu Core
维度 | Buildroot | Yocto | Ubuntu Core |
---|---|---|---|
定位 | 轻量级嵌入式系统构建工具 | 工业级定制化Linux发行版构建框架 | 面向IoT的轻量级安全操作系统 |
构建逻辑 | 单次全量编译(Monolithic) | 分层架构(Meta-layer) | Snap包容器化部署 |
包管理 | 静态选择(无增量更新) | 动态配方(Recipes)支持增量更新 | Snap商店在线更新 |
定制性 | 中等(可裁剪内核/基础软件) | 极高(从内核到应用深度定制) | 中等(依赖Snap生态) |
构建时间 | 10–60分钟(首次) | 2–10小时(首次) | 30分钟+(依赖PPA源) |
磁盘占用 | 3–10GB | 50–200GB | ≥512MB RAM |
学习曲线 | 低(类Linux内核配置) | 陡峭(需掌握BitBake语法) | 低(类Ubuntu桌面) |
调试复杂度 | 低(日志集中) | 高(日志分散在tmp/work) | 中等(Snap隔离机制) |
资源受限设备 | ✅ 超小型设备(Flash<16MB) | ⚠️ 需优化配置 | ❌ 资源占用较高 |
网络设备 | ✅ 路由器/网关(集成iptables等) | ⚠️ 需额外配置网络功能 | ✅ 边缘计算节点(云原生支持) |
复杂工业系统 | ❌ 依赖处理能力弱 | ✅ 车机/工控(实时性、安全认证) | ⚠️ 需手动集成实时补丁 |
快速原型开发 | ✅ 验证硬件基础功能 | ❌ 构建周期长 | ✅ 开箱即用(预装AI/云工具) |
长期维护与更新 | ❌ 全量更新困难 | ✅ 企业级维护(SLA支持) | ✅ 5年LTS + 自动回滚 |
系统启动时间 | 快 | 一般 | 满 |
由于实际项目要求系统时间尽可能快,同时不要求过于复杂的性能,因此这里选择了buildroot
实操过程
从易到难,由浅入深,控制变量,逐个击破
硬件准备
Luckfox Pico Pro/Max,考虑到不需要特别大的DDR,同时尽可能低成本,这里选择G2版本
软件环境
Ubuntu22.04.5虚拟机或物理机,试过都可以,虚拟机好备份,物理机编译快
折腾前先点灯
在单片机开发中,为了确认硬件和开发环境是否OK,通常会先点一个灯看看;对于软件开发,就是写一个’Hello World’;对于嵌入式Linux而言,就是上电看终端输出,同时尝试交互指令
参考教程
开发板出厂自带系统,连接串口2,Type-C上电,打开终端,可以看到成功启动
重新编译系统镜像
参考教程
- 安装依赖环境
# 更新源
sudo apt update
# 安装需要的包
sudo apt-get install -y git ssh make gcc gcc-multilib g++-multilib module-assistant expect g++ gawk texinfo libssl-dev bison flex fakeroot cmake unzip gperf autoconf device-tree-compiler libncurses5-dev pkg-config bc python-is-python3 passwd openssl openssh-server openssh-client vim file cpio rsync
- 获取最新的 SDK
git clone https://gitee.com/LuckfoxTECH/luckfox-pico.git
- 配置环境变量
# 切换到工具链的目录下
cd /path/to/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf
# 更新一下环境变量
source env_install_toolchain.sh
- 选择硬件版本、启动媒介
# 切换到SDK目录下
cd /path/to/luckfox-pico/
# 选择要编译的硬件版本
xxx@xxx-server:~/path/to/luckfox-pico$ ./build.sh lunch
You're building on LinuxLunch menu...pick the Luckfox Pico hardware version:选择 Luckfox Pico 硬件版本:[0] RV1103_Luckfox_Pico[1] RV1103_Luckfox_Pico_Mini_A[2] RV1103_Luckfox_Pico_Mini_B[3] RV1103_Luckfox_Pico_Plus[4] RV1103_Luckfox_Pico_WebBee[5] RV1106_Luckfox_Pico_Pro[6] RV1106_Luckfox_Pico_Max[7] RV1106_Luckfox_Pico_Ultra[8] RV1106_Luckfox_Pico_Ultra_W[9] RV1106_Luckfox_Pico_Pi[10] RV1106_Luckfox_Pico_Pi_W[11] RV1106_Luckfox_Pico_86Panel[12] RV1106_Luckfox_Pico_86Panel_W[13] custom
Which would you like? [0~13][default:0]: 5Lunch menu...pick the boot medium:选择启动媒介:[0] SD_CARD[1] SPI_NAND
Which would you like? [0~1][default:0]: 0Lunch menu...pick the system version:选择系统版本:[0] Buildroot
Which would you like? [0][default:0]: 0
[build.sh:info] Lunching for Default BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk boards...
[build.sh:info] switching to board: /path/to/luckfox-pico/project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk
[build.sh:info] Running build_select_board succeeded.
- 开始编译
# 开始全部编译
./build.sh
因为编译过程要用到wget
来获取一些python
库,可能存在网络连接的问题,最佳解决方案是给它配置一个代理。因为平台限制的问题,这里不能具体提及,需要可参考
十多分钟就编完了,buildroot
比Yocto
还是要轻量化很多的。
烧录镜像
参考教程
这里选择先烧录TF卡,万一搞错了也容易改
- 格式化TF卡
TF卡连接至电脑后,最好先格式化卡。
这里选择Windows自带的Diskpart,使用方法很简单,Win+R
输入diskpart
回车打开,需要管理员身份,注意千万不要错选成自己的磁盘。
打包镜像
cd /path/to/luckfox-pico/output/image/
zip -v image.zip boot.img env.img idblock.img oem.img rootfs.img uboot.img userdata.img
使用scp
拷贝到本地并且解压
管理员打开SocToolKit
,选择对应的文件和TF卡,开始刻录
将卡拔下,插入开发板,上电,完成,可以看到如点灯的界面
修改设备树文件来添加外设
实际开发中,可能需要根据需求添加一些外设。传统的MCU的外设初始化是以函数的形式存在的,通过编写初始化函数配置相应的寄存器实现。
在Linux系统中需要配置设备树文件,将设备树文件编译进系统内核中,系统内核会自动加载
实际项目中需要添加两路串口,这里通过修改设备树重新编译内核来实现。
找到设备树文件,打开项目配置文件,可以看到其中指定了设备树文件为rv1106g-luckfox-pico-pro.dts
cat project/cfg/BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Pro-IPC.mk export RK_CHIP=rv1106# app config
export RK_APP_TYPE=RKIPC_RV1106# Config CMA size in environment
export RK_BOOTARGS_CMA_SIZE="66M"# Kernel dts
export RK_KERNEL_DTS=rv1106g-luckfox-pico-pro.dts
在整个SDK中查找一下这个文件
# 查找文件
find ./ -name rv1106g-luckfox-pico-pro.dts
# 编辑设备树文件
nano ./sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-luckfox-pico-pro.dts
找到UART
的部分,disable
改成okay
/**********UART**********/
/* UART3_M1 */
&uart3 {status = "okay";
};/* UART4_M1 */
&uart4 {status = "okay";
};
只需要重新编译内核即可
# 清理旧的内核编译
./build.sh clean kernel
# 重新编译内核(包含新的设备树)
./build.sh kernel
编译完成后需要重新打包
# 将所有组件打包成完整固件
./build.sh firmware
重新将./output/image/
下的文件烧录到sd卡
烧录完成后上电,可以看到设备下多了两个/dev/ttyS3
和/dev/ttyS4
,这就是对应的uart3
和uart4
[root@luckfox root]# ls /dev/ttyS*
/dev/ttyS3 /dev/ttyS4
查看一下它们的信息,可以看到默认波特率是9600bps
[root@luckfox root]# stty -F /dev/ttyS3 -a
speed 9600 baud;stty: /dev/ttyS3line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho
[root@luckfox root]# stty -F /dev/ttyS4 -a
speed 9600 baud;stty: /dev/ttyS4line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho
将TX和RX通过USB转TTL连接值计算机做测试,引脚可以参考
将他设置成115200bps,发送测试数据同时接收
# 设置波特率
stty -F /dev/ttyS3 115200 cs8 -parenb -cstopb
# 发送数据到串口3
echo "UART3 Test" > /dev/ttyS3
# 接收串口3的数据
cat /dev/ttyS3
可以看到通信正常