PX4 飞控软件启动流程(NuttX + FMU-v6C)
文档涵盖:从上电到系统就绪的完整启动链,以及各飞行控制模块的加载顺序。目标平台:PX4 FMUv6C(STM32H7, Cortex-M7, NuttX RTOS)
目录
- [启动总览](#1-启动总览)
- [第一阶段:硬件初始化](#2-第一阶段硬件初始化)
- [第二阶段:NuttX 与 NSH 启动](#3-第二阶段nuttx-与-nsh-启动)
- [第三阶段:rcS 主启动脚本](#4-第三阶段rcs-主启动脚本)
- [第四阶段:传感器初始化](#5-第四阶段传感器初始化)
- [第五阶段:状态估计器](#6-第五阶段状态估计器)
- [第六阶段:控制与输出](#7-第六阶段控制与输出)
- [第七阶段:多旋翼控制模块详解](#8-第七阶段多旋翼控制模块详解)
- [模块启动机制](#9-模块启动机制)
- [模块间通信:uORB 消息总线](#10-模块间通信uorb-消息总线)
- [相关源文件索引](#11-相关源文件索引)
1. 启动总览
从飞控板上电到系统完全就绪,整个启动流程分为七个阶段:

2. 第一阶段:硬件初始化
源文件: boards/px4/fmu-v6c/src/init.c
2.1 stm32_boardinitialize() — 最低层硬件初始化
在 NuttX 内存初始化完成后、设备驱动加载前调用。
__EXPORT void stm32_boardinitialize(void){ board_on_reset(-1); // PWM 引脚置低(防止误转电机) board_autoled_initialize(); // LED GPIO 初始化 px4_gpio_init(gpio, ...); // 批量配置 GPIO (PX4_GPIO_INIT_LIST) stm32_usbinitialize(); // USB 接口初始化}PX4_GPIO_INIT_LIST 包含(board_config.h:255):
| GPIO | 功能 |
|---|---|
| ADC 输入引脚 | 电池电压/电流、硬件版本检测 |
| CAN1/CAN2 TX/RX | CAN 总线接口 |
| GPIO_HEATER1_OUTPUT | IMU 温控加热 |
| GPIO_nPOWER_IN_A/B/C | 电源检测(Brick1/Brick2/USB) |
| GPIO_VDD_5V_PERIPH_nEN | 外设 5V 电源控制 |
| GPIO_VDD_5V_HIPOWER_nEN | 高功率 5V 电源控制 |
| GPIO_VDD_3V3_SENSORS_EN | 传感器 3.3V 电源控制 |
| GPIO_TONE_ALARM_IDLE | 蜂鸣器控制 |
2.2 board_app_initialize() — 板级应用初始化
由 NuttX boardctl(BOARDIOC_INIT) 调用,在 NSH 启动之前执行。
__EXPORT int board_app_initialize(uintptr_t arg){ VDD_5V_PERIPH_EN(true); // 打开 5V 外设电源 VDD_5V_HIPOWER_EN(true); // 打开高功率 5V 电源 px4_platform_init(); // HRT 高精度定时器启动 board_determine_hw_info(); // 读取 ADC 判断硬件版本 // V6C00 / V6C01 / V6C02 等 stm32_spiinitialize(); // SPI 总线初始化 board_spi_reset(10, 0xffff); // SPI 外设复位(10ms) board_dma_alloc_init(); // DMA 内存分配器初始化 drv_led_start(); // LED 驱动启动 stm32_sdio_initialize(); // SD 卡接口初始化 px4_platform_configure(); // 根据硬件版本配置外设 I2C/SPI 映射}硬件版本检测:FMU-v6C 通过 ADC 读取版本/修订引脚,区分 7 种硬件变体:
| 版本 ID | 说明 |
|---|---|
| V6C00 | FMUv6C Rev 0, I2C4 外部但有内部设备 |
| V6C01 | FMUv6C Rev 1, I2C4 内部 I2C2 外部 |
| V6C02 | FMUv6C Rev 2, BMI088 + ICM42688P |
| V6C10 | 无 PX4IO Rev 0 |
| V6C11 | 无 PX4IO Rev 1 |
| V6C21 | FMUv6C Mini Rev 1 |
| V6C22 | FMUv6C Mini Rev 2, BMI088 + ICM42688P |
3. 第二阶段:NuttX 与 NSH 启动
NuttX 配置: boards/px4/fmu-v6c/nuttx-config/nsh/defconfig
CONFIG_INIT_ENTRYPOINT="nsh_main" // 系统入口 = NSH 主函数CONFIG_NSH_ARCHINIT=y // 启动时调用 board_app_initialize()CONFIG_NSH_CROMFSETC=y // 自动挂载 CROMFS 到 /etcCONFIG_FS_CROMFS=y // 压缩 ROMFS 支持(默认)CONFIG_FS_ROMFS=y // 普通 ROMFS 支持(备选)ROMFS 嵌入
启动脚本存储在 ROMFS 中,编译时嵌入固件,运行时挂载为根文件系统:

挂载后的 /etc/ 目录结构:
/etc/├── rcS ← 主启动脚本(自动执行)├── init.d/│ ├── rc.mc_defaults ← 多旋翼默认参数│ ├── rc.board_defaults ← FMU-v6C 板级参数│ ├── rc.board_sensors ← FMU-v6C 传感器启动│ ├── rc.vehicle_setup ← 飞行器类型分支│ ├── rc.mc_apps ← 多旋翼控制模块│ ├── rc.sensors ← 通用传感器│ ├── rc.autostart ← 自动生成: 空气框架选择│ ├── rc.autostart.post ← 空气框架额外参数│ └── airframes/│ ├── 4001_quad_x ← 通用四旋翼 X 型│ ├── 4014_s500 ← S500 机架│ └── ... ← 其他空气框架└── extras/ └── px4_io-v2_default.bin ← IO 协处理器固件4. 第三阶段:rcS 主启动脚本
源文件: ROMFS/px4fmu_common/init.d/rcS
执行流程(按顺序):
| 步骤 | 操作 | 含义 |
|---|---|---|
| 1 | ver all | 打印系统版本信息 |
| 2 | 挂载 SD 卡 (/dev/mmcsd0 → /fs/microsd) | 外部存储 |
| 3 | 检查 hardfault log | 异常时播放错误提示音 |
| 4 | param load / param import | 加载飞控参数(优先 SD,后备 MTD) |
| 5 | 检查 SYS_AUTOCONFIG | 需要时重置参数 |
| 6 | rc.board_arch_defaults | 架构级默认参数(如适用) |
| 7 | rc.board_defaults | FMU-v6C 板级参数 |
| 8 | rc.additional_init | 附加初始化(如适用) |
| 9 | rc.autostart | 加载空气框架配置 |
| 10 | tone_alarm start | 启动蜂鸣器 |
| 11 | dataman start | 航点/任务存储 |
| 12 | send_event start | 事件通知 |
| 13 | load_mon start | 资源负载监控 |
| 14 | RGB LED 启动 | 状态指示灯 |
| 15 | 用户配置覆盖 (/fs/microsd/etc/config.txt) | 可选 |
| 16 | 传感器初始化 | 见下一节 |
| 17 | 状态估计器 (EKF2) | EKF 启动 |
| 18 | PX4IO | 协处理器固件校验与启动 |
| 19 | RC 输入 | 遥控信号处理 |
| 20 | Commander | 飞行模式状态机 |
| 21 | 输出驱动 | DShot / PWM |
| 22 | UAVCAN / Cyphal | CAN 总线外设 |
| 23 | rc.vehicle_setup → rc.mc_apps | 控制模块启动 |
| 24 | 其他模块 | 磁偏估计、云台、FFT 等 |
| 25 | rc.logging | 日志记录器 |
| 26 | rc.autostart.post | 空气框架后处理参数 |
| 27 | mavlink boot_complete | 通知地面站系统就绪 |
| 28 | 释放脚本变量 | 回收 RAM |
5. 第四阶段:传感器初始化
5.1 FMU-v6C 板级传感器 — rc.board_sensors
源文件: boards/px4/fmu-v6c/init/rc.board_sensors
board_adc start ← 板载 ADC(电压/电流检测)硬件版本检查:if HW >= V6C02: bmi088 -A -R 4 start ← SPI BMI088 加速度计 bmi088 -G -R 4 start ← SPI BMI088 陀螺仪else: bmi055 -A -R 4 start ← SPI BMI055 加速度计 bmi055 -G -R 4 start ← SPI BMI055 陀螺仪icm42688p -R 6 start ← SPI ICM42688P (冗余 IMU)ms5611 -X -b 4 -a 0x77 start ← I2C4 气压计ist8310 -X -b 4 -a 0xc start ← I2C4 内置磁力计ist8310 -X -b 1 -R 10 start ← I2C1 外置磁力计(GPS 模块)5.2 通用传感器 — rc.sensors
源文件: ROMFS/px4fmu_common/init.d/rc.sensors
按参数启动可选传感器(由对应参数控制是否启用):
| 参数名 | 传感器 | 总线 |
|---|---|---|
SENS_EN_BATT=1 | batt_smbus | SMBus 智能电池 |
SENS_EN_LL40LS=1 | ll40ls_pwm | PWM 接口 Lidar-Lite |
SENS_EN_LL40LS=2 | ll40ls | I2C 接口 Lidar-Lite |
SENS_EN_MPDT=1 | mappydot | I2C |
SENS_EN_MB12XX>0 | mb12xx | I2C 声呐 |
SENS_EN_PGA460>0 | pga460 | UART 声呐 |
SENS_EN_TRANGER>0 | lightware_laser | UART/I2C 激光测距 |
SENS_EN_SF1XX>0 | sf1xx_laser | UART/I2C 激光测距 |
SENS_EN_BMP280=1 | bmp280 | I2C/SPI 气压计 |
SENS_EN_L3GD20=1 | l3gd20 | SPI 陀螺仪 |
SENS_EN_LSM303D=1 | lsm303d | SPI 磁力计 |
GPS_1_CONFIG≠0 | gps | UART GPS |
SENS_EN_THERMAL=1 | heater | IMU 恒温加热 |
5.3 传感器聚合 — sensors start
sensors 模块将多个传感器数据融合为统一的 uORB 主题输出:

6. 第五阶段:状态估计器
由参数决定使用哪个估计器:
# rcS:321-384if param compare -s EKF2_EN 1 ekf2 start & ← 默认: EKF2(推荐)if param compare -s LPE_EN 1 local_position_estimator start ← 备用: LPEif param compare -s ATT_EN 1 attitude_estimator_q start ← 备用: 姿态估计器EKF2 数据流

7. 第六阶段:控制与输出
7.1 PX4IO 协处理器
# rcS:388-420if px4io supported px4io checkcrc ${IOFW} ← 校验固件版本 if CRC 不匹配 px4io update ${IOFW} ← 更新固件 (/etc/extras/px4_io-v2_default.bin) px4io start ← 启动 IO 协处理器PX4IO 负责:PWM 信号生成、RC 输入解析(PPM/SBUS)、安全开关逻辑。
7.2 Commander — 飞行模式状态机
# rcS:466-480commander start ← 启动 Commanderdshot start ← DShot 数字协议pwm_out start ← PWM 输出(非 DShot 时)Commander 处理:
- 飞行模式切换(手动/定高/定点/任务/返航)
- 安全状态机(预解锁 → 已解锁 → 飞行)
- 预飞检(传感器健康度、GPS 锁定数、磁力计一致性)
7.3 输出驱动

8. 第七阶段:多旋翼控制模块详解
源文件: ROMFS/px4fmu_common/init.d/rc.mc_apps
rc.vehicle_setup 根据 VEHICLE_TYPE=mc 加载 rc.mc_apps:
# rc.mc_appscontrol_allocator start ← 控制分配(混控器)mc_rate_control start ← 角速率控制(内环 PID)mc_att_control start ← 姿态控制(外环 PID)mc_hover_thrust_estimator start ← 悬停推力在线估计flight_mode_manager start ← 飞行模式管理mc_pos_control start ← 位置控制land_detector start multicopter ← 着陆检测if MC_AT_EN > 0: mc_autotune_attitude_control start ← 自整定if MC_NN_EN=1: mc_nn_control start ← 神经网络控制if MC_RAPTOR_ENABLE=1: mc_raptor start ← Raptor 竞速控制8.1 控制流水线
从位置设定点到电机输出的完整控制链路:

8.2 关键 uORB 消息流

| uORB 消息 | 发布者 | 订阅者 |
|---|---|---|
sensor_combined | sensors | ekf2, mc_rate_control |
vehicle_attitude | ekf2 | mc_att_control, navigator |
vehicle_local_position | ekf2 | mc_pos_control, navigator |
vehicle_attitude_setpoint | mc_pos_control / flight_mode_manager | mc_att_control |
vehicle_rate_setpoint | mc_att_control | mc_rate_control |
actuator_controls_0 | mc_rate_control | control_allocator |
actuator_motors | control_allocator | dshot / pwm_out |
vehicle_control_mode | commander | 所有控制模块 |
manual_control_setpoint | manual_control | commander, flight_mode_manager |
9. 模块启动机制
9.1 从 ekf2 start 到代码执行

9.2 builtin 表的生成
每个模块的 CMakeLists.txt 中定义:
px4_add_module( MODULE ekf2 ← 模块名(即命令名) MAIN ekf2 ← 入口函数名(生成 ekf2_app_main) SRCS ekf2.cpp ...)编译时对所有模块执行 cmake/px4_add_module.cmake:214:
target_compile_definitions(<img class="wxp-inline-math-image" src="blob:app://obsidian.md/8d9eab40-a4be-4b07-a4d1-976f727020db" alt="公式" />{MAIN}_app_main)所有模块的入口在编译时自动汇总到 board_ioctl.c:48 的 builtin 表中:
FAR const struct builtin_s g_kernel_builtins[] = { #include <NuttX/kernel_builtin/kernel_builtin_list.h> // 自动生成的内容: // {"ekf2", ekf2_app_main, ...}, // {"mc_pos_control", mc_pos_control_app_main, ...}, // ...};9.3 模块生命周期

模块主循环的代码模式:
while (!should_exit()) { orb_subscribe() // 等待新消息 orb_copy() // 读取数据 run_algorithm() // 运行核心算法 orb_publish() // 发布结果 schedule() // 调度下次运行}10. 模块间通信:uORB 消息总线
uORB 是 PX4 的核心进程间通信机制,基于发布/订阅模式。
10.1 工作原理

10.2 关键特性
| 特性 | 说明 |
|---|---|
| 多对多 | 一个发布者 → 多个订阅者;多个发布者 → 单个主题 |
| 零拷贝 | 订阅者获取的是共享内存的引用 |
| 实时性 | 发布立即生效,无队列延迟 |
| 自描述 | 所有消息通过 .msg 文件定义 |
| 跨平台 | NuttX/Posix 共用同一套接口 |
10.3 消息定义示例
消息在 msg/ 目录下以 .msg 文件定义:
# msg/vehicle_attitude.msguint64 timestamp # 时间戳float32[4] q # 姿态四元数float32[4] delta_q_reset # 重置时的四元数增量uint8 quat_reset_counter # 重置计数器11. 相关源文件索引
板级文件
| 文件 | 作用 |
|---|---|
boards/px4/fmu-v6c/default.px4board | 板级构建配置 |
boards/px4/fmu-v6c/src/init.c | 板级硬件初始化 |
boards/px4/fmu-v6c/src/board_config.h | 板级硬件定义(GPIO、ADC、I2C等) |
boards/px4/fmu-v6c/src/hw_config.h | Bootloader 硬件配置 |
boards/px4/fmu-v6c/src/CMakeLists.txt | 板级源文件编译 |
boards/px4/fmu-v6c/init/rc.board_defaults | 板级默认参数 |
boards/px4/fmu-v6c/init/rc.board_sensors | 板级传感器启动 |
boards/px4/fmu-v6c/extras/px4_io-v2_default.bin | IO 协处理器固件 |
ROMFS 启动脚本
| 文件 | 作用 |
|---|---|
ROMFS/px4fmu_common/init.d/rcS | 主启动脚本 |
ROMFS/px4fmu_common/init.d/rc.mc_defaults | 多旋翼默认参数 |
ROMFS/px4fmu_common/init.d/rc.mc_apps | 多旋翼控制模块启动 |
ROMFS/px4fmu_common/init.d/rc.vehicle_setup | 飞行器类型分支 |
ROMFS/px4fmu_common/init.d/rc.sensors | 通用传感器启动 |
ROMFS/px4fmu_common/init.d/rc.autostart | 自动生成:空气框架选择 |
ROMFS/px4fmu_common/init.d/airframes/4001_quad_x | 四旋翼 X 型配置 |
ROMFS/px4fmu_common/init.d/airframes/4014_s500 | S500 机架配置 |
ROMFS/CMakeLists.txt | ROMFS 编译处理 |
NuttX 平台文件
| 文件 | 作用 |
|---|---|
platforms/nuttx/CMakeLists.txt | NuttX 固件链接与 ROMFS 嵌入 |
platforms/nuttx/cmake/px4_impl_os.cmake | NuttX 平台编译标志 |
platforms/nuttx/src/px4/common/board_ioctl.c | 模块启动(builtin 表) |
boards/px4/fmu-v6c/nuttx-config/nsh/defconfig | NuttX 内核配置 |
CMake 构建系统
| 文件 | 作用 |
|---|---|
CMakeLists.txt | 顶层 CMake:模块遍历与编译 |
cmake/px4_config.cmake | CONFIG 解析,匹配 .px4board |
cmake/kconfig.cmake | Kconfig 处理,生成模块列表 |
cmake/px4_add_module.cmake | 模块注册与 builtin 号生成 |
关键控制模块
| 模块 | 源码路径 | 功能 |
|---|---|---|
| sensors | src/modules/sensors/ | 传感器聚合 |
| ekf2 | src/modules/ekf2/ | EKF2 状态估计 |
| commander | src/modules/commander/ | 飞行模式状态机 |
| control_allocator | src/modules/control_allocator/ | 控制分配(混控) |
| mc_rate_control | src/modules/mc_rate_control/ | 角速率 PID |
| mc_att_control | src/modules/mc_att_control/ | 姿态控制 |
| mc_pos_control | src/modules/mc_pos_control/ | 位置控制 |
| flight_mode_manager | src/modules/flight_mode_manager/ | 飞行模式管理 |
| navigator | src/modules/navigator/ | 导航与任务执行 |
| logger | src/modules/logger/ | 飞行日志 |
| land_detector | src/modules/land_detector/ | 着陆检测 |
| dshot | src/drivers/dshot/ | DShot 协议输出 |
文档信息
目标平台: PX4 FMUv6C (STM32H743IIK6, NuttX)
机型: 四旋翼 X 型 (Airframe 4001)
对应代码: PX4-Autopilot main 分支
夜雨聆风