尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

F Prime 速率组调度(Rate Group Scheduling)完全指南:从时钟分频到相位调度

F Prime 速率组调度(Rate Group Scheduling)完全指南:从时钟分频到相位调度 F Prime 速率组调度Rate Group Scheduling完全指南从时钟分频到相位调度【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址: https://gitcode.com/GitHub_Trending/fpr/fprime导读本文基于 F´F Prime飞行软件框架的系统功能参考文档系统讲解其周期性执行机制——速率组调度Rate Group Scheduling。这是 F´ 中遥测采集、传感器读取、控制回路等所有周期性任务的驱动骨架一个系统时钟源产生主 tick经过分频后驱动多个速率组Rate Group再由速率组按序调用其成员组件。读完本文你将掌握 RateGroupDriver 的分频原理与配置方法、Active/Passive Rate Group 的执行模型与超时检测Overrun/Slip机制、ActivePhaser 的相位调度模型以及速率组的遥测与统计清除命令的实战用法。概述F´ 的周期执行骨架速率组调度提供了以定义速率周期性执行组件的能力。其基本思想是一个系统时钟源生成主 tickprimary tick该主 tick 被分频驱动多个以不同频率运行的速率组每个速率组按定义好的顺序调用一组组件。这是 F´ 中循环处理的基础执行模式——遥测收集、传感器读取、控制回路以及其他周期性任务都通过速率组驱动。该能力由一串协作组件构成周期源cycle source生成主 tick如LinuxTimer、PosixTime、ChronoTime等详见 Time Services速率组驱动器Rate Group Driver将主 tick 分频为多个子速率速率组组件Rate Group将周期调用分发给其成员组件。时钟分频RateGroupDriver速率组驱动器接收一个主系统 tick并将其分频产生不同速率的输出。其典型用法是一个 1 Hz 的 tick 经分频后产生 1 Hz、0.5 Hz、0.25 Hz 的输出。分频比例divider在构造/配置时指定。RateGroupDriver 是被动组件运行在调用者的线程上下文中。配置接口与约束驱动器通过configure()传入一组分频器DividerSetRateGroupDriverImpl::configure(const DividerSet dividerSet);从 源码实现 可以看到配置过程中的关键约束与内部处理表大小校验static_assert保证分频表大小与NUM_CYCLEOUT_OUTPUT_PORTS一致offset 合法性任何端口的 offset 必须小于其 divisoroffset 0或offset divisor否则FW_ASSERT失败——因为 offset 大于等于 divisor 的端口永远不会被调用rollover 防溢出m_rollover为所有非零 divisor 的乘积并断言乘积不会溢出FwSizeType每次 tick 后m_ticks (m_ticks 1) % m_rollover避免整数回绕导致跳周期内容拷贝DividerSet的内容在调用时被复制因此传入的数组可以是临时变量必须在构造之后、任何端口调用之前调用configure()否则CycleIn_handler中的FW_ASSERT(this-m_configured)会失败。分频逻辑CycleIn_handler源码对每个配置了非零 divisor 且已连接的输出端口判断(m_ticks % divisor) offset是否成立成立则调用该输出端口。文档中的分频示例SchedIn 速率divider[0]SchedOut[0]divider[1]SchedOut[1]divider[2]SchedOut[2]1 Hz11 Hz20.5 Hz40.25 Hz即divisor 为 4 的端口每第 4 次CycleIn调用被触发一次。每个输出端口通常连接到某个速率组组件的输入。设计约束RateGroupDriver 被设计为可在 ISR 上下文运行其需求 RGD-002 通过 Inspection 验证因此实现避免浮点计算、获取互斥锁、调用未知副作用的库、过长的实现路径。速率组执行三种变体速率组按序调用其成员组件并传递一个指示调用顺序的上下文值context。F´ 提供三种变体变体线程模型输入端口类型适用场景Active Rate Group独立线程异步入队唤醒线程需要将速率组执行与时钟源解耦的重负载处理Passive Rate Group调用者线程同步无需独立线程开销的轻量处理Active Phaser独立线程异步需要在周期内精确分配各组件执行时刻的相位调度Active 与 Passive 速率组都会跟踪每个周期完成所需时间并以遥测形式上报。Active Rate Group独立线程 超时检测Svc::ActiveRateGroup是一个主动组件驱动连接到Svc::Sched输出端口的一组组件。其输入Svc::Cycle端口是异步的调用该端口会向队列投递一条消息唤醒组件任务任务随后按序调用所有成员输出端口。这使速率组执行与时钟源解耦。上下文配置一组上下文值以数组形式传入configure()void configure(U32 contexts[], FwIndexType numContexts);每个 context 值可供组件区分速率组内的多次调用组件头文件 提供了基于ContextArray的新签名旧签名已标记DEPRECATED。超时/滑移Slip检测机制组件在 CycleIn 被调用时置位标志在速率组执行开始时清除该标志若在周期结束时检测到标志再次被置位则声明一次 cycle slip发出RateGroupCycleSlip警告事件WARNING_HI源码并递增RgCycleSlips遥测计数fpp 定义。这表示新周期在前一周期完成前就已开始——系统未满足时序要求需要关注速率过快或成员组件耗时过长。其单元测试ActiveRateGroupTester.cpp验证了滑移事件与计数遥测的行为包括节流计数。Passive Rate Group同步执行 每端口时序遥测Svc::PassiveRateGroup是被动组件在调用者线程上下文中执行通常由 RateGroupDriver 直接同步调用。输入Svc::Cycle端口是同步的成员组件直接在调用速率组的那一方上下文中被调用。configure()接受两个参数fpp 定义一个 U32 上下文数组每个输出端口一个值传给每个速率组成员可选的Os::RawTimeSource指定用于周期执行时间测量的计时器源默认为Os::RAWTIME_DEFAULT。计时源限制重要关键限制configure()中的RawTimeSource参数只影响每个周期的结束时间戳。周期的开始时间戳来自周期驱动器如RateGroupDriver、LinuxTimer它们以RAWTIME_DEFAULT构造Os::RawTime。当两者源不同时Os::RawTime会拒绝该时间间隔POSIX 实现返回INVALID_PARAMS周期时间被上报为零。该特性仅在以下情况正确使用默认值RAWTIME_DEFAULT或周期驱动器使用相同的非默认源。要部署级地更换时钟应覆盖config/Os/RawTimeSource.hpp并设置RAWTIME_DEFAULT而不是在此处传入非默认源。参见 Configuring F´ 中的 OSAL 配置。默认配置 中的枚举展示了可选源RAWTIME_DEFAULT CLOCK_REALTIME—— 默认构造 RawTime 对象使用的时钟POSIX 上即传给clock_gettime()的clockid_tRAWTIME_REALTIME CLOCK_REALTIME—— 墙钟时间系统时间调整时可能跳变或渐变RAWTIME_MONOTONIC CLOCK_MONOTONIC—— 单调时钟不受系统时间调整影响RAWTIME_BOOTTIME CLOCK_BOOTTIME—— 挂起期间也继续前进的单调时钟仅 Linux。命令与原子统计PassiveRateGroup支持CLEAR_STATISTICS同步命令实现将所有端口时长高水位high water marks和最大周期时间清零。周期计数不会被清除因为它表示运行总数。所有统计量由无锁原子操作保护m_maxTime与各端口 HWM从而ISR 安全且消除了互斥锁开销。遥测通道通道类型描述发送语义MaxCycleTimeU32速率组周期最大执行时间微秒。由CLEAR_STATISTICS命令清除变化时更新仅最大值增加时CycleTimeU32最近一次周期的执行时间微秒每周期发送CycleCountU32已执行周期总数。不被CLEAR_STATISTICS清除每周期发送PortCycleTimeU32[PassiveRateGroupOutputPorts]最近一次周期中各成员端口的执行时间微秒每周期发送仅当PassiveRateGroupCfg::PortCycleTime启用PortCycleTimeHWMU32[PassiveRateGroupOutputPorts]各端口执行时间的高水位微秒。由CLEAR_STATISTICS清除变化时更新任一高水位增加时降低带宽占用PortCycleTime每周期发送提供每个周期执行的完整时序快照PortCycleTimeHWM采用变化时更新语义仅在至少一个端口的高水位上升时发送在降低遥测带宽的同时仍能捕获时序异常。每端口高水位与周期统计的启用由配置项PassiveRateGroupCfg::PortCycleTime控制见 实现 与 测试。使用场景CLEAR_STATISTICS用于系统变更后重新建立时序基线re-baselining、或在特定运行阶段隔离时序行为。Active Phaser周期内相位调度Svc::ActivePhaser提供更精细的调度模型每个周期被划分为可配置数量的 tick各个端口调用被映射到周期内特定的 tick 窗口。这允许精确控制每个组件在周期内的调用时刻实现相位调度——不同组件在周期内不同时间点运行以摊开处理负载。调度示例来自 SDD一个相位周期由 10 个 tick 组成。端口调用 A长度 2从 tick 0 开始端口调用 B长度 3从 tick 2 开始端口调用 C长度 1在 tick 6 和 tick 8 各启动一次。调度每 10 个 tick 重复。端口调用按其注册顺序被调用若端口调用指定了长度组件会在运行时检查该调用是否超过其指定长度overrun发生超时时发出MissedDeadline警告事件需求 AP-003见 SDD。Dropped Cycles丢周期语义CycleIn与内部Tick端口声明为drop——队列满时到达的周期被丢弃。这是预期行为且不上报任何事件或遥测通道与ActiveRateGroup会发出RateGroupCycleSlip并计数RgCycleSlips不同ActivePhaser对丢弃周期保持静默。被丢弃的周期会使相位基准永久滞后一个周期且MissedDeadline不会观测到它因为它只度量已执行周期内的超时。操作员不应将组件没有事件视为没有丢周期。配置要点汇总配置项配置位置/方式说明速率组成员输出端口数量编译期配置ActiveRateGroupOutputPorts/PassiveRateGroupOutputPorts等输出端口数量在编译时确定RateGroupDriver 分频比例configure(const DividerSet)构造后、端口调用前调用offset 必须小于 divisor成员组件的上下文值configure(contexts, numContexts)基于端口号索引的配置表ActivePhaser tick 数与每端口时间窗口setup 时配置决定周期内各调用的相位分配PassiveRateGroup 计时源configure(..., Os::RawTimeSource)默认RAWTIME_DEFAULT仅影响周期结束时间戳全局时钟源覆盖config/Os/RawTimeSource.hpp中RAWTIME_DEFAULT部署级切换时钟如改为CLOCK_MONOTONIC深入阅读周期源cycle source驱动速率组调度的机制参见 Time Services各组件完整设计文档RateGroupDriver SDD —— 分频需求 RGD-001/RGD-002、端口表与 ISR 合规设计ActiveRateGroup SDD —— 需求 ARG-001 至 ARG-004、滑移检测设计PassiveRateGroup SDD —— 需求 FPRIME-PRG-001 至 005、CLEAR_STATISTICS与遥测通道ActivePhaser SDD —— 需求 AP-001 至 003、丢周期语义速率组端口类型定义见 Svc::Sched 与 Svc::Cycle 对应的 fpp 接口参考实现Ref 部署中的速率组拓扑连接示例见 Ref 拓扑 目录。【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址: https://gitcode.com/GitHub_Trending/fpr/fprime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表