PX4 固件编译与烧写流程
一、编译链总览
make px4_fmu-v5_default 启动后经过七个阶段,最终将固件写入 MCU Flash:
1 | 选择 default.px4board |
相关前置知识:SOC 与 BSP 层平台抽象
二、各阶段详解
2.1 目标解析
顶层 Makefile 包装器解析 px4_fmu-v5_default,得到:
- board =
px4/fmu-v5 - label =
default - generator = Ninja(优先选择)
随后管理 CMake 配置缓存,调用 CMake/Ninja 执行真正的编译。
2.2 Kconfig 阶段
Kconfig 将 default.px4board 变成 .config 与 autoconf.h。
Kconfig 两类输入:
- 规则输入:大量 Kconfig 文件,定义可选项、依赖关系与默认值
- 默认选择集:
defconfig,给出初始配置快照
核心计算规则:
depends on:不满足则强制关闭select:联动打开依赖项choice:互斥选择,保留一个
注意:PX4 的 Kconfig 与 NuttX 的 Kconfig 是两条独立链路,分别控制 PX4 模块与 NuttX 内核的编译选项。
输出:
.config:CONFIG_*开关事实表autoconf.h:将事实表变成 C 宏#define CONFIG_XXX 1
CMake 根据 CONFIG_* 决定编译哪些目录,代码按 #ifdef CONFIG_* 裁剪。
2.3 CMake 配置阶段
输入:.config + 工具链 + 平台/板目录
输出:build.ninja + CMakeCache.txt
2.4 编译阶段
Ninja 调用 arm-none-eabi-gcc/g++ 将每个 .c/.cpp 编译为 .o,关键编译参数:
1 | -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard |
2.5 链接阶段
arm-none-eabi-ld 使用链接脚本(来自 NuttX/板级配置的 nuttx-config 与 Board ldscript)将所有 .o 与静态库 .a 组合成 px4_fmu-v5_default.elf(带符号与段信息)。
2.6 镜像封装
1 | objcopy firmware.elf -> firmware.bin / firmware.hex |
2.7 Bootloader 烧写
通过以下方式将镜像写入 MCU 内部 Flash 的固定地址区间:
- USB DFU
- MAVLink Bootloader(QGroundControl 固件更新)
- JLINK 调试器
流程:擦除应用区 Flash → 写入固件 → CRC 校验 → 重启跳转执行。
三、各阶段输入输出汇总
| 阶段 | 执行者 | 输入 | 输出 | 被谁使用 |
|---|---|---|---|---|
| 目标解析 | PX4 顶层 Makefile | px4_fmu-v5_default |
board、label、generator | 后续 Kconfig/CMake |
| Kconfig 求解 | kconfig 工具 | Kconfig 规则 + default.px4board |
.config + autoconf.h |
CMake 与编译器 |
| CMake 配置 | cmake | .config + toolchain + 平台/板目录 |
build.ninja + CMakeCache.txt |
Ninja |
| 编译/归档 | ninja → arm-none-eabi-gcc/g++ | 源码 + 头文件 + autoconf.h |
.o、lib*.a |
链接器 |
| 链接 | arm-none-eabi-ld | .o/.a + 链接脚本 |
firmware.elf |
objcopy/封装/调试 |
| 提取/封装 | objcopy + PX4 封装工具 | firmware.elf |
.bin/.hex/.px4 |
bootloader/QGC |
| 擦写/启动 | bootloader + QGC | .px4 或等价数据流 |
Flash 应用区固件 | MCU 复位后执行 |
四、上电执行路径
固件写入 Flash 后,上电复位时 MCU 的执行路径:
1 | MCU 从 Flash 取向量表 |
stm32_boardinitialize()
将 Board 层的 GPIO 初始化清单写进寄存器:
1 | Board 层提供 PX4_GPIO_INIT_LIST(GPIO_xxx 宏/Pinset 位域) |
board_app_initialize()
点亮 HRT/ADC/HW_INFO/SPI/IO_TIMER 功能,为 PX4 主系统启动做最后准备:
1 | -> HRT 初始化(要求先跑起来,后续 ADC/SPI 初始化依赖时间戳) |
上一篇:SOC 与 BSP 层平台抽象
下一篇:交叉编译顺序详解