3. PX4飞控固件编译:从GitHub克隆PX4-Autopilot源码,配置交叉编译环境,编译第一个固件
好,到了真正动手的环节了。前面两章我们把工具链和概念理了一遍,现在要干点实在的——把PX4固件从源码编译出来。说实话,我第一次编译PX4的时候,光是环境配置就折腾了大半天。但你别怕,我把那些坑都踩过了,你跟着我的步骤走,会顺很多。
3.1 从GitHub拉取PX4-Autopilot源码
先找个干净的工作目录。我个人习惯在~/workspace下面放所有项目,你随意,但路径里最好不要有中文和空格。
mkdir -p ~/workspace
cd ~/workspace
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
这里有个关键点:--recursive参数。PX4依赖很多子模块,比如mavlink、uavcan、ecl等等。不加这个参数,你拉下来的代码是不完整的,编译到一半会报错说找不到头文件。我曾经有一次忘了加,结果排查了半小时才发现是子模块没拉全。
拉取完成后,进入目录看看结构:
cd PX4-Autopilot
ls -la
你会看到src/、boards/、cmake/、ROMFS/这些目录。其中boards/里存放了所有支持的硬件板级配置,后面选目标平台时会用到。
git clone --depth=1只拉最新版本,省流量。但后续更新时需要用git fetch --unshallow补全历史。
3.2 配置交叉编译环境
编译固件和编译普通Linux程序不一样。你是在PC上写代码,但最终要跑到ARM架构的飞控板(比如Pixhawk)上。这就需要交叉编译工具链。
PX4官方推荐用ubuntu.sh脚本一键安装依赖。但我不建议你直接跑那个脚本——它装的东西太多,有些你用不上,而且容易和系统已有的包冲突。
我习惯手动装核心组件:
# 安装基础编译工具
sudo apt update
sudo apt install -y \
git \
cmake \
ninja-build \
python3-pip \
python3-venv \
gcc-arm-none-eabi \
gdb-multiarch
# 安装Python依赖
pip3 install --user \
pyserial \
pyulog \
kconfiglib
这里重点说一下gcc-arm-none-eabi。这是ARM Cortex-M系列的交叉编译器,PX4的实时操作系统(NuttX)就是用它编译的。你可以在终端验证一下:
arm-none-eabi-gcc --version
如果输出了版本号,说明工具链装好了。如果没有,可能是源里没有这个包,你可以去ARM官网下载预编译的版本,解压后加到PATH里。
gcc去编译固件!那是x86架构的编译器,编译出来的东西飞控板跑不了。我见过有人搞混了,编译了一整天,最后刷进去飞控直接变砖。
3.3 编译第一个固件
环境配好了,我们来编译一个最简单的目标——px4_fmu-v5,对应Pixhawk 4飞控板。
cd ~/workspace/PX4-Autopilot
make px4_fmu-v5_default
第一次编译会比较慢,因为要下载NuttX源码、编译所有依赖库。我的机器大概要15-20分钟。你可以去泡杯咖啡。
编译过程中,终端会输出很多信息。你主要关注最后几行:
-- Build files have been written to: /home/user/workspace/PX4-Autopilot/build/px4_fmu-v5_default
[100%] Linking CXX executable px4_fmu-v5_default.elf
[100%] Built target px4_fmu-v5_default
看到[100%] Built target,说明编译成功了。生成的固件在build/px4_fmu-v5_default/目录下,主要有这几个文件:
| 文件 | 说明 |
|---|---|
px4_fmu-v5_default.elf |
带调试信息的可执行文件,用于GDB调试 |
px4_fmu-v5_default.bin |
纯二进制固件,刷写时用这个 |
px4_fmu-v5_default.hex |
Intel HEX格式,部分烧录工具需要 |
核心逻辑:编译的本质是把C/C++源码 + 飞控板配置 + 交叉编译器组合起来,生成目标硬件能识别的机器码。你不需要改任何代码,就能得到一个可运行的固件。
3.4 编译流程全景图
下面这张图展示了从源码到固件的完整流程,我建议你保存下来,以后遇到编译问题可以对照着排查:
3.5 常见编译问题与避坑
编译过程中难免遇到问题。我把最常见的几个列出来,你遇到了可以直接对照:
- 错误:
arm-none-eabi-gcc: command not found
交叉编译器没装或者没加到PATH。检查一下which arm-none-eabi-gcc,如果找不到,重新安装或者手动添加路径。 - 错误:
fatal error: mavlink/v2.0/...: No such file or directory
子模块没拉全。回到PX4目录,执行git submodule update --init --recursive补全。 - 错误:
CMake Error: .../Toolchain-arm-none-eabi.cmake: No such file
CMake找不到交叉编译器的工具链文件。检查cmake/toolchains/目录是否存在,如果缺失,重新clone源码。 - 编译到一半卡住不动
通常是网络问题,下载依赖超时。可以设置代理,或者用make px4_fmu-v5_default -j2降低并行度,减少网络并发压力。
gcc-arm-none-eabi包,版本匹配度最好。Ubuntu 18.04的包太旧,编译新版本PX4会报错。我曾经在18.04上折腾了一下午,最后升级到20.04才搞定。
3.6 验证固件是否可用
编译完成后,最好验证一下固件文件是否完整。我一般用file命令查看:
file build/px4_fmu-v5_default/px4_fmu-v5_default.elf
输出应该类似:
px4_fmu-v5_default.elf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped
看到ARM和statically linked就对了。这说明它是ARM架构的静态链接可执行文件,可以直接在飞控板上运行。
你也可以看看文件大小:
ls -lh build/px4_fmu-v5_default/px4_fmu-v5_default.bin
一般.bin文件在500KB到1MB之间。如果太小(比如只有几KB),说明编译可能出了问题,检查一下有没有报错被忽略了。