第一章:PX4与UART概述
大家好,我是你们的老朋友。今天咱们开始聊PX4驱动开发,第一站就是UART。
说实话,UART这个接口,在嵌入式领域太常见了。我做了这么多年飞控开发,几乎每个项目都离不开它。你想想看,飞控要和GPS模块通信、要和遥控器接收机对接、还要和地面站传数据……这些活儿,大部分都是UART干的。
1.1 PX4是什么?
PX4,说白了就是一个开源的飞行控制软件栈。它跑在硬件上,负责把传感器数据读进来,算一算姿态,然后输出控制信号给电机。
我个人习惯把PX4理解成一个“实时操作系统 + 飞控中间件 + 应用层”的集合体。它基于NuttX这个RTOS,上层跑着各种模块——传感器驱动、位置估计、导航控制等等。
嗯,这里要注意:PX4不是一套固定的硬件方案。你可以用Pixhawk,也可以用自己画的板子。只要你的MCU能跑NuttX,理论上都能移植PX4。
1.2 UART通信协议基础
UART,全称是Universal Asynchronous Receiver/Transmitter。名字挺长,但原理很简单。
说白了就是两根线:
- TXD:发送数据
- RXD:接收数据
再加上一根GND,就能通信了。注意,是交叉连接——你的TXD接对方的RXD,反之亦然。
UART是异步的,没有时钟线。那怎么同步呢?靠的是波特率。双方约定好同一个速率,比如115200bps,然后按这个节奏采样电平。
数据帧格式长这样:
- 起始位:1位,低电平
- 数据位:5~9位,常用8位
- 校验位:可选,奇校验或偶校验
- 停止位:1位或2位,高电平
我在项目中遇到过一个问题:两个设备波特率都设成了115200,但通信就是乱码。查了半天,发现是停止位设置不一致——一个用1位,一个用2位。这种坑,你想想看,多隐蔽。
核心要点:UART通信双方必须完全一致——波特率、数据位、校验位、停止位,一个都不能错。
1.3 PX4中UART的应用场景
在PX4里,UART几乎无处不在。我列几个最常见的场景:
| 场景 | 典型设备 | 波特率 | 备注 |
|---|---|---|---|
| GPS模块 | u-blox M8N, NEO-M9N | 38400 / 115200 | NMEA或UBX协议 |
| 遥控器接收机 | SBUS, DSM, CRSF | 100000 / 115200 | 注意SBUS是反相电平 |
| 数传模块 | HolyBro SiK, 3DR Radio | 57600 / 115200 | MAVLink协议 |
| 外部传感器 | 激光雷达、光流模块 | 115200 / 921600 | 视具体协议而定 |
| 调试串口 | USB转串口工具 | 115200 | 用于nsh shell或日志输出 |
你看,从定位到遥控,从通信到调试,全是UART的活儿。所以我说,搞PX4驱动开发,UART是基本功。
我的经验:刚开始学PX4时,我建议先从调试串口入手。把nsh shell跑起来,能敲命令了,后面的事情就好办了。
1.4 PX4的UART架构概览
在PX4里,UART驱动不是直接操作寄存器的。它分了好几层:
- 硬件层:MCU的UART外设,负责收发字节
- 驱动层:NuttX的串口驱动,提供open/read/write/ioctl接口
- 抽象层:PX4的uORB消息机制,把数据包装成主题
- 应用层:GPS驱动、RC驱动等,订阅/发布uORB消息
说白了,底层是NuttX在管硬件,上层是PX4在管数据。中间通过字符设备文件(比如/dev/ttyS1)来衔接。
我曾经踩过一个坑:在应用层直接操作寄存器,结果和NuttX驱动冲突了,系统直接死机。后来学乖了,老老实实走标准接口。
下面这张图,是我画的PX4 UART驱动整体框架。你看一眼,心里就有数了。
这张图你看懂了吗?数据从硬件收上来,经过NuttX驱动变成字符流,再通过uORB消息机制分发给各个应用模块。反过来,应用层要发数据,也是走这个路径,方向相反。
避坑指南:我曾经在配置UART时,直接用了默认的DMA设置,结果发现GPS数据老是丢包。后来查手册才知道,某些STM32型号的UART DMA有buffer对齐要求。所以,别盲目相信默认配置,一定要看芯片参考手册。
1.5 本章小结
好了,第一章就聊这么多。我们理清了几个关键点:
- PX4是一个基于NuttRTOS的飞控软件栈
- UART是异步串行通信,靠波特率同步
- PX4里UART用在GPS、RC、数传、调试等场景
- 驱动架构分四层:硬件→NuttX驱动→字符设备→uORB→应用
下一章,我们会深入NuttX的串口驱动框架,看看底层到底是怎么工作的。到时候我会拿一个实际案例,手把手带你分析代码。