4、PX4 Autopilot 固件编译:从源码到可执行文件

好,咱们进入正题。这一章要解决的核心问题就一个:怎么把 PX4 的源码变成能刷进飞控板的固件。

说白了,就是搭建编译环境、拉代码、敲命令、处理报错。我刚开始接触 PX4 时,光编译环境就折腾了两天。嗯,现在流程成熟多了,但坑还是有的。咱们一步步来。

本章核心流程:GitHub 克隆源码 → 安装工具链 → 选择目标机型 → 编译 → 处理错误。

PX4 固件编译流程 ① 克隆源码 ② 安装工具链 ③ 选择机型 ④ 执行编译 ✅ 编译成功 ❌ 编译失败 🔧 分析错误日志 🔄 重新编译 💡 提示 多旋翼/固定翼选择不同 make 目标名不同

4.1 从 GitHub 克隆 PX4 源码

先做第一步:把代码拉到本地。我个人习惯用 git clone 加 --recursive 参数,因为 PX4 依赖很多子模块,一次性拉全省事。

# 克隆最新稳定版(推荐)
git clone https://github.com/PX4/PX4-Autopilot.git --recursive

# 如果你网络不好,可以只拉主仓库,再单独更新子模块
git clone https://github.com/PX4/PX4-Autopilot.git
cd PX4-Autopilot
git submodule update --init --recursive

⚠️ 注意:国内网络环境下,子模块下载经常超时。我曾经遇到过 git submodule 卡住半小时的情况。建议用代理,或者直接下载 GitHub Release 里的源码包(已包含子模块)。

克隆完成后,建议先切到一个稳定的发布版本。我一般用 v1.13.3 或 v1.14.0,这两个版本经过大量验证,坑比较少。

git checkout v1.13.3
git submodule update --init --recursive

4.2 配置编译环境

环境配置是新手最容易翻车的地方。PX4 官方提供了自动化脚本,但说实话,我建议你手动走一遍,这样出了问题知道去哪修。

4.2.1 Ubuntu 环境(推荐)

我主力开发机是 Ubuntu 20.04/22.04。下面是核心依赖安装命令:

# 更新包管理器
sudo apt update
sudo apt upgrade -y

# 安装基础编译工具
sudo apt install -y \
    git zip cmake build-essential genromfs ninja-build \
    exiftool astyle python3-pip python3-dev python3-venv \
    python3-serial python3-numpy python3-jinja2 \
    libxml2-dev libxslt1-dev libgstreamer1.0-dev \
    libgstreamer-plugins-base1.0-dev

# 安装 ARM 交叉编译器(针对 Pixhawk 等 STM32 飞控)
sudo apt install -y gcc-arm-none-eabi gdb-arm-none-eabi

💡 我的经验:gcc-arm-none-eabi 版本很重要。Ubuntu 20.04 默认源里的是 9.x,够用。如果你用 Ubuntu 22.04,默认是 10.x,也没问题。但千万别用 Ubuntu 18.04 的 7.x 版本,编译 PX4 v1.13+ 会报一堆奇奇怪怪的错误。

4.2.2 Python 依赖

PX4 编译过程中会调用一些 Python 脚本,比如生成参数文件、检查代码格式等。建议创建一个虚拟环境:

cd PX4-Autopilot
python3 -m venv px4_venv
source px4_venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

嗯,这里要注意。如果你不创建虚拟环境,系统全局的 Python 包可能会冲突。我吃过这个亏——有一次装了个新版本的 numpy,结果把 ROS 的依赖搞坏了,折腾了一下午。

4.3 编译固定翼/多旋翼固件

环境配好了,终于可以编译了。PX4 用 make 命令加目标机型来编译。目标机型的命名规则是:制造商_飞控板_应用配置。

4.3.1 多旋翼固件编译

最常用的目标机型是 px4_fmu-v5(对应 Pixhawk 4)和 px4_fmu-v3(对应 Pixhawk 1)。

# 编译多旋翼固件(默认配置)
make px4_fmu-v5_default

# 编译带 RTPS 支持的多旋翼固件(用于和 ROS2 通信)
make px4_fmu-v5_rtps

我第一次编译时,看着终端里刷刷刷滚过的日志,心里还挺激动。整个过程大概 10-20 分钟,取决于你的 CPU 和网络(要下载一些工具链)。

4.3.2 固定翼固件编译

