4、PX4源码编译:从GitHub拉取到第一个固件
好,咱们进入正题。这一章要干的事,说白了就是把PX4的源码从GitHub上拽下来,再把编译环境搭好,最后编译出一个能跑的固件。我刚开始接触PX4时,光编译环境就折腾了两天——嗯,现在回头看,其实没那么复杂。
4.1 从GitHub拉取PX4-Autopilot
先说说拉代码。我个人习惯用SSH方式克隆,省得每次输密码。如果你还没配SSH Key,也可以用HTTPS。
# 用SSH(推荐)
git clone git@github.com:PX4/PX4-Autopilot.git --recursive
# 或者用HTTPS
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
这里有个关键点:--recursive 参数。PX4依赖很多子模块,比如mavlink、uavcan等。不加这个参数,你拉下来的代码编译时会报一堆找不到头文件的错误。我曾经吃过这个亏,拉完代码直接make,结果卡了半小时才发现子模块没更新。
git submodule status 查看。如果某个子模块前面有个减号(-),说明没拉全,执行 git submodule update --init --recursive 补上。
4.2 编译环境搭建:make、cmake、gcc
编译环境说白了就三样东西:make(构建工具)、cmake(生成构建配置)、gcc(编译器)。但PX4对版本有要求,不是随便装一个就能用。
4.2.1 安装基础工具链
如果你用的是Ubuntu 20.04或22.04,官方推荐用以下命令一键安装:
sudo apt update
sudo apt install git zip qtcreator cmake build-essential genromfs ninja-build exiftool -y
# 安装依赖库
sudo apt install libxml2-dev libxslt1-dev libssl-dev -y
这里我多说一句:ninja-build 很多人会漏掉。虽然不用ninja也能编译,但用了之后编译速度能快30%左右。我项目里编译px4_fmu-v5,用make大概要8分钟,换成ninja只要5分半。
4.2.2 安装ARM交叉编译器
PX4固件跑在STM32这类ARM芯片上,所以需要交叉编译器。官方推荐gcc-arm-none-eabi,版本要求9-2020-q2-update或更高。
# 下载并安装ARM编译器
wget https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/9-2020-q2-update/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2
sudo tar xjf gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 -C /opt/
# 配置环境变量
echo 'export PATH=$PATH:/opt/gcc-arm-none-eabi-9-2020-q2-update/bin' >> ~/.bashrc
source ~/.bashrc
# 验证安装
arm-none-eabi-gcc --version
toolchain.cmake 文件,指定编译器路径,避免版本冲突。
4.2.3 验证环境
装完之后,跑一下PX4自带的检查脚本:
cd PX4-Autopilot
make check
这个脚本会检查所有依赖是否齐全。如果输出全是绿色的 OK,说明环境没问题。如果有红色报错,按提示补装就行。
4.3 编译第一个固件:px4_fmu-v5
环境搭好了,咱们来编译第一个固件。我选 px4_fmu-v5 是因为它是Pixhawk 4的主控固件,也是目前最常用的版本之一。
4.3.1 编译命令
cd PX4-Autopilot
make px4_fmu-v5
就这么简单?对,就这么简单。第一次编译会下载一些依赖包,大概需要10-15分钟。后面再编译就快了,增量编译一般1-2分钟搞定。
4.3.2 编译过程解读
编译时你会看到一堆输出,我挑几个关键阶段说说:
| 阶段 | 输出示例 | 说明 |
|---|---|---|
| 配置 | -- Configuring done |
cmake生成构建配置,检查依赖 |
| 编译 | [ 45%] Building CXX object ... |
百分比从0到100,编译各个模块 |
| 链接 | Linking CXX executable px4_fmu-v5.elf |
把所有目标文件链接成可执行文件 |
| 生成固件 | Built target px4_fmu-v5 |
生成 .px4 固件文件 |
4.3.3 编译产物
编译完成后,在 build/px4_fmu-v5_default/ 目录下能找到这些文件:
- px4_fmu-v5.elf:带调试信息的可执行文件,用于GDB调试
- px4_fmu-v5.px4:固件文件,直接烧录到飞控
- px4_fmu-v5.bin:纯二进制文件,某些烧录工具需要
核心要点:我们真正需要的是 .px4 文件。这个文件包含了引导加载程序和固件本身,通过QGroundControl或命令行工具就能烧录到飞控里。
4.4 常见编译错误与避坑
编译过程中难免遇到问题。我把自己踩过的坑整理了一下:
- 错误:arm-none-eabi-gcc not found —— 环境变量没配好,重新source一下.bashrc
- 错误:submodule not updated —— 执行
git submodule update --init --recursive - 错误:cmake版本过低 —— PX4要求cmake 3.10+,用
cmake --version检查,低了就升级 - 错误:内存不足 —— 编译时加
-j2限制并行任务数,比如make px4_fmu-v5 -j2
我曾经在编译时遇到一个诡异的错误:undefined reference to 'px4_log'。查了半天,发现是某个模块的日志宏定义没包含头文件。这种问题一般清理一下重新编译就能解决:
make clean
make px4_fmu-v5
4.5 本章知识体系
下面这张图把本章的核心流程串起来了:
这张图把整个流程分成了四个阶段:拉取源码 → 搭建环境 → 编译固件 → 生成产物。每个阶段都有对应的工具和输出,环环相扣。
4.6 验证编译结果
编译完成后,我习惯做两件事验证固件是否正常:
- 检查文件大小:
ls -lh build/px4_fmu-v5_default/px4_fmu-v5.px4,正常应该在1MB左右 - 查看固件信息:
strings build/px4_fmu-v5_default/px4_fmu-v5.px4 | grep "PX4",能看到固件版本和编译时间
.px4 文件重命名加上日期,比如 px4_fmu-v5_20250101.px4。这样方便回溯,知道哪个版本是啥时候编译的。