3DR Radio固件定制:SiK源码编译与烧录实战指南
2026/9/3 18:38:35 网站建设 项目流程

简介:面向无线通信与嵌入式开发者的3DR Radio固件源码包,围绕Si1000、C8051F930和SI4432三颗芯片,提供完整的433MHz低功耗数字传输电台实现。压缩包共82个文件,含24个C头文件、18个C源文件、12个Python脚本、9个C#工程文件,并附Makefile与hex固件,整体约230KB,目录分层清晰,便于对照阅读与重新编译。已有1058人学习/下载。源码开放了射频前端配置、数据包封装与解封装、错误检测与纠正机制,以及待机与工作模式下的功耗优化策略;开发者可自由查看和修改协议参数,也可将其中无线通信框架移植到其他Si1000或SI4432相关项目中。对想深入理解无线数传底层原理的初学者、或从事嵌入式低功耗通信开发的技术人员,这套开源固件都能提供扎实的实战参考与二次开发基础。 拆开一块 3DR Radio 模块,主板上那枚不起眼的 Si1000 芯片才是真正的主角。它把 8051 内核、射频收发前端和 Flash 全部封进一颗芯片里,而你从网上拉下来的 3DR Radio 固件源码,就是跑在这颗芯片上的整套裸机程序。很多人把 3DR Radio 当成一个"用就完事"的遥测外设:插上线、配对、飞。但只要你愿意打开固件源码,会发现这块模块的很多东西——默认波特率、发射功率、空中速率、信道中心频率、LED 指示逻辑——全部可以由你自己改。这篇就把我从源码阅读到编译烧录的完整过程整理出来,给想折腾这套固件的朋友一条能走通的路。

1. 固件源码到底值不值得啃:先搞清楚 3DR Radio 是什么

1.1 模块拆开后的物理真相

3DR Radio 这个名字,最早来自 3D Robotics 推出的开源遥测无线电模块,最常用的版本是 433MHz 和 915MHz 两种。它做的是地面站和飞控之间的透明串口桥接,你在地面站上看到的 MAVLink 数据流,本质上就是这个模块把飞控 UART 收到的数据打包、发射,另一端的模块接收后再从 UART 吐出来。

模块的核心不是普通的射频收发芯片,而是 Silicon Labs 的 Si1000 系列 SoC。这颗芯片很有意思,它内部集成了一个 8051 内核(C8051F930)和一颗完整射频收发前端,不需要外接 MCU。这套硬件方案决定了固件的形态:它是一份跑在 8051 内核上的大而全的裸机程序,没有操作系统,没有线程,只有一个大循环在不断检查串口和射频中断。

1.2 开源固件的真正价值

3DR Radio 的固件项目叫 SiK,全称是 Si1000 Kernel,开源在 GitHub 的 ArduPilot 组织下。这是整套系统最有价值的资产。你不需要依赖原厂的升级工具,不需要逆向二进制指令,直接拉源码就能定位到每一处行为。

从源码角度看,它能改的东西大致分三类:

  • 通信参数:串口波特率、空中波特率、发射功率、信道频率、心跳超时
  • 协议行为:MAVLink 透传策略、包重传机制、流控逻辑
  • 硬件指示:LED 闪烁模式、按钮行为、串口调试输出

这三类改动覆盖了绝大多数使用场景。比如你想让模块默认以 115200 波特率连接飞控,不用每次上电都手动 AT 指令,直接在源码里改默认值,一劳永逸。

2. 源码骨架拆解:从目录结构到一条数据包的完整旅程

2.1 目录结构:先看 boards 再谈其他

把 SiK 仓库拉下来之后,第一步别急着读代码,先看目录结构。仓库里最值得关注的是boards/文件夹,里面按硬件版本划分了板级目录,例如原厂的 3dr_radio_v1、v2、v3,以及 Pixhawk 定制版本。每个板级目录下都有board.hboard.mk这类文件,它们决定了固件编译时用哪些引脚定义、哪些射频配置。

这里有个容易忽略的点:同一套 SiK 源码编译出来的固件,烧到不同硬件版本上,行为可能完全不一样。原因就在boards/目录里,不同板子有不同board.h。所以拿到源码后,先确认自己手头的模块是哪个硬件版本,再进到对应的板级目录去读文件,这个顺序不能反。

2.2 数据流:从飞控串口到空中再到地面站

读完目录结构,下一步是理解一条数据包在固件内部是怎么流动的。SiK 的代码虽然文件不少,但主线其实非常清楚:

  1. 飞控把 MAVLink 字节流从 UART 送进模块,8051 的 UART 中断逐字节把数据收进缓冲区。
  2. 主循环检测到缓冲区里有完整数据帧,就交给内部的打包逻辑,把数据帧按 SiK 自定义的无线包格式封装。
  3. 封装后的包通过 Si1000 的 RF 部分做 GFSK 调制后从天线发出去。
  4. 接收端模块收到射频包,做完整性校验,通过后把有效负载从 UART 吐给地面站。

