第二章 调度策略基础:调度器的角色、任务模型与调度方式

各位同学,咱们今天聊聊调度策略的根基。说实话,很多做运动控制的工程师,一上来就盯着PID参数调,或者死磕轨迹规划算法,却忽略了调度器这个“幕后总指挥”。我见过太多项目,算法写得漂亮,但一上机就跑飞了——十有八九是调度策略没搞对。

调度器是什么?说白了,它就是CPU的“交通警察”。多任务同时抢着用CPU,谁先走、谁后走、走多久,都得听它的。在运动控制里,这个角色尤其关键。你想想看,一个伺服驱动器里,电流环、速度环、位置环、通讯任务、监控任务……全挤在一个芯片上。调度器要是乱指挥,电机抖一下,产品就废了。

2.1 调度器的核心职责

调度器干的事,归纳起来就三件:

  • 任务选择:从就绪队列里挑一个任务来执行
  • 上下文切换:保存当前任务的状态,加载下一个任务的状态
  • 时间管理:决定什么时候切换、切换给谁

嗯,这里要注意,上下文切换是有代价的。我早期做一款多轴控制器时,为了追求“实时性”,把调度周期设得特别短,结果CPU一半的时间都花在切来切去上了。后来才明白,调度器的效率不是看切换频率,而是看“有效计算时间占比”。

关键指标:调度开销比

调度开销比 = 调度器运行时间 / 总CPU时间。这个值超过5%,你就得警惕了。

2.2 任务模型:三种基本类型

搞调度,先得搞清楚任务长什么样。我习惯把任务分成三类,就像区分三种性格的人:

2.2.1 周期任务

这类任务最有规律。每隔固定时间触发一次,比如电流环1kHz、速度环500Hz。在工业现场,大部分控制回路都是周期任务。

周期任务的三个参数:

  • 周期T:两次触发的时间间隔
  • 执行时间C:任务实际跑完需要的时间
  • 截止时间D:必须在D时间内完成,通常D=T

举个例子,我做过一个激光切割项目,位置环周期是1ms。但有一次发现,当切割复杂图形时,位置环的执行时间从0.3ms飙到了0.8ms。差点就超时了。这就是典型的“执行时间抖动”,你得留余量。

2.2.2 非周期任务

这类任务啥时候来,你猜不到。比如急停信号、限位开关触发、通讯中断。它们的特点是:

  • 触发时间不确定
  • 但一旦来了,必须尽快响应
  • 执行时间通常很短

我曾经遇到一个案例:客户反映设备偶尔会“卡顿”一下。查了三天,发现是某个非周期的IO中断处理函数里,不小心写了个延时循环。非周期任务最忌讳的就是“赖着不走”。

2.2.3 偶发任务

偶发任务介于两者之间。它可能隔很久才来一次,但来了之后,短时间内可能连续触发多次。比如:

  • 编码器断线报警
  • 温度超限保护
  • 网络重连请求

偶发任务有个关键参数叫最小到达间隔。你设计调度器时,得按最坏情况来算——假设它连续以最小间隔触发,系统能不能扛住。

我的经验:设计任务模型时,永远假设最坏情况。周期任务按最大执行时间算,非周期任务按最大频率算。别指望“一般不会这样”,工业现场什么破事都能发生。

2.3 抢占与非抢占调度

这是调度策略里最核心的抉择。两种方式,各有各的脾气。

2.3.1 非抢占调度

简单粗暴:一个任务开始跑,除非它自己主动让出CPU,否则谁也别想打断它。

优点:

  • 实现简单,没有复杂的上下文切换
  • 共享数据不用加锁,因为不会被打断
  • 任务执行时间可预测

缺点:

  • 高优先级任务可能被低优先级任务堵死
  • 响应时间不可控

我记得刚入行时,用单片机做一个小型运动控制器,用的就是非抢占调度。当时觉得挺美,代码简单。结果有一次,一个通讯任务在发数据包时卡住了(对方没应答),整个系统就僵在那了。从那以后,我对非抢占调度就多了一份敬畏。

2.3.2 抢占调度

抢占调度就“霸道”多了。高优先级任务一来,低优先级任务立马靠边站。CPU直接切换过去。

优点:

  • 高优先级任务响应快
  • 适合硬实时场景

缺点:

  • 上下文切换开销大
  • 共享资源需要保护(互斥锁、关中断等)
  • 可能出现优先级反转

优先级反转是什么?我简单说个场景:任务A(高优先级)和任务C(低优先级)共享一个资源。任务C先拿到了资源,然后被任务B(中优先级)抢占了。任务B跑个没完,任务A等着资源干着急。这就是优先级反转。

避坑指南:我曾经在一个6轴机器人项目里,因为没处理好优先级反转,导致关节3在高速运动时偶尔“抽风”。查了两周,最后发现是共享内存访问没加优先级继承协议。从那以后,我只要用抢占调度,必配优先级继承或优先级天花板协议。

2.4 调度策略的选择依据

说了这么多,到底怎么选?我个人的经验是:

场景 推荐调度方式 理由
单任务控制回路 非抢占 简单可靠,无竞争风险
多任务硬实时系统 抢占 + 优先级继承 保证关键任务响应
混合任务(周期+非周期) 抢占 + 固定优先级 非周期任务设高优先级
资源极度受限 非抢占 + 协作式 节省上下文切换开销

你可能会问:有没有一种调度方式能通吃所有场景?我的答案是:没有。每个项目都有它的脾气,你得根据任务模型、硬件资源、实时性要求来权衡。

2.5 本章知识体系图

下面这张图,是我自己画的一个调度策略知识框架。你看一眼,就能把本章的内容串起来:

调度策略基础框架 调度器核心职责 任务选择 上下文切换 时间管理 任务模型 周期任务 (T, C, D) 非周期任务 偶发任务 调度方式 非抢占调度 抢占调度

这张图把调度器、任务模型、调度方式串在了一起。你顺着箭头看,就能理解它们之间的关系。调度器根据任务模型(周期、非周期、偶发)来选择合适的调度方式(抢占或非抢占),最终实现任务选择、上下文切换和时间管理。

本章核心要点:

  • 调度器是实时系统的“交通警察”,负责任务选择、上下文切换和时间管理
  • 任务模型分三类:周期任务(固定间隔)、非周期任务(随机触发)、偶发任务(有最小间隔)
  • 非抢占调度简单但响应慢,抢占调度响应快但需处理资源竞争
  • 优先级反转是抢占调度中的常见陷阱,需用优先级继承或天花板协议解决

好了,调度策略的基础就聊到这。这些概念看着简单,但真正用好了,能帮你省下不少调试时间。下一章咱们会深入具体的调度算法,比如RMS、EDF这些,到时候再结合实战案例细讲。


公众号:蓝海资料掘金营,微信deep3321