PX4学习笔记(二)从芯片复位 → px4_main 完整启动时序(文字流程图)
总链路分段
硬件复位 → start.S 汇编初始化 → stm32_start () 芯片 C 底层初始化 → os_start () NuttX 内核完整初始化 → NSH 控制台启动 → 挂载 ROMFS 并执行 rcS 启动脚本 → 调用 px4_main.c
阶段 1:硬件上电 / 看门狗 / 软件复位(硬件层,无代码)
- MCU 复位,CPU PC 指针强制指向 Flash 起始地址 0x08000000
- 硬件自动读取向量表前两个字:
- 0x00:主堆栈 MSP 初始栈顶地址
- 0x04:复位中断服务程序 Reset_Handler 入口地址
- CPU 跳转 Reset_Handler,进入
nuttx/arch/arm/armv7-m/start.S
阶段 2:start.S 汇编初始化(纯汇编,无 C 运行环境)
文件路径:nuttx/arch/arm/armv7-m/start.S
cpsid i关闭全局中断,防止初始化阶段外设中断干扰- 加载向量表预设值,初始化 MSP 主堆栈(中断 / 复位专用栈)
- 判断复位来源(冷上电 /bootloader 跳转),决定是否完整初始化 RAM
- 清零
.bss段:循环把 RAM 未初始化全局变量区全部置 0 - 拷贝
.data段:将 Flash 中已初始化全局变量复制到 RAM - 可选配置双堆栈 MSP/PSP,区分中断栈与任务栈
- 跳转至芯片 C 初始化函数
stm32_start()
本阶段仅搭建 C 语言运行环境,不操作任何外设、不配置时钟
阶段 3:stm32_start.c STM32 芯片底层初始化
文件路径:nuttx/arch/arm/src/stm32/stm32_start.c
- RCC 复位全部外设,外设寄存器恢复出厂默认
- 配置外部晶振 HSE / 内部 HSI,配置 PLL 倍频,设置 SYSCLK、AHB、APB 分频(系统主频)
- 开启 Cortex-M FPU 浮点单元(CPACR 寄存器),为姿态解算提供硬件浮点
- 开启 Flash 预取缓冲、指令缓存,提升 Flash 代码运行速度
- 初始化 SysTick 滴答定时器,提供内核调度时基
- 划分 RAM 空闲区域,初始化系统堆(malloc/free 底层内存池)
- 调用
board_early_initialize()板级早期初始化- 路径:
boards/xxx/xxx/src/board_init.c - 功能:基础 LED、电源使能引脚、PMIC 预上电、传感器供电开关初始化
- 路径:
- 全部硬件底层就绪,调用 NuttX 操作系统入口:
os_start()
阶段 4:os_start () NuttX 内核全量初始化
文件路径:nuttx/sched/os_start.c
- 初始化内核全局状态、TCB 任务控制块链表
- 同步机制初始化:信号量、互斥锁、条件变量、POSIX 消息队列
- 中断子系统 irq 初始化,注册硬件中断向量、中断优先级分组
- 内存管理 mm 初始化:任务静态栈管理、堆内存分配器
- VFS 虚拟文件系统初始化:挂载设备节点、初始化 CDev 字符设备框架
- 初始化块设备驱动框架(SD/FRAM 等存储外设底层接口)
- 创建系统空闲 IDLE 任务(最低优先级,无其他任务时运行)
- 开启全局中断
cpsie i,启动抢占式优先级调度器 - 调度器切换至 IDLE 任务,NuttX RTOS 正式运行
阶段 5:NuttX 自动启动 NSH Shell 任务
- os_start 完成调度后,内核自动运行第一个用户任务:NSH 控制台
- NSH 初始化串口控制台、标准输入输出 stdout/stderr
- NSH 自动挂载内置 ROMFS 文件系统(固件内置只读文件系统)
- 对应资源:
ROMFS/px4fmu_common/
- 对应资源:
- NSH 执行启动脚本
rcS,路径/etc/init.d/rcS
阶段 6:rcS 启动脚本(PX4 业务入口前置)
文件路径:ROMFS/px4fmu_common/init.d/rcS
- 配置系统环境变量、日志目录、参数存储分区
- 初始化高精度 hrt 定时器、挂载 FRAM/SD 卡文件系统
- 执行核心入口命令:
px4_main - 脚本调用平台层入口函数,进入 PX4 专属业务层
阶段 7:px4_main PX4 飞控框架主入口
文件路径:platforms/nuttx/px4_main.c
- 初始化 PX4 平台封装层(封装 NuttX 原生系统调用)
- 初始化 uORB 消息总线、参数管理模块
- 依次加载所有板载外设驱动(IMU、GPS、PWM、RC 输入等)
- 启动 WorkQueue 高低优先级任务线程池
- 启动飞控核心业务任务:commander、姿态估计、姿态控制、mavlink 通信等
极简纵向时序总览(快速记忆)
复位 → start.S(栈 + bss/data 初始化)→ stm32_start(时钟 / FPU / 板级早初始化) → os_start(NuttX 内核、调度、中断、VFS 初始化)→ NSH 启动 → 挂载 ROMFS 执行 rcS 脚本 → 调用 px4_main.c
关键分界标记
- start.S ↔ stm32_start:汇编结束,进入芯片硬件时钟配置
- stm32_start ↔ os_start:裸机硬件初始化完成,进入 RTOS 操作系统
- os_start ↔ NSH:内核调度器启动,拥有多任务能力
- NSH+rcS ↔ px4_main:通用 NuttX 系统结束,进入 PX4 飞控专属底层框架
