
嵌入式系统编程【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址https://gitcode.com/gh_mirrors/fpri/fprime点击查看免费下载本文以 Svc/ActiveRateGroup/docs/sdd.md 软件设计文档为核心结合 ActiveRateGroup.fpp、ActiveRateGroup.cpp 等源码与 Ref 参考拓扑 中的实际集成方式系统讲解 F´F Prime飞行软件框架中主动速率组Active Rate Group组件的端口设计、执行流程、事件遥测与周期滑移cycle slip检测机制并给出配置参数、实例化方法和单元测试的运行方式。1. 为什么需要速率组ActiveRateGroup 扮演什么角色在 F´ 这类嵌入式飞行软件框架中周期性任务通常按固定时间片调度。Svc::ActiveRateGroup正是承担这一职责的主动组件active component它接收外部驱动的周期信号然后按固定顺序依次调用一组挂接在Svc::Sched输出端口上的成员组件从而把一个时间周期切分给多个需要周期性执行的组件。根据 sdd.md 的设计描述该组件的核心职责包括作为主动组件由异步输入端口Svc::Cycle唤醒任务线程按顺序调用每个Svc::Sched输出端口并传入一个指示调用次序的上下文值跟踪整个速率组的执行时间并以遥测形式上报检测周期滑移overrun / cycle slip即上一个周期尚未完成、下一个周期信号已经到达的情况。2. 组件需求Requirementssdd.md 第 2 节给出了该组件的四条形式化需求需求编号需求描述验证方式ARG-001组件必须是主动组件由异步端口调用唤醒审查Inspection、单元测试ARG-002组件必须按顺序调用输出端口并传入基于端口号的查表上下文值单元测试ARG-003组件必须跟踪速率组的执行时间并作为遥测上报单元测试ARG-004当新周期在上一个周期完成之前到达时组件必须上报警告事件单元测试这四条需求直接映射到 ActiveRateGroup.fpp 中的组件定义异步CycleIn输入端口、Sched输出端口数组、RgMaxTime遥测通道与RateGroupCycleSlip警告事件以及 test/ut 目录下的对应单元测试。3. 组件结构与端口设计3.1 组件图以下是 sdd.md 中的组件框图原图Svc::ActiveRateGroup 组件端口框图左侧为异步 CycleIn 输入端口右侧为 Sched 输出端口数组底部为 Log、LogText、Time、Tlm 服务端口从图中可以看到组件被标注为active其端口布局与 ActiveRateGroup.fpp 中的声明完全一致。3.2 端口一览sdd.md 第 3.1.2 节定义了组件使用的端口类型ActiveRateGroup.fpp 给出了对应的 FPP 声明端口数据类型名称方向类型用途Svc::CycleCycleIn输入异步接收调用运行一个速率组周期Svc::SchedRateGroupMemberOut输出n/a挂接速率组成员组件在 FPP 模型中的完整声明如下 The rate group cycle input async input port CycleIn: Svc.Cycle drop Scheduler output port to rate group members output port RateGroupMemberOut: [ActiveRateGroupOutputPorts] Sched Ping input port for health async input port PingIn: Ping Ping output port for health output port PingOut: Ping值得注意的细节CycleIn带drop关键字即异步丢弃式输入端口当消息队列已满时新的周期调用会被丢弃。结合下文周期滑移机制可以理解——如果任务执行过慢导致队列堆积多余周期信号会被丢弃而CycleIn_preMsgHook中的滑移标志仍会置位从而在周期结束时触发滑移检测。RateGroupMemberOut是Svc.Sched端口数组数组大小由常量ActiveRateGroupOutputPorts决定成员组件通过该端口获得调度调用。PingIn/PingOut用于接入 Svc::Health 健康检查验证任务线程的存活。此外组件还包含如下特殊端口ActiveRateGroup.fppLog事件输出端口发送事件LogText文本事件输出端口Time时间获取端口Tlm遥测输出端口。两个端口数据类型的 FPP 定义同样值得对照阅读。Svc::Cycle 携带一个cycleStart: Svc.TimerVal计时引用参数由调用方通常是RateGroupDriver在周期开始时打点Svc::Sched 则携带一个context: NATIVE_UINT_TYPE上下文参数用于告知成员组件本次调用在其速率组中的次序。4. 功能设计与执行流程4.1 配置函数与上下文数组sdd.md 第 3.2 节明确指出一组上下文值context values通过配置函数以数组形式传入void configure(NATIVE_UINT_TYPE contexts[], NATIVE_UINT_TYPE numContexts);对应源码见 ActiveRateGroup.hpp 与 ActiveRateGroup.cpp。其语义要点上下文数组的索引与输出端口号一一对应第N个上下文值会被传给RateGroupMemberOut[N]上下文值的作用是让同一组件区分多次调用如果一个组件在多个速率组中多次被挂接它可以借助上下文参数区分是哪一次调用、来自哪个速率组configure()内部通过FW_ASSERT校验上下文数组非空、数量与输出端口数一致然后将上下文值拷贝进组件私有存储m_contexts在CycleIn_handler中还会再次FW_ASSERT(m_numContexts)确保组件在配置前不会被调用。另外仓库中还保留了另一套实现变体ActiveRateGroupImplActiveRateGroupImpl.cpp其上下文数组改由构造函数传入二者核心执行逻辑完全一致。4.2 一次周期的执行时序sdd.md 第 3.3.1 节给出了速率组端口调用时序图对应底层实现在 ActiveRateGroup.cpp 的CycleIn_handler中可拆解为以下步骤消息前置钩子CycleIn_preMsgHookL110-L113在调用方线程上执行将m_cycleStarted标志置true标记新周期已请求。该钩子不与CycleIn_handler在同一线程执行这正是滑移检测得以实现的并发基础清除滑移标志m_cycleStarted false按顺序调用输出端口遍历RateGroupMemberOut的每个端口若isConnected_RateGroupMemberOut_OutputPort(port)为真则调用RateGroupMemberOut_out(port, m_contexts[port])传入该端口对应的上下文值L68-L73计时结束end.take()记录周期结束时刻通过end.diffUSec(cycleStart)计算本次周期执行耗时微秒更新最大执行时间若本次耗时超过历史最大值m_maxTime则更新之并通过tlmWrite_RgMaxTime写入遥测滑移检测见下文 4.3周期计数m_cycles自增。4.3 周期滑移Cycle Slip检测机制这是本组件最核心的故障检测能力。sdd.md 第 3.2 节对此的描述是组件在周期端口被调用时置位标志在速率组执行开始时清除标志如果周期结束时发现标志再次被置位则声明发生周期滑移cycle slip发送事件并递增滑移计数。结合 ActiveRateGroup.cpp 的源码完整逻辑如下// check for cycle slip. That will happen if new cycle message has been received // which will cause flag will be set again. if (this-m_cycleStarted) { this-m_cycleSlips; if (this-m_overrunThrottle ACTIVE_RATE_GROUP_OVERRUN_THROTTLE) { this-log_WARNING_HI_RateGroupCycleSlip(this-m_cycles); this-m_overrunThrottle; } // update cycle slips this-tlmWrite_RgCycleSlips(this-m_cycleSlips); } else { // if cycle is okay start decrementing throttle value if (this-m_overrunThrottle 0) { this-m_overrunThrottle--; } }机制解读并发窗口CycleIn_preMsgHook在调用方线程置位CycleIn_handler在组件任务线程清除并检查。若周期执行期间又有新的CycleIn调用到达即使因drop语义未入队钩子仍会置位标志周期结束时即可发现滑移后果m_cycleSlips自增并写入遥测通道RgCycleSlips事件节流throttle为避免滑移连续发生时事件风暴刷屏源码通过m_overrunThrottle计数器限制事件上报频率——只有当节流计数小于阈值时才发送RateGroupCycleSlip警告事件。该阈值由配置文件 config/ActiveRateGroupCfg.hpp 定义namespace Svc { enum { //! Number of overruns allowed before overrun event is throttled ACTIVE_RATE_GROUP_OVERRUN_THROTTLE 5, }; }即默认连续发生 5 次滑移后停止逐次上报警告事件而正常周期会逐步递减节流计数为后续滑移重新开放事件上报。4.4 状态与算法sdd.md 第 3.4、3.5 节明确指出该组件没有状态机也没有显著算法。其所有行为均由上述基于标志位与计时器的过程性逻辑实现不依赖复杂状态模型。5. 事件与遥测定义ActiveRateGroup.fpp 中定义的事件与遥测通道如下事件Events事件严重级别ID格式RateGroupStarteddiagnostic0Rate group started.RateGroupCycleSlip(cycle: U32)warning high1Rate group cycle slipped on cycle {}其中RateGroupStarted由任务preamble()钩子在进入消息循环前发送ActiveRateGroup.cpp用于指示速率组任务已启动RateGroupCycleSlip携带参数cycle发生滑移时的周期计数即m_cycles供地面系统定位故障发生的周期。遥测通道Telemetry通道类型ID格式RgMaxTimeU320{} usRgCycleSlipsU321无RgMaxTime速率组历史最大执行时间微秒update on change语义仅在最大值变化时上报避免每个周期都占用遥测带宽RgCycleSlips累计滑移次数同样为变化时上报。6. 在 Reference 参考拓扑中的实际集成Ref 示例工程 提供了三个速率组实例是理解本组件落地配置的最佳范例。6.1 实例化Ref/Top/instances.fpp 中以 FPP 语言声明了三个Svc.ActiveRateGroup实例instance rateGroup1Comp: Svc.ActiveRateGroup base id 0x0200 \ queue size Default.QUEUE_SIZE \ stack size Default.STACK_SIZE \ priority 120 instance rateGroup2Comp: Svc.ActiveRateGroup base id 0x0300 \ queue size Default.QUEUE_SIZE \ stack size Default.STACK_SIZE \ priority 119 instance rateGroup3Comp: Svc.ActiveRateGroup base id 0x0400 \ queue size Default.QUEUE_SIZE \ stack size Default.STACK_SIZE \ priority 118三个实例分别以 120 / 119 / 118 的优先级创建独立任务线程队列深度与栈大小均取默认值QUEUE_SIZE 10STACK_SIZE 64 * 1024见 instances.fpp。在 Ref/Top/topology.fpp 中还通过Ports_RateGroups枚举rateGroup1/rateGroup2/rateGroup3将三个速率组与RateGroupDriver的除法器输出对应起来。6.2 配置与驱动Ref/Top/RefTopology.cpp 展示了完整的装配代码NATIVE_INT_TYPE rateGroupDivisors[Svc::RateGroupDriver::DIVIDER_SIZE] {1, 2, 4}; NATIVE_INT_TYPE rateGroup1Context[Svc::ActiveRateGroup::CONNECTION_COUNT_MAX] {}; NATIVE_INT_TYPE rateGroup2Context[Svc::ActiveRateGroup::CONNECTION_COUNT_MAX] {}; NATIVE_INT_TYPE rateGroup3Context[Svc::ActiveRateGroup::CONNECTION_COUNT_MAX] {}; ... rateGroupDriverComp.configure(rateGroupDivisors, FW_NUM_ARRAY_ELEMENTS(rateGroupDivisors)); rateGroup1Comp.configure(rateGroup1Context, FW_NUM_ARRAY_ELEMENTS(rateGroup1Context)); rateGroup2Comp.configure(rateGroup2Context, FW_NUM_ARRAY_ELEMENTS(rateGroup2Context)); rateGroup3Comp.configure(rateGroup3Context, FW_NUM_ARRAY_ELEMENTS(rateGroup3Context));这里体现了两个设计要点除数数组{1, 2, 4}RateGroupDriver将同一基频分别按 1、2、4 分频得到三个不同周期的调度信号分别驱动rateGroup1Comp最高频、rateGroup2Comp、rateGroup3Comp最低频——即所谓速率组的速率差异来源上下文数组rateGroupNContext的大小取Svc::ActiveRateGroup::CONNECTION_COUNT_MAX见 ActiveRateGroup.hpp初始化为 0配合configure()传入。示例中各成员组件可通过上下文参数分辨自身所属的速率组序号。6.3 遥测通道接入Ref/Top/RefPackets.xml 中三个速率组的RgMaxTime与RgCycleSlips遥测通道均被加入下行数据包定义地面系统可直接监控每个速率组的执行时间与滑移情况channel namerateGroup1Comp.RgMaxTime/ channel namerateGroup2Comp.RgMaxTime/ channel namerateGroup3Comp.RgMaxTime/ ... channel namerateGroup1Comp.RgCycleSlips/ channel namerateGroup2Comp.RgCycleSlips/ channel namerateGroup3Comp.RgCycleSlips/7. 单元测试与覆盖率该组件的单元测试位于 Svc/ActiveRateGroup/test/ut包含ActiveRateGroupImplTester.cpp、ActiveRateGroupImplTester.hpp与ActiveRateGroupTester.cpp。测试目录的 Readme.txt 给出了执行方式From Svc/ActiveRateGroup:make ut run_utNote that the Ref application needs to be built first.sdd.md 第 6 节还提示可通过以下命令查看单元测试覆盖率fprime-util check --coverage单元测试主要围绕第 2 节的需求 ARG-001 至 ARG-004 展开重点验证异步周期端口唤醒、输出端口按序调用并传递上下文值、执行时间遥测上报、以及周期滑移时的警告事件与计数行为。8. 变更记录与工程规范sdd.md 第 7 节的变更日志显示该组件的设计演进历史日期描述6/22/2015设计评审修订7/22/2015设计评审行动项8/10/2015更新为周期输入端口cycle input port8/31/2015单元测试评审更新这一演进说明早期设计可能使用其他唤醒方式2015 年 8 月起定型为通过Svc::Cycle端口驱动与当前 ActiveRateGroup.fpp 中的实现一致。工程规范方面docs 目录还提供了设计检查表Checklist_Design.xlsx、代码检查表Checklist_Code.xlsx与单元测试检查表Checklist_Unit_Test.xls供开发与评审流程参考。9. 小结Svc::ActiveRateGroup是 F´ 框架中周期性调度的心脏之一它通过异步Cycle端口接收RateGroupDriver分频产生的周期信号按序驱动一组Sched成员组件并以TimerVal计时、以RgMaxTime遥测上报最大执行时间、以RateGroupCycleSlip警告事件和RgCycleSlips遥测暴露过载风险。理解其CycleIn_preMsgHook与CycleIn_handler的双线程标志位协作机制以及上下文数组按端口序号传递的设计是正确使用和排查速率组问题的关键Ref 参考拓扑 中的三实例装配则是将其投入实际飞控软件的完整范例。赞分享嵌入式系统编程【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址https://gitcode.com/gh_mirrors/fpri/fprime点击查看免费下载相关推荐F´ (F Prime) 飞行软件框架中的 Svc::ActiveRateGroup 速率组调度组件详解F´ F Prime 飞行软件框架中的 Svc::ActiveRateGroup 速率组调度组件详解 Svc::ActiveRateGroup 是 F´ 飞行软嵌入式系统编程F´ 框架 Svc::PassiveRateGroup 被动速率组组件深度解析调度端口驱动、上下文传递与周期计时遥测F´ 框架 Svc::PassiveRateGroup 被动速率组组件深度解析调度端口驱动、上下文传递与周期计时遥测 导读 Svc::PassiveRateG嵌入式系统编程F´ 框架中的 Svc::ActiveRateGroup 组件实现定时速率组调度的完整解析F´ 框架中的 Svc::ActiveRateGroup 组件实现定时速率组调度的完整解析 Svc::ActiveRateGroup 是 F´F Prime嵌入式系统编程上一篇如何使用ColorBlendr3分钟上手Android个性化主题设置新手也能轻松搞定下一篇自动机器学习库AutoKeras的安装与使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考