1. Betaflight 概述与架构
Betaflight 是一款专为无人机设计的开源飞控软件,基于 Cleanflight 和 Baseflight 发展而来,提供了强大的飞行控制和配置功能。其代码架构主要分为以下几个核心模块:
-
硬件抽象层 (HAL):
- 提供底层硬件驱动接口
- 支持多种 MCU 平台 (STM32 系列为主)
- 包含 GPIO、SPI、I2C、UART、ADC 等驱动
-
传感器处理层:
- IMU (加速度计 / 陀螺仪) 数据采集与处理
- 气压计高度测量
- 罗盘航向测量
- GPS 定位数据处理
-
飞行控制层:
- 姿态估计 (DCM/Mahony/Madgwick 算法)
- PID 控制器实现
- 飞行模式管理
- 电机输出控制
-
用户接口层:
- CLI 命令行界面
- 配置参数管理
- OSD (On-Screen Display) 系统
- 黑匣子日志记录
-
通信层:
- 接收机协议支持 (SBUS、PPM、DSM 等)
- 遥测协议支持 (Mavlink、FrSky 等)
- 串口通信
- WiFi/Bluetooth 支持
2. Betaflight 任务调度系统
Betaflight 采用基于时间片的任务调度系统,将不同功能划分为多个独立任务,每个任务有固定的执行周期和优先级。这种设计使得系统能够高效处理实时性要求不同的各种任务。
2.1 任务分类与优先级
Betaflight 中的任务主要分为以下几类:
-
高优先级任务:
- 传感器数据采集
- 姿态估计更新
- 电机输出更新
- 这些任务需要在短时间内完成,以保证飞行控制的实时性
-
中等优先级任务:
- 飞行模式逻辑处理
- PID 控制器计算
- 接收机信号处理
- 这些任务需要定期执行,但对时间精度要求稍低
-
低优先级任务:
- 通信协议处理
- OSD 显示更新
- 黑匣子日志记录
- 用户接口处理
- 这些任务对实时性要求较低,可以在系统负载较小时执行
2.2 任务调度实现
Betaflight 的任务调度核心代码位于src/main/scheduler
目录下,主要由以下几个部分组成:
c运行
// 任务定义结构体
typedef struct taskDescriptor_s {
taskFuncPtr_t function; // 任务函数指针
uint32_t rate_hz; // 任务执行频率(Hz)
uint32_t interval_ticks; // 任务执行间隔(系统时钟 ticks)
uint32_t last_run; // 上次执行时间
uint32_t execution_time; // 任务执行时间统计
uint32_t execution_time_max; // 任务最大执行时间统计
uint8_t priority; // 任务优先级
bool enabled; // 任务是否启用
const char *name; // 任务名称(用于调试)
} taskDescriptor_t;
// 系统任务列表
static taskDescriptor_t taskDescriptors[TASK_MAX] = {
// 定义各个任务
[TASK_MOTORS_OUTPUT] = {
.function = motorsOutputTask,
.rate_hz = 400,
.interval_ticks = 2500, // 2.5ms @ 1MHz
.priority = 1,
.enabled = true,
.name = "MOTORS"
},
[TASK_SENSOR_READ] = {
.function = sensorReadTask,
.rate_hz = 800,
.interval_ticks = 1250, // 1.25ms @ 1MHz
.priority = 2,
.enabled = true,
.name = "SENSOR"
},
[TASK_ATTITUDE_ESTIMATION] = {
.function = attitudeEstimationTask,
.rate_hz = 400,
.interval_ticks = 2500, // 2.5ms @ 1MHz
.priority = 2,
.enabled = true,
.name = "ATTITUDE"
},
[TASK_PID_CONTROL] = {
.function = pidControlTask,
.rate_hz = 400,
.interval_ticks = 2500, // 2.5ms @ 1MHz
.priority = 1,
.enabled = true,
.name = "PID"
},
[TASK_OSD_UPDATE] = {
.function = osdUpdateTask,
.rate_hz = 50,
.interval_ticks = 20000, // 20ms @ 1MHz
.priority = 3,
.enabled = true,
.name = "OSD"
},
// 其他任务...
};
// 任务调度主循环
void schedulerTask(void)
{
uint32_t currentTime = micros();
uint32_t nextWakeTime = UINT32_MAX;
// 遍历所有任务
for (int i = 0; i < TASK_MAX; i++) {
taskDescriptor_t *task = &taskDescriptors[i];
// 检查任务是否启用且是否到执行时间
if (task->enabled && (currentTime - task->last_run >= task->interval_ticks)) {
// 记录任务执行开始时间
uint32_t taskStartTime = micros();
// 执行任务
task->function();
// 计算任务执行时间
uint32_t executionTime = micros() - taskStartTime;
task->execution_time = executionTime;
// 更新最大执行时间统计
if (executionTime > task->execution_time_max) {
task->execution_time_max = executionTime;
}