这个过程里,固件还穿插做了两件容易被忽视的事:ACK 重传和管理帧解析。SiK 的无线链路是有确认机制的,发送方如果没收到接收方的 ACK,会按重传策略重发,这保证了 MavLink 数据在无线链路上的可靠性。管理帧则是 AT 指令的基础,你在串口终端里输入ATI能返回固件版本,走的就是管理通道。

读源码的时候,可以顺着数据流去搜函数:UART接收处理、射频发射函数、ACK 超时处理。把这几个点找到,整个固件的脉络就基本清楚了。

3. 编译工具链:搭建 SiK 固件的构建环境

3.1 工具链选择与安装细节

编译 SiK 是目前体验最"复古"的一环,因为它的官方构建流程依赖 Silicon Labs 自家的 IDE 和 Keil C51 编译器。这套工具链主要跑在 Windows 上,步骤如下:

  • 安装 Silicon Laboratories IDE(旧版 IDE,当前官网可能不好找,需要从历史下载链接或社区存档获取)
  • 安装 Keil C51 编译器,注意 SiK 源码对 C51 的版本有一定要求,实测较新版本也能编译,但个别文件可能有差异
  • 打开 SiK 仓库里的工程文件(后缀通常是.uvproj.wsp),确认工程引用的板级目录是自己的硬件版本
  • 设置编译优化选项,8051 内核的 Flash 空间有限,一般要开启较高优化等级才能把固件塞进去

这套环境放在现在来说确实有点"古董",但 SiK 本来就是为这颗 8051 SoC 写的,绕不开。Linux 环境下也有人用 SDCC 交叉编译,但对 Si1000 这种特定芯片,SDCC 的支持不如 Keil C51 成熟,生成的代码体积和稳定性都可能出问题。我的建议是别在工具链上折腾替代方案,老老实实用官方 IDE 编译。

3.2 board.h 里的关键参数清单

编译之前,务必打开自己板级目录下的board.h逐项过一遍。下表的参数是我在实际使用中确认过对行为影响最直接的几个。

参数/宏名称作用我的实测备注
SERIAL_BAUDUART 串口速率决定模块和飞控/地面站之间的波特率,两边必须一致
AIR_BAUD空中射频波特率空中速率受带宽限制,过高会导致接收灵敏度下降
TXPOWER射频发射功率受硬件限制,普通模块不建议直接拉满
RADIO_CHANNEL射频信道中心频率一般出厂已设好,修改需要谨慎考虑频段合规问题
MAVLINK 相关宏决定是否开启 MAVLink 特化处理非 MAVLink 透传场景可以关闭,节省资源

我强烈建议在动任何代码之前,先把原厂固件用 AT 指令读一遍当前参数ATI,记录下原始配置,再对照board.h里的宏定义,这样能快速定位哪些参数在源码里、哪些参数运行时才能改。

3.3 编译后的产物

编译成功后会生成 hex 文件,这个 hex 文件就是最终要烧进模块的固件。在烧录之前,可以对 hex 文件做一次简单的代码体积检查,看占用了多少 Flash。SiK 原厂固件的体积通常很紧凑,如果你加入的改动明显增大了代码体积,得警惕编译优化等级是否被调低了。

4. 第一次真正修改固件:以改串口波特率和发射功率为例

4.1 改串口波特率:最直观的上手实验

要说哪个改动最能建立成就感,一定是改默认串口波特率。很多人的需求是让模块默认就跑 115200,省得每次用 AT 指令改。

源码中修改位置在board.h里的串口速率定义。类似下面的代码:

#define SERIAL_BAUD 57600 // 原厂默认值 // 改为 #define SERIAL_BAUD 115200 // 你的目标波特率

改完编译、烧录,模块上电后默认就是 115200。这里有一个我踩过的坑:改完波特率之后,如果模块连接的是飞控,飞控对应的SERIALx_BAUD参数也必须改成 115200,否则两端波特率不一致,地面站会看到大量的掉包和校验失败。这不是模块的问题,是两端没有对齐。

4.2 调整发射功率与空中速率

发射功率是另一个高频改动点。原厂固件默认功率设置通常比较保守,源码里搜索TXPOWER或者直接定位到射频参数初始化段,可以找到类似这样的代码:

// 射频功率寄存器配置 radio_set_txpower(20); // 20 dBm,约 100 mW

如果你用的是普通版本模块(没有外置功放),我建议不要把功率调得高于硬件规格。因为 Si1000 内部的功放能力有限,盲目拉高功率会导致射频输出饱和、信号反而变差,而且芯片发热明显上升。如果你的模块是带 PA/LNA 的高功率版本,功率设置逻辑在源码里通常是另一条分支,需要额外关注 PA 的偏置和开关时序。

空中速率的调整逻辑类似。空中速率越高,单包传输时间越短,但同时接收灵敏度下降,通信距离会缩短。拿 433MHz 模块来说,空中速率设在 57600 和设在 19200,实际拉距表现差距非常明显。如果你需要远距离数传,把空中速率降下来,收益远大于盲目加功率。

5. 烧录、变砖与自救:bootloader 是最后的救命稻草

5.1 bootloader 的作用与进入方式

