协处理器与IO处理器:STM32F1的“第二大脑”

聊到Pixhawk的架构,很多人第一反应就是主控芯片有多强。但说实话,真正让Pixhawk在工业级和科研领域站稳脚跟的,反而是那个看起来“不起眼”的协处理器——STM32F1系列。

我刚开始接触Pixhawk时,也纳闷过:为什么非要塞两颗芯片?主控都那么强了,不够用吗?后来在一次飞控调试中,主控因为内存溢出直接死机,但无人机居然还能保持姿态稳定、缓缓降落。那一刻我才真正明白——这颗协处理器,就是飞控的“最后一道防线”。

STM32F1:不是配角,是“保险丝”

在FMUv2及之后的架构中,STM32F1的角色非常明确:IO协处理器 + 故障安全协处理器。它不负责复杂的导航算法,也不处理传感器融合。它的任务就两个:

  • 接管IO控制:处理PWM输出、RC输入、舵机信号等实时性要求高的外设
  • 监控主控状态:一旦发现主控“失联”或异常,立刻接管控制权

说白了,主控是大脑,负责思考;STM32F1是脊髓反射中枢,负责本能反应。你想想看,如果大脑宕机了,身体还能不能动?在无人机上,这个“本能反应”就是保命的关键。

核心设计思路:将高实时性、低复杂度的IO任务从主控剥离,交给专用协处理器。主控专注于算法,协处理器专注于可靠执行。

硬件看门狗机制:不是“重启”,是“移交”

传统的看门狗,就是定时器超时后直接复位系统。但在Pixhawk里,这个机制被玩出了新花样。

STM32F1内部有一个独立的硬件看门狗(IWDG),它不依赖主控的时钟。主控需要定期通过SPI或CAN向STM32F1发送“心跳包”。如果STM32F1在预设时间内没收到心跳,它会认为主控已经“挂掉”了。

这时候,STM32F1不会傻傻地复位整个系统。它会:

  1. 记录故障状态:把主控失联的时间、当前姿态、传感器数据存下来
  2. 切换控制源:将PWM输出切换到预设的故障安全值(比如油门归零、舵面回中)
  3. 尝试恢复通信:持续发送复位信号给主控,如果主控恢复,再平滑交还控制权

我曾经在测试中故意让主控跑飞,结果STM32F1在50毫秒内就完成了切换。无人机只是轻微晃动了一下,然后稳稳悬停。嗯,这个设计,真的救过我的项目。

个人经验:在配置硬件看门狗时,心跳超时时间别设太短。我建议设在200-500ms之间。太短容易误触发,太长又失去保护意义。另外,记得在STM32F1的固件里加上“去抖”逻辑——连续3次心跳丢失才触发切换,避免偶发通信干扰导致误动作。

IO协处理器的具体分工

STM32F1在Pixhawk里具体管哪些事?我列个表,你一看就明白:

功能模块 主控(STM32F4/F7/H7) 协处理器(STM32F1)
PWM输出 生成控制指令(如油门值) 解析指令并生成精确PWM波形
RC输入 读取遥控器通道值 捕获PPM/SBUS信号并转发给主控
故障安全 监控自身状态 独立监控主控心跳
外设接口 连接传感器、GPS等 连接舵机、LED、蜂鸣器等
固件更新 通过USB/SD卡更新 通过主控间接更新

看到没?协处理器管的都是“手和脚”的活。主控只管“想”,协处理器只管“做”。这种分工在工业控制领域非常常见,说白了就是“让专业的人干专业的事”。

FMUv2+架构中的协处理器演进

从FMUv2开始,协处理器的地位越来越重要。我记得FMUv2刚出来时,很多人觉得STM32F1性能太弱,跑个PWM输出都费劲。但实际用下来才发现,人家根本不需要跑复杂逻辑——它只需要稳定、可靠、低延迟。

到了FMUv3和v4,协处理器的固件也一直在优化。比如:

  • 增加了CAN接口支持:让协处理器可以直接与电调通信
  • 优化了心跳协议:从简单的“ping-pong”改成了带状态码的“健康报告”
  • 加入了安全降落逻辑:主控失联后,协处理器可以执行预设的“返航”或“降落”动作

这里有个坑,我得提醒你:协处理器的固件版本必须与主控固件匹配。我曾经因为升级了主控固件但忘了更新协处理器,结果心跳协议不兼容,飞控一上电就报“协处理器故障”。折腾了两天才找到原因。

避坑指南:在更新Pixhawk固件时,记得同时更新协处理器固件。具体操作是:先刷主控固件,然后通过Mission Planner或QGroundControl的“更新协处理器”功能,刷入对应版本的STM32F1固件。别偷懒,否则飞着飞着突然失控,那可不是闹着玩的。

硬件看门狗的代码实现思路

虽然我们不需要手写Pixhawk的协处理器固件,但理解它的实现逻辑,对调试和二次开发很有帮助。下面是一个简化的看门狗心跳检测代码示例:

// STM32F1协处理器端的心跳检测
void Watchdog_CheckHeartbeat(void) {
    static uint32_t lastHeartbeatTime = 0;
    uint32_t currentTime = HAL_GetTick();
    
    // 检查是否收到主控的心跳包
    if (heartbeatReceived) {
        lastHeartbeatTime = currentTime;
        heartbeatReceived = false;
        // 正常状态,继续执行
        return;
    }
    
    // 计算距离上次心跳的时间
    uint32_t elapsed = currentTime - lastHeartbeatTime;
    
    // 如果超过500ms没收到心跳,触发故障安全
    if (elapsed > 500) {
        // 记录故障
        faultLog.faultType = FAULT_MAIN_HEARTBEAT_LOST;
        faultLog.timestamp = currentTime;
        
        // 切换到故障安全模式
        EnterFailsafeMode();
        
        // 尝试复位主控
        HAL_GPIO_WritePin(MAIN_RESET_GPIO_Port, MAIN_RESET_Pin, GPIO_PIN_RESET);
        HAL_Delay(100);
        HAL_GPIO_WritePin(MAIN_RESET_GPIO_Port, MAIN_RESET_Pin, GPIO_PIN_SET);
    }
}

这段代码看着简单,但实际项目中要考虑的细节很多。比如:

  • 心跳包要带CRC校验,防止数据被干扰
  • 故障安全模式要预设好PWM输出值,不能直接归零(否则无人机自由落体)
  • 复位主控后,要等待主控重新初始化完成,再交还控制权

我个人习惯在故障安全模式里加一个“渐变”逻辑:不是瞬间切换PWM值,而是在100ms内平滑过渡。这样即使切换发生,无人机也不会出现剧烈抖动。

总结一下

STM32F1作为协处理器,在Pixhawk架构里扮演着“守护者”的角色。它不追求性能,只追求可靠。硬件看门狗机制也不是简单的“死机重启”,而是一套完整的故障检测、切换、恢复流程。

你想想看,如果无人机在空中突然主控死机,协处理器能立刻接管,让飞机安全降落——这个设计,值不值得你花时间深入理解?

下一章,我们会聊聊Pixhawk的传感器架构,看看那些IMU、磁力计、气压计是怎么协同工作的。到时候我会分享一个我在高海拔地区调试气压计的真实案例,保证让你有收获。