1. 从一次无人机坠机谈谈"硬实时"被误解的那些事
先讲个真实案例。前几年我参与过一个工业级无人机的飞控选型评估,团队里一位刚从嵌入式培训学校出来的同事,坚持认为只要在STM32H7上跑一个带抢占式调度的FreeRTOS、把任务优先级配好,系统就是"硬实时"了。他甚至在方案评审会上说:"中断延迟我测过,最坏情况也就3微秒,这还不够硬吗?"
我当时没直接反驳,而是让他把在最高优先级任务里加一个长时间的浮点运算、同时开启Cache、再挂一个DMA搬运任务,看看中断响应时间会变成多少。结果测出来的最坏延迟从3微秒直接彪到400多微秒。大家对这个数字可能没有直观概念——对于一架时速100公里的穿越机,400微秒意味着它在空间上已经多走了约1.1厘米,如果这是一次需要精确到毫米级的视觉定位修正,姿态已经偏了。
这个案例很好地引出了本文的核心问题:飞控计算机里所谓的"硬实时"和"软实时",差的远远不止一个延迟数字。很多人在做飞控系统设计时,把实时性当成一个"快慢问题"来理解,但实际上它本质上是确定性(determinism)问题。
这篇文章我打算从飞控计算机的实际使用场景出发,把硬实时与软实时在调度模型、失败后果、系统架构、验证方法上的差异全部拆开讲透,最后给出我在实际工程中采用的混合设计思路和配置参考。内容比较长,但每一节都是能直接落到代码和配置上的干货。
适合的读者包括:正在做飞控系统选型的嵌入式工程师、无人机的开源飞控二次开发者、对实时操作系统有基础认知但想深入理解"确定性"内涵的研究生,以及准备把普通的Linux板卡引入飞控架构但心存疑虑的架构师。
2. 硬实时与软实时的分水岭:不是"快"而是"可证明"
在进入飞控计算机的细节之前,必须先把概念层面的东西掰清楚。很多介绍实时系统的文章会把硬实时定义为"响应时间必须在一个明确的截止时间(deadline)之前完成",这本身没错,但在工程实践里这句话实在太容易被误读。
我用一个通俗类比来解释:假设你是一个餐厅厨师,软实时的要求是"顾客饿了就赶紧上菜,最好在10分钟内,但偶尔15分钟也能接受";硬实时的要求是"这道菜必须在12点整出锅,因为包间里的客人要在12点整给领导敬酒,晚一秒钟这桌饭就砸了"。看出来了吗?软实时在乎的是平均体验,硬实时在乎的是最坏情况的保证。
把这个类比翻译成飞控系统的语言:
硬实时(Hard Real-Time):飞控计算机必须保证所有高优先级控制任务在确定的最坏执行时间(WCET,Worst-Case Execution Time)内完成,这个上界不是靠"大概率"保证的,而是通过程序分析、硬件特性和调度算法计算出来的。一旦超时,后果是物理性的——姿态失控、飞机坠毁。
软实时(Soft Real-Time):系统允许偶尔错过截止时间,只要任务在统计意义上能够及时完成。比如飞控里的遥测数据记录任务,偶尔晚几十毫秒写入SD卡,顶多丢一帧日志,不影响飞行安全。
这里有个关键的教训:不能以"延迟多小"来区分硬实时和软实时。一个系统即使平均延迟只有1微秒,如果最坏情况下可能被某个高阶中断、Cache Miss或者总线竞争拖到几十毫秒,它依然不是硬实时的。反过来,一个系统的平均延迟有50微秒,但通过时间触发调度(Time-Triggered)精确锁定了最坏执行时间,那它在飞控里就是硬实时的。
这也就是为什么我在评估飞控实时性的时候,从来没有把"跑得多快"放在第一位,而是先去问一个问题:最坏情况你有没有算过?用的是测量法(testing-based)还是静态分析法(static analysis)?
测量法,就是写一个测试程序反复触发中断看最大延迟。这种方法的问题是,它只能覆盖到你触发的那些场景,Cache状态、总线仲裁优先级、DMA占用的组合数量几乎是无限的,你测到的不是上界,只是"到目前为止见过的最大值"。静态分析法则会结合指令集模拟、Cache行为建模、调度分析得出一个数学上的上界,可靠得多,但分析过程复杂,对处理器硬件的细节要求高。飞控里但凡涉及安全级的任务(尤其是姿态控制和电机输出),我都要求采用静态分析结果作为截止时间设计的依据。
飞控系统中的典型硬实时任务包括:
- 姿态解算:以固定频率(如1kHz)读取IMU数据并解算姿态
- 控制律计算:根据姿态误差计算电机控制量
- 电机PWM输出:必须在严格相位对齐的时间点更新占空比
- 传感器数据采集的触发时刻:IMU的采样时刻和控制律计算时刻之间的延迟必须恒定
典型的软实时任务则包括:
- 遥测数据下行
- 黑匣子日志记录
- 地面站图像传输
- 航线规划和重规划(非紧急情况下)
在飞控计算机的设计中,硬实时任务是"驾驶舱",软实时任务是"客厅"。驾驶舱里每一个操作都有硬性的时间约束,客厅里即便偶尔拖延也不致命。
3. 飞控调度架构的深层差异:时间触发 vs 事件紧急触发
确定了概念,下一步是看硬实时和软实时在飞控系统调度架构上的具体体现。这个差异,比大多数嵌入式开发者以为的要大得多。
3.1 硬实时的经典范式:时间触发调度
航天和航空飞控领域最经典的硬实时范式是时间触发调度(Time-Triggered,TT),代表是TTEthernet(Time-Triggered Ethernet)和TTP(Time-Triggered Protocol)。时间触发的核心思想是:所有任务和消息的启动时刻,在离线设计阶段就被精确排定在了一个周期性的调度表里。
类比一下,时间触发就像交响乐团的指挥:每一个乐手在哪个小节进入,早就在乐谱上写死了,乐团不会因为"某个乐手状态好就提前演奏"。每个任务在固定的相位开始执行,在下一个固定的相位之前完成。这带来两个巨大的好处:
可确定性:因为调度表是固定的,不需要运行时的任务优先级仲裁,任务之间没有竞争关系。CPU在每个时间点执行什么,都是预先知道的。这让最坏情况分析变得非常可行——你只需要分析每个任务的WCET,再排进调度表,后面的事就是机械性的。
相位同步:传感器采集、控制律计算、执行器输出的时间相位是精确对齐的。比如IMU在t=0时刻采样,控制律在t=0.4ms时刻开始计算,PWM在t=0.8ms时刻刷新,三者之间延迟恒定,控制环路的相位裕度不会因为调度抖动而恶化。
在飞控领域,这个范式的好处怎么强调都不为过。飞行控制的稳定性依赖于系统的延迟模型。如果控制任务的调度抖动过大(jitter),在频域上就相当于引入了不确定的相位噪声,会吃掉控制器的相位裕度,严重的会引起高频振荡甚至发散。
飞控计算机中的时间触发调度的实现通常不依赖普通RTOS的优先级抢占,而是依赖静态调度表:一个循环任务表,系统按固定的时间步进(如1kHz对应的1ms周期)依次执行。调度表中的每个任务都要保证在分配给它的时间窗口内完成,如果某个任务超时了怎么办?一般有看门狗策略:硬件看门狗强制复位,或者切换到冗余通道。
3.2 软实时的典型范式:优先级抢占 + 事件驱动
软实时系统的代表是通用RTOS上常见的**优先级抢占调度(Preemptive Priority Scheduling)**加上事件驱动模型。FreeRTOS、RT-Thread、主流的VxWorks、以及带PREEMPT_RT补丁的Linux,都属于这种范式。
这种模型里,系统不是一个静态的表,而是一组等待事件的线程/任务。事件来了(比如姿态传感器数据就绪),调度器根据优先级决定谁先运行。高优先级任务可以抢占低优先级任务。
这种模型灵活性强,适合处理突发性的事件(比如遥控器信号丢失需要触发返航逻辑),但代价是运行时的调度决策引入了不确定的排队延迟、上下文切换开销、优先级翻转概率。用数学语言说,这类调度的最坏情况响应时间分析,需要把所有高优先级任务的最坏执行时间、资源锁等待时间叠加起来,而且还要考虑中断和DMA这些"隐藏的高优先级执行者"。
我之前在一个飞控项目里就踩过优先级翻转的坑:遥测DMA中断、姿态控制任务、以及对一个共享CAN外设的互斥访问之间形成了经典的优先级翻转链,导致姿态任务在毫秒级周期里偶尔被拖慢了1微秒。用逻辑分析仪抓了三天才找到原因,后来把互斥锁改成了无锁环形缓冲才解决。
3.3 飞控里最常见的混合架构
实际工程里,很少有飞控计算机是纯时间触发或者纯事件驱动的。以我参与过的某款双余度飞控为例,架构是这样的:
- 内回路(姿态/角速率环):时间触发。IMU数据通过DMA以1kHz频率写入双缓冲,由一个定时器在固定相位唤醒控制任务,任务使用无锁数据访问,执行完在固定时刻刷新PWM。
- 外回路(位置/速度环):优先级抢占+事件驱动。订阅IMU数据和GPS数据,融合后更新位置环路,对时间要求相对宽松,甚至在GPS信号丢失时只需要保持"不崩"即可。
- 决策层(故障处理、模式切换):事件驱动,但通过独立的监控任务(watchdog任务)兜底。模式切换的延迟允许有几十毫秒级别的非确定性,但切换动作本身是受状态机约束的,不会因为延迟造成控制律发散。
这种混合架构的本质是:硬实时任务放在一个被严格隔离的"确定性岛"内,软实时任务在这个岛之外自由竞争。隔离不是概念层面的,而是通过物理手段(如独立的CPU核、独立的DMA通道、内存隔离、时间窗口隔离)做出来的。
4. 失败后果与系统设计取向:一个错误导致的物理灾难边界
硬实时和软实时最根本的差异,不在调度技术,而在失败后的物理后果。这是飞控领域判断"要不要用硬实时"的最高标准。
4.1 硬实时任务的失败模式
硬实时任务错过截止时间的后果通常是灾难性的。飞控里的典型例子:
- 姿态控制任务在某个控制周期内没有完成计算,导致控制输出保持上一周期的指令。如果下一个周期恢复还可以接受,但如果连续三个周期都没能刷新输出,飞机的姿态会在几毫秒级别内出现不可控偏转。
- 电机PWM信号的刷新时刻偏离了预期相位,导致多个电机的输出力矩在空间上产生交叉耦合,飞行器出现轻微抖动甚至振荡。对于没有充分相位裕度的小型无人机,这种高频振荡通常意味着瞬间失控。
- 传感器采样时刻与控制计算时刻之间的抖动,会导致控制环路的有效采样时间模糊化,在高速机动时引入几度的姿态误差。
这就是为什么硬实时任务在飞控设计中要部署在确定性环境中:它们的时间行为必须严格符合预先的分析模型,哪怕出现一个微小的偏差,后果也是物理性的。
4.2 软实时任务的失败模式
软实时任务错过截止时间的后果通常是非灾难性的,但依然会影响系统性能:
- 遥测数据丢一帧,不影响飞行。
- GPS融合任务被延迟50ms,位置估计精度略微下降,但仍然稳定收敛。
- 日志写入被延迟,可能丢几百条记录,但飞控的实时控制环路不影响。
这个"非灾难性"指的是不会直接导致坠机,但并不是说可以完全忽视。我见过一个因为日志记录任务频繁抢占姿态控制任务,导致姿态控制任务偶尔超时并触发保护机制的炸机案例——一个本身是软实时的任务,如果占用的资源(CPU时间、总线带宽、缓存)干扰了硬实时任务,它实际上变成了系统安全的威胁。所以在飞控系统中处理软实时任务,不能只考虑它自己的截止时间,还要考虑它对硬实时任务的干扰上界。
4.3 余度设计与表决机制中的实时性要求
说到失败后果,不得不展开讲一下飞控里余度设计和表决机制对实时性的影响。这是很多人容易忽略的维度。
在双余度或三余度飞控中,多个飞控通道分别计算姿态和控制量,然后通过**表决器(voter)**选出一个有效的输出。表决的前提是:各个通道的输出必须在时间上可比。如果通道A的输出在t=0时刻生成,而通道B的输出在t=0.5ms时刻生成,表决器需要认为这两个输出对应的是同一个控制周期,否则会把两个周期的控制量混在一起投票,结果是灾难性的。
这要求每个通道的任务调度必须是周期对齐的,最好采用一种称作"本地表决窗口"的机制:每个通道在每个控制周期内,在自己的时间窗口内完成计算,并把输出送到表决器;表决器在窗口结束时统一比较。如果某个通道没有在窗口内完成,它的输出会被标记为无效,而不是参与表决。这个机制下,即使某个通道出现了随机硬件故障导致计算超时,表决器也能正确识别并隔离故障通道。
更深一层,三余度系统还要求交叉通道的数据传输(Cross-Channel Data Transfer,CCDT)具有确定的延迟。假设通道A在t=0时刻采样,通道B在t=0.2ms时刻采样,两条通道之间交换数据后,各自进行表决逻辑。如果信道的传输延迟不确定,表决逻辑就会引入表决延迟,导致每个通道的控制律计算相位不一致。时间触发总线(如TTEthernet)之所以在飞控中备受青睐,恰恰因为它能提供全局时钟同步和确定的消息传输时延,让每个通道的采样、计算、交换、表决都能在全局时基上对齐。
我曾在一个项目里对比过CAN总线和TTEthernet在三余度飞控交叉通道数据传输中的表现。CAN由于事件触发、带冲突检测,在高负载下的数据到达时间抖动很大(几十微秒到上百微秒),做交叉表决时需要额外加时间戳补偿逻辑;TTEthernet则把所有消息时隙化,抖动控制在亚微秒级。最终我们为了保住确认性,果断选择了TTEthernet。代价是硬件成本上升、配置复杂度大幅增加,但在三余度架构里,这一点代价换来的是表决机制的可信度。
5. 系统验证的差异:跑1000次测试通过,不等于硬实时
很多开发者分不清硬实时和软实时,本质上是因为他们不清楚这两种系统在验证方法上的截然不同。软实时系统可以用统计测试来验证——跑一千次,一万次,看延迟分布,只要绝大多数在阈值内,十几个异常点可以当作可接受的偶发事件。硬实时系统则只能靠形式化分析和充分的穷举性测试来验证,统计平均没有意义,你必须证明"最坏情况就是这么长,没有例外"。
以飞控中典型的硬实时任务验证为例,通常至少需要做以下几件事:
最坏执行时间(WCET)分析:
- 使用静态分析工具(如aiT、Otawa)对目标处理器的指令时序进行建模,推导任务代码的理论最大执行时间。
- 结合Cache访问模式分析(LRU/随机替换策略),确定任务在"最冷Cache"时的开销。
- 分析中断嵌套和DMA抢占对CPU周期的贡献。
调度分析:
- 对于时间触发系统,验证静态调度表中所有任务时间窗的可行性和间隔满足要求。
- 对于优先级抢占系统,使用RMA(Rate Monotonic Analysis)的可调度性判定公式:任务集在特定条件下满足
Σ(Ci/Ti) ≤ n(2^(1/n) - 1)才可判定为可调度。一旦涉及阻塞(资源共享),还得引入优先级天花板协议(Priority Ceiling Protocol)的分析模型。
硬件在环(HIL)测试:
- 将飞控计算机接上惯性仿真器、控制对象模型,跑故障注入场景(如某个传感器信号丢失、CAN总线堵塞、CPU主频降级、内存错误注入),观察任务是否都能在最坏时限内完成。
- 重点记录系统的
迟延上界(maximum lateness)、截止时间错失次数(deadline miss count)。
长时间压力测试:
- 不是跑一小时,而是连续72小时以上、在温度循环、振动环境、供电波动下重复运行典型任务和边界任务,捕捉低概率的调度异常。
而软实时系统的验证就简单得多:只需要统计任务响应时间分布,设定一个可容忍的截止时间错失率(比如低于0.1%),然后通过压力测试验证分布稳定即可。
在实际飞控项目的审厂和适航沟通中,经常被问到的问题就是"你怎么证明你的系统是硬实时的?"。如果回答说"我测过很多次,没有超时",评审专家通常会追问:"你测了多少次?覆盖了哪些场景?你如何确定没有覆盖到的场景不会超时?" 而如果回答"我做了WCET分析和RMA可调度性分析,结论是任务集在最坏情况下可在X毫秒内完成",这个说服力就完全不一样了。
这也是为什么在很多航空飞控系统中,我们倾向于使用带有形式化验证工具链的RTOS(如VxWorks 653、PikeOS),而不是开源的FreeRTOS——不是说FreeRTOS实时性不好,而是它缺少完整的WCET分析和调度验证工具链,这让"硬实时"四个字没法从工程上自证。
6. 选型与实现:在飞控ARM处理器上如何为任务配置实时属性
前面讲了这么多概念和架构,这一节我落脚到具体实现:在常见的飞控计算机上(比如NXP i.MX8、STM32H7、或带AMP(Asymmetric Multiprocessing)的异构平台),到底怎么为不同的任务配置实时属性?这里我给出我实际用过的策略。
6.1 明确任务分类表
在设计飞控软件之初,我们就要做一张任务分类表,明确每个任务的实时属性、周期、截止时间、最坏执行时间和允许错失率。这个表早于任何代码编写存在。以下是一个实际案例:
| 任务名称 | 实时属性 | 周期(ms) | 截止时间(ms) | 允许错失率 | 关键性级别 |
|---|---|---|---|---|---|
| IMU采样与姿态解算 | 硬实时 | 1 | 0.5 | 0 | 安全级 |
| 内回路控制律(角速率) | 硬实时 | 1 | 0.8 | 0 | 安全级 |
| 外回路位置控制 | 软实时 | 10 | 10 | 0.5% | 一般级 |
| GPS数据融合 | 软实时 | 10 | 15 | 2% | 一般级 |
| 遥测数据打包发送 | 软实时 | 10 | 50 | 5% | 低关键性 |
| 黑匣子记录 | 软实时 | 100 | 200 | 5% | 低关键性 |
| 故障检测与冗余切换 | 硬实时 | 1 | 0.5 | 0 | 安全级 |
注意这个表格里的截止时间都不是一个周期时间。比如IMU采样的周期是1ms,但截止时间是0.5ms,意味着采样任务必须在半个周期内完成,给剩余的控制律计算留出时间。实际设计时,我会把硬实时任务占用的CPU时间预算控制在总CPU时间的60%以内,留出40%的余量给软实时和其他偶发负载,防止"一个软实时任务突然占用过多CPU把硬实时挤爆了"。
6.2 硬实时任务的设计要点
硬实时任务在设计上有一些可落实的原则,我逐条说:
- 使用静态或伪静态内存分配:不在任务内部使用malloc/free,防止堆碎片导致的分配延迟。飞控的CCM(Core Coupled Memory)或内部SRAM中,为每个硬实时任务预先分配好固定内存块。
- 禁止在硬实时任务内做阻塞性IO:打印日志、访问文件系统这类操作统统移到软实时任务里,硬实时任务只通过无锁环形缓冲区向软实时任务传递数据。
- 使用中断响应而不是轮询:IMU数据就绪时通过硬件中断或DMA完成通知触发任务,避免CPU空转判断状态位。
- 为硬实时任务单独建立中断优先级:在STM32H7的NVIC中,把IMU触发中断放在"组最高优先级",并且关闭组内其他可嵌套中断,保证IMU中断的响应不会被其他外设中断延迟。
- 缓存锁定(Cache Locking):对于时间确定性要求极高的代码和数据段,可以使用硬件提供的Cache锁定功能,把关键代码和常驻数据锁定在Cache里,消除Cache Miss带来的最坏执行时间波动。i.MX8等应用处理器通常支持类似的缓存锁定功能,但配置极其复杂,需要在启动早期进行页表设置和MMU配置。
- 禁用分支预测导致的不确定性:现代处理器中的分支预测器会让同一段代码在不同输入下的执行时间产生巨大差异。在硬实时任务里,尽量减少数据依赖的分支,必要时采用
__builtin_expect或干脆用不回应的短分支,保持执行时间的平坦。
6.3 软实时任务的隔离与约束
软实时任务虽然不需要确定性,但必须接受两类约束:
第一是时间预算约束。所有软实时任务累计的CPU占用率必须留出明确的余量。比如在任务启动时计算周期内的平均CPU占用率,一旦超过预设值(如30%),低优先级的软实时任务将被动态降频或丢弃部分工作。
第二是资源访问约束。软实时任务访问共享外设(比如UART、CAN、SPI)时,不能在持有锁的情况下被硬实时任务多次等待。我的做法是:软实时任务使用"无中断禁止"的互斥机制(如Priority Ceiling),或者干脆把对硬实时任务有影响的外设访问全部放到硬实时任务的周期外执行。
以我最近用i.MX8M Plus做的一版飞控为例,核心配置是:
- 4个Cortex-A53中,1个核跑Linux(负责视觉导航、地面站通信、日志),另外1个核跑带RT-PREEMPT补丁的Linux或裸机RTOS(负责外回路控制、故障处理)。A53核和M7核之间通过共享内存+Mailbox通信,确保数据交换不依赖Linux的实时性。
- M7核上跑时间触发的硬实时任务(姿态解算1kHz + 控制律1kHz + 故障检测1kHz),任务调度表提前排好,使用M7内部TCM(Tightly Coupled Memory)存放关键代码和数据。
- 软实时任务(GPS融合、位置环、遥测打包)在A53核上跑,通过信号量向M7发起非实时请求。
- 关键日志和调试输出通过UART DMA方式输出,不影响实时任务的执行。
这个架构跑下来的实际效果:M7核上姿态解算任务的调度抖动低于1微秒,PWM刷新时刻在全天候运行中保持恒定在0.2微秒以内,A53核上的Linux任务即便高负载也不影响M7核上的硬实时任务执行。这个隔离效果是我用普通单核RTOS无论如何都做不到的。
7. 聊聊那些打着"实时"旗号的RTOS和Linux实时化方案
最后这一节,我从工程经验的角度盘点一下飞控领域常见实时化方案的适用性,帮助大家选型时少走弯路。
7.1 FreeRTOS/RT-Thread:真硬实时吗?
FreeRTOS是优先级抢占式调度,从RTOS内核本身来说,它完全可以用于硬实时任务。难点在于:
- 它本身不提供WCET分析工具,最坏情况由工程师自己推。
- 部分BSP的外设驱动(如TouchGFX、USB、LWIP协议栈)会引入不可控的重负载中断或长临界区,导致硬实时任务的延迟上界不可控。
- 堆内存分配、printf重定向等库函数可能引入不确定延迟。
如果你问我FreeRTOS能不能做飞控的硬实时任务,我的回答是"可以,但要非常克制"。把硬实时任务缩减到极小的关键集合,所有外设访问都封装成固定时间的DMA操作,明确关闭任何可能引入长临界区的功能。这样FreeRTOS可以胜任小型无人机飞控,但代价是需要大量的人工分析。
我在多个开源飞控(比如PX4、ArduPilot)的调度策略中也看到同样的影子:PX4的workqueue模型本质上是优先级抢占,但它把速率最快的姿态控制任务放在独立的高优先级线程中,其他任务放到低优先级workqueue里,这个设计思路跟混合架构的内核逻辑是一样的。
7.2 VxWorks、PikeOS等商用RTOS:硬实时的正统选择
商用RTOS(VxWorks 653、PikeOS)通常带完整的调度分析工具链,支持ARINC 653标准的空间/时间分区隔离,适合航空级飞控。它们提供的技术保障包括:应用之间内存隔离(不是MMU保护那种隔离,而是分区概念),每个分区占用固定的时间窗口,这个窗口单靠RTOS调度器就可以锁定,不依赖硬件Cache锁定。在需要适航认证的飞控项目中,这类RTOS几乎是唯一选项。代价是授权费用高、开发环境封闭、学习曲线陡峭。
7.3 Linux + RT-PREEMPT:是软实时,别当硬实时用
这几年很多飞控尝试用带RT-PREEMPT补丁的Linux跑控制任务。RT-PREEMPT大幅减少了内核的不可抢占区间,在大多数场景下可以把调度延迟压到几十微秒,但是:
- Linux的中断下半部(softirq)、内存管理(页面回收、KSM)、以及文件系统操作,仍然存在非常长的不可阻塞区间。极端情况下(比如内存压力大触发回收),延迟可能达到毫秒级。
- Linux的进程调度不是为硬实时设计的,即使设置SCHED_FIFO,也会有内核功能(如rcu、定时器)的存在导致非确定性。
我的判断是:RT-PREEMPT适合跑飞控里的软实时任务,比如视觉避障、路径规划、地面站通信这类对极端最坏情况不敏感的工作负载。如果一定要用它跑姿态控制,必须在系统层面做完备的延迟上界测试,并加上独立的硬件看门狗兜底。我甚至见过一个团队在RT-PREEMPT Linux上通过"核心隔离(isolcpus)+ affinization + 禁调度器tick"的配置,把临界任务延迟控制在了10微秒级别,但那是极其特化的场景,不具代表性。
7.4 我能给的最终选型建议
- 飞控的安全级姿态控制:必须硬实时。有人问"FPGA+软核和单片机哪个好",我的建议是如果你没有把握做完整的WCET分析,干脆用FPGA实现硬逻辑控制律,这比在MCU上纠结实时性更稳妥。
- 飞控的外回路控制:软实时即可。用带RT-PREEMPT的Linux或者普通RTOS的低优先级任务实现,配合一定的容错逻辑即可。
- 飞控的任务调度核心:如果做三余度或更高安全等级的飞控,直接考虑时间触发架构+分区隔离(ARINC 653)。如果做消费级或工业级无人机,混合架构(M7时间触发+Linux软实时)已经足够,成本和复杂度都可控。
我在实际项目里最常说的一句话是:做飞控系统设计,先做任务分类表和WCET分析,再选平台,最后才写代码。顺序反了,后面全是在填坑。这句话也送给读到这里的你。