固定翼的编译命令类似,只是目标名不同:

# 编译固定翼固件
make px4_fmu-v5_default

# 注意:px4_fmu-v5_default 默认是多旋翼配置
# 固定翼需要单独指定 airframe

等等,这里有个关键点。很多人以为 px4_fmu-v5_default 就是多旋翼,其实它只是一个基础固件。真正的机型选择是在固件烧录后,通过地面站参数 SYS_AUTOSTART 来设置的。编译时你只需要选对飞控硬件平台。

目标机型 适用飞控 典型应用
px4_fmu-v2_default Pixhawk 1 (FMUv2) 老款飞控,资源有限
px4_fmu-v3_default Pixhawk 1 (FMUv3) 2MB Flash 版本
px4_fmu-v5_default Pixhawk 4 (FMUv5) 多旋翼/固定翼通用
px4_fmu-v5_rtps Pixhawk 4 需要 ROS2 通信
sitl_default PC 仿真 软件在环测试

🔑 关键理解:编译时选的是硬件平台,不是飞机类型。飞机类型(多旋翼/固定翼/垂直起降)是在地面站里通过参数设置的。你编译一个 px4_fmu-v5_default,既可以飞多旋翼,也可以飞固定翼。

4.4 常见编译错误处理

编译不出错是不可能的,这辈子都不可能的。我整理了几个高频错误,你遇到了直接对照着修。

4.4.1 错误 1:arm-none-eabi-gcc 找不到

/bin/sh: 1: arm-none-eabi-gcc: not found

原因:交叉编译器没装,或者没加到 PATH 里。

解决:

# 检查是否安装
which arm-none-eabi-gcc

# 如果没装,重新安装
sudo apt install gcc-arm-none-eabi

# 如果装了但找不到,手动添加 PATH
export PATH=$PATH:/usr/bin

4.4.2 错误 2:子模块缺失

FATAL: src/modules/uORB is not a git repository

原因:git clone 时没有加 --recursive,子模块是空的。

解决:

git submodule update --init --recursive

我曾经犯过一个低级错误:从 GitHub 网页直接下载了 ZIP 包,结果里面没有 .git 目录,子模块根本拉不下来。后来老老实实用 git clone 了。

4.4.3 错误 3:Python 依赖版本冲突

ModuleNotFoundError: No module named 'jinja2'

原因:Python 包没装全,或者虚拟环境没激活。

解决:

source px4_venv/bin/activate
pip install -r requirements.txt

4.4.4 错误 4:内存不足导致编译崩溃

c++: fatal error: Killed signal terminated program cc1plus

原因:编译时并行任务太多,把内存吃光了。特别是虚拟机用户,2GB 内存很容易挂。

解决:限制并行编译任务数。

# 限制为 2 个并行任务
make px4_fmu-v5_default -j2

# 或者更保守,单线程编译
make px4_fmu-v5_default -j1

💡 我的建议:如果你在虚拟机上编译,至少分配 4GB 内存和 2 个 CPU 核心。我自己的开发机是 16GB 内存 + 8 核,用 -j8 编译大概 5 分钟搞定。

4.4.5 错误 5:固件体积超出 Flash 限制

region 'FLASH' overflowed by 12344 bytes

原因:你启用了太多模块,固件太大了,飞控的 Flash 装不下。FMUv2 只有 1MB,很容易超。

解决:

  • 换用更大 Flash 的飞控(如 FMUv5 有 2MB)
  • 裁剪不需要的模块:修改 boards/px4/fmu-v2/default.cmake,注释掉不需要的驱动
  • 使用优化编译:make px4_fmu-v2_default RELEASE=1

4.5 编译产物与验证

编译成功后,你会在 build/<目标机型>/ 目录下找到固件文件。最重要的两个:

  • px4_fmu-v5_default.px4:标准固件包,包含 bootloader,可以直接用 QGroundControl 刷写
  • px4_fmu-v5_default.elf:带调试信息的 ELF 文件,用于 GDB 调试

怎么验证固件对不对?我一般用这个命令:

# 查看固件版本信息
strings build/px4_fmu-v5_default/px4_fmu-v5_default.px4 | grep "PX4"

# 或者用 size 命令查看各段大小
arm-none-eabi-size build/px4_fmu-v5_default/px4_fmu-v5_default.elf

嗯,看到输出里有 PX4 v1.13.3 之类的字样,基本就稳了。