PX4 交叉编译顺序详解
一、完整编译链条
default.px4board -> Kconfig -> CMake -> Ninja -> 链接 -> 镜像封装 -> Bootloader 写入 Flash
本文是对 固件编译与烧写流程 的 Kconfig 阶段补充说明。
二、Kconfig 阶段详解
2.1 两类输入
| 类型 | 内容 |
|---|---|
| 规则输入 | 大量 Kconfig 文件,定义所有可选项、依赖关系与默认值 |
| 默认选择集 | defconfig(即 .px4board),给出初始选择快照 |
2.2 核心计算规则
1 | # 典型规则示例 |
2.3 两条 Kconfig 链路
PX4 的 Kconfig 与 NuttX 的 Kconfig 是相互独立的两条链路:
| 链路 | 控制范围 |
|---|---|
| PX4 Kconfig | PX4 模块(CONFIG_MODULES_*)、驱动、功能特性 |
| NuttX Kconfig | NuttX 内核裁剪、驱动框架、内存/堆栈/调试选项 |
两者均通过 default.px4board 的配置快照完成依赖求解,分别输出各自的 .config 部分,合并后供 CMake 消费。
三、编译阶段详解
| 阶段 | 执行者 | 输入 | 输出 | 输出被谁用 |
|---|---|---|---|---|
| 目标解析 | PX4 顶层 Makefile | px4_fmu-v5_default |
board=px4/fmu-v5,label=default,generator=Ninja |
后续 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 复位后执行 |
四、autoconf.h 的作用
autoconf.h 将 .config 事实表转换为 C 预处理宏:
1 | // .config 内容 |
代码层面通过条件编译实现功能裁剪:
1 |
|
CMake 也直接读取 CONFIG_* 开关,决定是否将某个目录/目标加入构建图谱,做到”不需要的代码连目录都不进入编译系统”。
五、链接脚本的来源
链接脚本决定各代码段(.text、.data、.bss)在 Flash/RAM 中的地址布局:
- NuttX 提供基础链接脚本框架
- Board 层的
nuttx-config根据芯片 Flash/RAM 大小进行裁剪 - 最终脚本控制 Bootloader 应用区的起始地址与大小,使固件能够被 PX4-Bootloader 正确识别与跳转