SiK 固件分两部分:出厂固化在芯片里的 bootloader 和用户通过 bootloader 写入的 app 固件。bootloader 的作用是接收来自串口的固件数据并写入 Flash,这样就不用每次升级都动用 JTAG/编程器。

进入 bootloader 的方式在 3DR Radio 模块上一般有两种:

  1. 按住模块上的按钮后上电(部分硬件版本有小按钮)
  2. 在 UART 空闲时通过工具发送特定字节或把 BOOT 引脚拉低后上电

不同的硬件版本细节不同。我在实际使用中,最稳的办法是查阅自己模块对应的板级目录里board.h中对 bootloader 引脚的注释,或者直接查看 bootloader 源码中串口接收处理的逻辑,确认进入条件。

5.2 用 sik_uploader.py 烧录的完整流程

SiK 仓库的tools/目录下提供了sik_uploader.py脚本,这是最常用的烧录工具。在 Linux 下用 USB-TTL 接好模块,在模块上电瞬间按对应方式进入 bootloader,之后执行类似下面的命令:

python sik_uploader.py /dev/ttyUSB0 path/to/firmware.hex

脚本会先通过串口和 bootloader 握手,然后以固定波特率把 hex 文件逐块写入 Flash。整个过程大概几十秒,期间不能断开串口连接,也不能断电。

这个工具还有一个很有用的参数:查看 bootloader 版本。不同版本的 bootloader 对 app 固件的兼容性有差异,如果你遇到烧录成功但模块无法正常启动的情况,先确认 bootloader 版本和固件版本是否配套。

5.3 变砖案例复盘:我和一块"黑屏"模块的半小时

分享一次真实翻车经历。有次我想把波特率改成 115200,但脑子一热,同时把空中速率也调高了,还顺手改了一个信道参数。烧录后模块完全没有反应,串口终端打 AT 无回显,LED 也不闪。第一反应是"砖了"。

冷静下来后的排查路径是这样的。首先,把模块重新上电,尝试进入 bootloader。因为 bootloader 是独立于 app 的,只要 bootloader 没被破坏,就能强制进入。按住按钮上电,排查脚本能识别到 bootloader,说明芯片没死。然后我重新烧回原厂固件,模块立刻恢复正常。

这个案例的结论很简单:折腾 app 固件不会把模块折腾砖,因为 bootloader 才是最后的安全网。真正让模块报废的操作,是烧录中途断电或者把 bootloader 区域擦掉。所以我的建议是,无论怎么改固件,务必保留原厂 hex 备份,并且不要手滑烧录任何覆盖 bootloader 的镜像。

6. 从源码到日常使用:折腾完固件之后的几点提醒

6.1 版本匹配是最大的隐性成本

3DR Radio 的硬件版本、bootloader 版本、固件版本、地面站参数,这四个东西是相互牵制的。只改其中一个,另外三个不一定兼容。比如给旧版硬件刷新版固件,射频前端寄存器配置可能对不上,表现为信号强度异常或者通信距离变短。我只踩过一次旧硬件配新固件的坑:模块能配对,但丢包率高得离谱,最后查下来是固件里默认的射频前导码长度和旧硬件的匹配度不好。

所以,刷固件之前,一定记录当前模块的ATI信息,包括固件版本、bootloader 版本。这样出现异常时能快速回退。

6.2 备份原厂固件,这件事别偷懒

很多人刷完自定义固件才想起来原厂固件没备份,回头网上找又不一定找得到对应版本的 hex。正确做法是拿到模块的第一时间,先读一遍ATI,然后从源码仓库或社区固件库下载对应版本的 hex 存好。这几十秒的功夫,能在后面省下几小时的折腾时间。

6.3 自定义固件最适合的三种场景

根据自己的经验,我总结三个真正值得改源码的场景:

  • 固定串口速率:批量部署数传模块时,避免每台设备都手动 AT 配置,编译时写死目标波特率
  • 定制 LED 指示逻辑:通过 LED 状态判断模块是处在配对状态、传输状态还是 bootloader 模式,户外调试时非常有用
  • 精简协议处理:如果只传输特定类型的数据,可以在固件层过滤掉不关心包,降低有效带宽占用

这三类改动在源码里都能找到明确的切入点。顺着数据流找 UART 接收处理、射频发送、管理帧处理这几个位置,把断点附近的逻辑改掉即可。

6.4 频率参数:源码里的东西更得谨慎

源码编译的灵活性带来一个隐蔽风险:你可以在代码里把中心频率改到任何 Si1000 支持的频点。但实际使用中,频率参数必须符合当地无线电管理规定,而且模块的硬件天线匹配是针对出厂频段设计的,随意改频不仅可能违法,实际辐射效率和接收灵敏度也会劣化。我的个人原则是:信道参数在编译后不再动,只通过运行时 AT 指令选择已通过合规性考虑的信道。

最后再分享一个小技巧:如果刷了自定义固件后模块连接不稳定,先用串口终端连上模块,输入ATI确认固件版本和参数,再用AT&F恢复默认参数,排除运行时参数被改乱的可能。很多时候问题不在固件代码,而在参数被不明不白地改过。固件源码给了你绝对的掌控力,但掌控之前,先学会记录和回退。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询