十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

F´ 框架 Ref 部署演示组件剖析:SendBuffApp 缓冲区发送与错误注入机制

F´ 框架 Ref 部署演示组件剖析:SendBuffApp 缓冲区发送与错误注入机制 F´ 框架 Ref 部署演示组件剖析SendBuffApp 缓冲区发送与错误注入机制【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址: https://gitcode.com/GitHub_Trending/fpr/fprimeRef::SendBuffApp是 F´F Prime飞行软件框架参考部署Ref 部署中用于演示数据缓冲区DataBuffer传输链路的示例组件它由速率组Rate Group调度驱动周期性将序列化后的数据包通过Drv.DataBuffer端口发送给Ref::RecvBuffApp并内置了错误注入、FATAL 事件生成、断言触发等故障演练能力。读完本文你将掌握该组件在 TestDeploymentsProject/Ref/SendBuffApp/docs/sdd.md 之外完整的 FPP 模型定义、底层 C 实现逻辑、数据包格式与校验和协议以及它如何在 Ref 拓扑中与速率组、BlockDriver、RecvBuffApp 协同工作。Ref::SendBuffApp组件图1. 组件定位与设计意图根据组件 SDDSoftware Design Description文档Ref::SendBuffApp是一个演示组件demonstration component其唯一职责是向配对组件Ref::RecvBuffApp发送数据缓冲区。SDD 明确描述了二者的单向协作关系TheRef::SendBuffAppis a demonstration component that sends data buffers toRef::RecvBuffAppRecvBuffApp SDD在 Ref 部署的整体数据通路中这对组件承担的角色是验证发送方 → 中间驱动 → 接收方的缓冲区流动闭环SendBuffApp生成并发送数据包BlockDriver模拟底层块设备驱动进行中转RecvBuffApp接收并校验数据包。这一链路在 RefTopology 连接定义 中体现为两条直接连接sendBuffComp.Data - blockDrv.BufferIn blockDrv.BufferOut - recvBuffComp.Data从部署角度SendBuffApp在 instances.fpp 中被实例化为queued队列型组件拥有独立的消息队列但无独立线程由速率组调度驱动其处理instance sendBuffComp: Ref.SendBuff base id 0x10010000 \ queue size Default.QUEUE_SIZE其中0x10010000是该实例所有命令、事件、遥测、参数 ID 的基地址Base IDqueue size 10继承自模块默认队列大小常量。2. 需求分析SDD 第 2 节给出了组件必须满足的两条需求其验证方式均为系统级测试System test需求编号描述验证方法ISF-RBF-001Ref::SendBuffApp组件应能够发送缓冲区系统测试ISF-RBF-002Ref::SendBuffApp组件应提供注入错误的能力系统测试这两条需求在源码层面均有直接对应实现ISF-RBF-001发送缓冲区由SchedIn_handler中this-Data_out(0, this-m_testBuff)调用实现见 SendBuffComponentImpl.cppISF-RBF-002注入错误由命令SB_INJECT_PKT_ERROR设置m_injectError标志位、并在下一次发包时破坏校验和数据实现见本文第 5 节。需要说明的是SDD 中模块清单Module Checklists单元测试Unit Testing章节为空说明该组件的验证目前主要依赖系统级链路测试与 Ref 部署的集成演示而非独立的单元测试套件。3. 组件模型FPP 定义全解组件的完整接口定义位于 SendBuffApp.fpp其 FPP 模型将组件声明为queued component并系统性地声明了端口、命令、事件、参数与遥测五个维度。3.1 端口Ports The rate group scheduler input sync input port SchedIn: Svc.Sched The data buffer output output port Data: Drv.DataBuffer端口方向类型说明SchedIn同步输入Svc.Sched速率组调度输入每个调度周期触发一次发送检查Data输出Drv.DataBuffer数据缓冲区输出端口连接至BlockDriver.BufferIn此外组件声明了 F´ 组件的标准特殊端口集合命令接收CmdDisp、命令注册CmdReg、命令响应CmdStatus、事件Log、文本事件LogText、时间获取Time、遥测Tlm、参数获取/设置ParamGet/ParamSet。3.2 命令Commands组件共定义 4 条异步命令覆盖正常启动、错误注入、故障演练三大场景async command SB_START_PKTS opcode 0 # 开始发送数据包 async command SB_INJECT_PKT_ERROR opcode 1 # 在下一个数据包中注入错误 async command SB_GEN_FATAL(arg1: U32, arg2: U32, arg3: U32) opcode 2 # 产生一条 FATAL 事件 async command SB_GEN_ASSERT(arg1..arg6: U32) opcode 3 # 触发一次断言FW_ASSERT结合实例 Base ID0x10010000四条命令的实际命令码分别为0x10010000、0x10010001、0x10010002、0x10010003在 GDS 中下发时即使用这些完整命令码。3.3 事件Events| 事件 | 严重级别 | ID | 格式 | | ---- | -------- | -- | ---- | |FirstPacketSent| ACTIVITY_HI | 0 |First packet ID {} received| |PacketErrorInserted| WARNING_HI | 1 |Inserted error in packet ID {}| |BuffSendParameterUpdated| ACTIVITY_LO | 2 |BuffSend Parameter {} was updated| |SendBuffFatal| FATAL | 3 |Test Fatal: {} {} {}|其中SendBuffFatal用于演示 F´ 的 FATAL 事件处理机制——当该事件发出时部署中配置的 FatalHandler 会接管并执行故障响应如断言失败、系统停机等。3.4 参数Parametersparam parameter3: U8 default 12 id 0 set opcode 10 save opcode 11 param parameter4: F32 default 13.14 id 1 set opcode 12 save opcode 13两个参数用于演示 F´ 参数系统的 set/save 双命令机制set opcode对应运行时修改参数值的命令save opcode对应将当前值持久化到参数数据库的命令。3.5 遥测Telemetry| 通道 | 类型 | ID | 更新策略 | | ---- | ---- | -- | -------- | |PacketsSent| U64 | 0 | 每次发送递增 | |NumErrorsInjected| U32 | 1 | update on change仅变化时上报 | |Parameter3| U8 | 2 | update on change | |Parameter4| F32 | 3 | update on change | |SendState|ActiveState| 4 | 每次调度上报 |ActiveState枚举仅含两个状态SEND_IDLE空闲与SEND_ACTIVE发送中用于 GDS 地面站观察组件当前是否处于发包状态。4. 核心实现调度驱动的发送流水线组件实现类SendBuffImpl继承自自动生成的SendBuffComponentBase核心状态量包括发送使能标志m_sendPackets、错误注入标志m_injectError、当前包 IDm_currPacketId、已发包数m_buffsSent与已注入错误数m_errorsInjected见 SendBuffComponentImpl.hpp。4.1 调度入口SchedIn_handlerSendBuffApp本身是 queued 组件没有自己的线程其处理完全由速率组通过SchedIn端口驱动。SchedIn_handlerSendBuffComponentImpl.cpp的执行分两个阶段阶段一先清空消息队列MsgDispatchStatus stat MSG_DISPATCH_OK; while (MSG_DISPATCH_OK stat) { stat this-doDispatch(); // 处理队列中的命令等消息 FW_ASSERT(stat ! MSG_DISPATCH_ERROR); }由于组件是 queued 类型下发到它的命令先进入消息队列调度回调第一件事就是doDispatch()把所有积压消息如SB_START_PKTS、SB_INJECT_PKT_ERROR处理完毕确保命令对状态标志的修改在本周期发包判断之前生效。阶段二按使能状态构造并发送数据包if (this-m_sendPackets) { if (!this-m_firstPacketSent) { this-m_firstPacketSent true; this-log_ACTIVITY_HI_FirstPacketSent(this-m_currPacketId); this-tlmWrite_NumErrorsInjected(this-m_errorsInjected); } this-m_testBuff.resetSer(); // 重置序列化指针 this-m_testBuff.serializeFrom(this-m_currPacketId); // 1) 写入包 ID this-m_currPacketId; this-m_buffsSent; this-tlmWrite_PacketsSent(this-m_buffsSent); // 2) 更新遥测 // 3) 填充 24 字节测试数据 U8 testData[24]; memset(testData, 0xFF, sizeof(testData)); // 4) 计算累加和校验 U32 csum 0; for (U32 byte 0; byte sizeof(testData); byte) { csum testData[byte]; } // 5) 按需注入错误 if (this-m_injectError) { ... } // 6) 序列化数据与校验和并发送 this-m_testBuff.serializeFrom(testData, sizeof(testData)); this-m_testBuff.serializeFrom(csum); this-Data_out(0, this-m_testBuff); // 通过输出端口发出 } this-m_invocations; this-tlmWrite_SendState(this-m_state);由此可归纳出SendBuffApp 数据包的内存布局这也是它与 RecvBuffApp 之间的隐式线协议偏移字段大小说明0Packet ID4 字节U32单调递增的包序号4Test Data24 字节初始全部为0xFF的测试数据28Checksum4 字节U3224 字节数据的字节累加和4.2 错误注入机制ISF-RBF-002 的实现SB_INJECT_PKT_ERROR命令处理器只做一件事把m_injectError置true并立即回OK响应。真正的破坏动作发生在下一个调度周期的发包流程中if (this-m_injectError) { this-m_injectError false; // 一次性标志用完即复位 this-m_errorsInjected; testData[5] 0; // 破坏第 6 字节由 0xFF 改为 0x00 this-log_WARNING_HI_PacketErrorInserted(this-m_currPacketId - 1); }由于校验和是在破坏数据之前计算的破坏后发出的数据包其校验和必然与接收方重新计算的结果不符从而保证错误一定能被对端检测到——这是演示链路错误检测功能的关键设计。该机制同时满足了需求 ISF-RBF-002 中提供注入错误能力的要求。4.3 参数更新回调parameterUpdated回调在参数被修改时触发根据参数 ID 读取新值并同步到遥测通道同时发送BuffSendParameterUpdated事件case PARAMID_PARAMETER3: { U8 val this-paramGet_parameter3(valid); this-tlmWrite_Parameter3(val); break; } case PARAMID_PARAMETER4: { F32 val this-paramGet_parameter4(valid); this-tlmWrite_Parameter4(val); break; } default: FW_ASSERT(0, id);5. 与接收方 RecvBuffApp 的校验闭环理解SendBuffApp离不开它的对端RecvBuffApp。接收组件在 RecvBuffApp.fpp 中定义了PacketStat结构体作为遥测载体其Data_handlerRecvBuffComponentImpl.cpp按发送方的序列化顺序逆向解析先反序列化包 ID再读取 24 字节数据与校验和然后独立重算校验和并比对U32 sum 0; for (U32 byte 0; byte size; byte) { sum testData[byte]; } if (sum ! csum) { this-m_stats.set_BuffErr(this-m_errBuffs); this-log_WARNING_HI_PacketChecksumError(id); this-m_stats.set_PacketStatus(PacketRecvStatus::PACKET_STATE_ERRORS); }发送方的PacketErrorInserted与接收方的PacketChecksumError两条告警事件在 GDS 中成对出现形成完整的注入 → 传输 → 检出可观测闭环。接收方还维护了PACKET_STATE_NO_PACKETS、PACKET_STATE_OK、PACKET_STATE_ERRORS三态统计并通过PktState遥测上报接收数、错误数与状态。6. 在 Ref 拓扑中的调度与连接SendBuffApp的调度来源是速率组 2 的成员端口 1topology.fpprateGroup2Comp.RateGroupMemberOut[1] - sendBuffComp.SchedIn链路为linuxTimer.CycleOut→rateGroupDriverComp.CycleIn→rateGroup2Comp.CycleIn→sendBuffComp.SchedIn。因此SendBuffApp以速率组 2 的频率被周期驱动每个周期检查一次m_sendPackets标志并决定是否发包。与中间驱动BlockDriverBlockDriver.fpp的连接为sendBuffComp.Data - blockDrv.BufferIn blockDrv.BufferOut - recvBuffComp.DataBlockDriver是一个 active 组件其BufferIn为异步输入端口缓冲区经其内部处理模拟块设备读写后从BufferOut转发给RecvBuffApp构成了完整的生成方 → 驱动 → 消费方三段式数据流演示。7. 构建与运行演示组件以独立 F´ 模块的形式构建CMakeLists.txt 展示了 F´ 模块注册的标准三要素FPP 自动编码输入、实现源文件、头文件register_fprime_module( AUTOCODER_INPUTS ${CMAKE_CURRENT_LIST_DIR}/SendBuffApp.fpp SOURCES ${CMAKE_CURRENT_LIST_DIR}/SendBuffComponentImpl.cpp HEADERS ${CMAKE_CURRENT_LIST_DIR}/SendBuff.hpp ${CMAKE_CURRENT_LIST_DIR}/SendBuffComponentImpl.hpp )其中SendBuff.hpp只是为兼容旧式命名Ref::SendBuff而做的类型别名封装typedef SendBuffImpl SendBuff;。在 Ref 部署下运行演示假设已按 docs/INSTALL.md 完成环境搭建的典型流程为在TestDeploymentsProject/Ref目录下执行fprime-util build构建部署执行fprime-util run启动应用并同时启动 GDSfprime-gds连接地面站在 GDS 命令面板下发命令sendBuffComp.SB_START_PKTS命令码0x10010000观察FirstPacketSent事件与PacketsSent遥测开始递增下发sendBuffComp.SB_INJECT_PKT_ERROR命令码0x10010001观察发送方产生PacketErrorInserted告警、接收方产生PacketChecksumError告警NumErrorsInjected与接收方BuffErr计数同步 1可进一步下发SB_GEN_FATAL带 3 个 U32 参数与SB_GEN_ASSERT带 6 个 U32 参数体验 FATAL 事件与断言触发的故障路径通过parameter3/parameter4的 set/save 命令opcode 偏移 10/11、12/13观察参数更新事件与遥测回读。8. 小结Ref::SendBuffApp虽名为演示组件却是理解 F´ 框架多项核心机制的理想样例它展示了 queued 组件如何在速率组驱动下通过doDispatch()消费命令队列、Drv.DataBuffer的序列化/反序列化用法、校验和 一次性错误注入标志的故障注入设计模式以及命令、事件、参数、遥测在单个组件内的完整声明与实现范式。配合 RecvBuffApp SDD 与 Ref 拓扑定义开发者可以快速掌握在 F´ 中搭建发送方—驱动—接收方缓冲区链路并验证错误处理逻辑的标准方法。【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址: https://gitcode.com/GitHub_Trending/fpr/fprime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表