F´ ComFprime 通信子拓扑深度解析F´ 帧协议上下行的轻量级通信栈实战指南【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址: https://gitcode.com/GitHub_Trending/fpr/fprime导读ComFprime 是 F´F Prime飞行软件与嵌入式系统框架内置的一组通信子拓扑Subtopology它把 F´ 轻量级通信栈中负责组帧/解帧framing/deframing的各个标准组件——Svc.FprimeFramer、Svc.FprimeDeframer、Svc.FprimeRouter、Svc.ComQueue、Svc.FrameAccumulator与Svc.BufferManager——预装配为两种可直接复用的拓扑变体并统一通过ComFprimeConfig配置实例属性。本文基于 ComFprime SDD 并结合仓库源码完整讲解两种变体的接线方式、全部配置项与底层实现细节读完本文你将能够在自己部署的 F´ 拓扑中正确复用 ComFprime把 ByteStream 驱动TCP/UDP/UART或自定义通信接口接到 F´ 的帧协议上下行链路上。1. 设计目标与需求概述ComFprime 子拓扑聚焦于航天器侧的 F´ 帧协议通信栈即把飞行软件内部产生的数据包遥测、事件、文件按 F Prime 格式组帧下行并把外部传入的字节流解帧、路由为命令/文件上行。其需求来自 SDD 中的 SVC-COMFPRIME 系列ID需求描述验证方式SVC-COMFPRIME-001提供 F´framer将 COM 缓冲区转换为 F Prime 格式的帧化数据包下行InspectionSVC-COMFPRIME-002提供 F´deframer将上行传入的数据包解析为 COM 缓冲区InspectionSVC-COMFPRIME-003提供 F´router将解帧后的数据包如命令/文件路由进入飞行软件InspectionSVC-COMFPRIME-004提供内置Svc::ComStub的子拓扑变体用于对接 ByteStream 驱动InspectionSVC-COMFPRIME-005提供期望部署方提供外部Svc::ComInterface的子拓扑变体InspectionSVC-COMFPRIME-006支持通过ComFprimeConfig配置实例属性ID、队列深度、栈大小、优先级、CPU 亲和性Inspection范围界定这些子拓扑只实现F´ 通信协议不提供 CCSDS 组帧/解帧能力也不包含 CDH指令与数据管理功能。需要 CCSDS 空间包/TC/TM 帧能力时应选用同目录下的 ComCcsds 子拓扑见 Svc/Subtopologies/ComCcsds/ComCcsds.fpp。2. 架构与核心组件2.1 实例总览公共构建块两种变体共享同一组核心组件见下表与 ComFprime.fpp 中的实例声明一一对应实例名类型Svc种类核心职责framerSvc.FprimeFramerPassive将 F´ 数据组帧为可传输的数据包deframerSvc.FprimeDeframerPassive从传入数据包中解出 F´ 数据fprimeRouterSvc.FprimeRouterPassive将解帧数据命令/文件等路由进飞行软件comQueueSvc.ComQueueActive为组帧排队数据遥测、事件、文件等带run调度口commsBufferManagerSvc.BufferManagerPassive为子拓扑提供内存分配缓冲池frameAccumulatorSvc.FrameAccumulatorPassive解帧前按帧边界累积完整帧comStubSvc.ComStubPassive仅变体 A将Drv::ByteStreamDriverModel驱动适配为下行链路各实例在 ComFprime.fpp 中的基地址偏移以ComFprimeConfig.BASE_ID为基准依次为comQueue 0x00000、frameAccumulator 0x01000、commsBufferManager 0x02000、deframer 0x03000、framer 0x04000、fprimeRouter 0x05000、comStub 0x06000。基地址默认值为0x03000000见 ComFprimeConfig.fpp部署时应注意与拓扑中其他组件的地址空间不冲突。2.2 两种变体变体 A带 ComStub子拓扑包含Svc::ComStub对外暴露 ByteStream 端口可直接接到你的Drv::ByteStreamDriverModelTCP/UDP/UART 等驱动上。变体 B带外部 ComInterface子拓扑不包含Svc::ComStub需要部署方自行提供一个实现Svc.Com接口的组件如Svc::ComStub、Svc::ComSplitter等并将其与子拓扑的 framer/deframer 端口相连。2.3 运行所需输入根据 SDD 第 2.2 节子拓扑正常工作需要三类接线速率组Rate Groups将调度器输出连接到comQueue.runSvc.ComQueue的调度口。传输端点Transport Endpoint变体 A在你的Drv::ByteStreamDriverModel与子拓扑的ComStub之间接好ByteStream send/recv变体 B提供你自己的Svc::ComInterface并接到子拓扑的 framer/deframer 端口。飞行侧挂接Flight-side hookups将router输出命令/文件接入 CDH 栈如命令分发器Svc.CommandDispatcher、文件上行Svc.FileUplink并将数据源遥测/事件/文件下行接入ComQueue。3. 数据通路详解从源码看数据流ComFprime.fpp 中的两个连接块清晰地刻画了数据流下行Downlink链路comQueue.dataOut - framer.dataIn framer.dataReturnOut - comQueue.dataReturnIn framer.bufferAllocate - commsBufferManager.bufferGetCallee framer.bufferDeallocate - commsBufferManager.bufferSendIn framer.comStatusOut - comQueue.comStatusIn遥测/事件/文件数据先进入comQueue排队comQueue出队后交给framer组帧组帧所需的Fw::Buffer由commsBufferManager缓冲池分配/回收链路状态comStatus回传给comQueue。上行Uplink链路frameAccumulator.bufferDeallocate - commsBufferManager.bufferSendIn frameAccumulator.bufferAllocate - commsBufferManager.bufferGetCallee frameAccumulator.dataOut - deframer.dataIn deframer.dataReturnOut - frameAccumulator.dataReturnIn deframer.dataOut - fprimeRouter.dataIn fprimeRouter.dataReturnOut - deframer.dataReturnIn外部字节流先进frameAccumulator按 F´ 帧格式累积出完整帧再交deframer解帧解出的数据包由fprimeRouter路由到命令分发器或文件上行栈。从Svc.ComQueue的接口定义ComQueue.fpp可以看到三个关键端口comPacketQueueIn异步输入接收Fw.Com队列、bufferQueueIn异步输入接收Fw.BufferSend与run调度口Svc.Sched drop其中run正是 SDD 所述需要速率组驱动的调度输入。变体 A 的Subtopology通过import FramingSubtopology复用全部公共组件仅额外增加comStub及三对端口连接ComFprime.fpp下行framer.dataOut - comStub.dataIn、comStub.dataReturnOut - framer.dataReturnIn、comStub.comStatusOut - framer.comStatusIn上行comStub.dataOut - frameAccumulator.dataIn、frameAccumulator.dataReturnOut - comStub.dataReturnIn。4. 使用方式两种变体的接线模式以下两个 FPP 接线示例取自 SDD 第 3 节接线时请以 ComFprime.fpp 中的确切端口名为准例如变体 A 的子拓扑端口实际为ComFprime.Subtopology.comQueueRun而非ComFprime.Subtopology.comQueue.run。4.1 变体 A — 带Svc::ComStub对接 ByteStream 驱动topology Flight { instance ComFprime.Subtopology # (A1) 提供 ByteStreamDriver 接口例如 Drv.TcpClient instance comDriver: ... # (A2) 调度 ComQueue connections RateGroups { rg.RateGroupMemberOut[0] - ComFprime.Subtopology.comQueueRun } # (A3) 连接 ByteStream 驱动 - 子拓扑提供的 ComStub connections ComDriver { comDriver.$recv - ComFprime.Subtopology.drvReceiveIn ComFprime.Subtopology.drvReceiveReturnOut - comDriver.recvReturnIn ComFprime.Subtopology.drvSendOut - comDriver.$send comDriver.ready - ComFprime.Subtopology.drvConnected } }[!TIP] 若 ByteStream 驱动需要缓冲区管理可使用ComFprime.Subtopology.commsBufferGetCallee与ComFprime.Subtopology.commsBufferSendIn两个端口分别对应commsBufferManager.bufferGetCallee/bufferSendIn见 ComFprime.fpp。变体 A 对外暴露的完整端口清单ComFprime.fpp还包括命令路由commandOut输出路由后的命令包到命令分发器、cmdResponseIn输入命令响应返回 router文件上行fileUplinkOut输出上行文件包到文件处理栈、fileUplinkReturnIn输入文件栈归还缓冲区所有权排队输入数组端口按索引连接comPacketQueueInFw::ComBuffer队列如遥测/事件、bufferQueueInFw::Buffer队列如文件下行、bufferReturnOut出队后归还Fw::Buffer所有权驱动接口drvReceiveIn、drvReceiveReturnOut、drvSendOut、drvConnected见上文 A3 接线调度comQueueRun。4.2 变体 B — 不带Svc::ComStub外部提供 ComInterfacetopology Flight { import ComFprime.FramingSubtopology # (B1) 提供你自己的 ComInterface instance radio: ... # (B2) 调度 ComQueue connections RateGroups { rg.RateGroupMemberOut[0] - ComFprime.comQueue.run } # (B3) 将你的 ComInterface 接到 ComFprime 的 framer/deframer connections Link { # Framer - ComInterface下行 ComFprime.framer.dataOut - radio.dataIn radio.dataReturnOut - ComFprime.framer.dataReturnIn radio.comStatusOut - ComFprime.framer.comStatusIn # ComInterface - FrameAccumulator上行 radio.dataOut - ComFprime.frameAccumulator.dataIn ComFprime.frameAccumulator.dataReturnOut - radio.dataReturnIn } }[!NOTE] 在变体 B 中ComFprime.FramingSubtopology不定义comStub实例且上行/下行与 ComInterface 的 5 个连接2 个输出、3 个输入必须由使用方在部署中自行建立详见 ComFprime.fpp 顶部的用法注释。5. 配置详解ComFprimeConfigSDD 明确要求只配置 ComFprime 子拓扑自身拥有的实例属性所有配置旋钮统一位于Svc/Subtopologies/ComFprime/ComFprimeConfig/ComFprimeConfig.fpp5.1 组件属性ComFprimeConfig.fpp下表汇总了 ComFprimeConfig.fpp 中的全部常量及其默认值供实战参考配置项所属模块默认值说明BASE_IDComFprimeConfig0x03000000子拓扑实例基地址各组件在此基础上偏移comQueueQueueSizes50ComQueue消息队列深度comQueueStackSizes64 * 1024ComQueue任务栈大小comQueuePriorities29ComQueue任务的 RTOS 优先级comQueueCpuAffinitiesOs.TASK_DEFAULTCPU 亲和性默认不绑定核心eventsQueueDepths100事件子队列深度最高优先级tlmQueueDepths500遥测子队列深度fileQueueDepths100文件下行子队列深度eventsQueuePriorities0事件子队列优先级最高tlmQueuePriorities2遥测子队列优先级fileQueuePriorities1文件子队列优先级CpuAffinities默认值Os.TASK_DEFAULT表示不进行核绑定无固定核心。若部署硬件为多核且需要为通信任务分配专用核心可在此改为具体核号。5.2 ComQueue 排队配置源码中的实际落地QueueDepths与QueuePriorities并不直接作为实例属性生效而是通过ComQueue的configComponents阶段写入其QueueConfigurationTable见 ComFprime.fppSvc::ComQueue::QueueConfigurationTable configurationTable; // Events最高优先级 configurationTable.entries[Ports_ComPacketQueue::EVENTS].depth ComFprimeConfig::QueueDepths::events; configurationTable.entries[Ports_ComPacketQueue::EVENTS].priority ComFprimeConfig::QueuePriorities::events; // Telemetry configurationTable.entries[Ports_ComPacketQueue::TELEMETRY].depth ComFprimeConfig::QueueDepths::tlm; configurationTable.entries[Ports_ComPacketQueue::TELEMETRY].priority ComFprimeConfig::QueuePriorities::tlm; // File Downlink Queuebuffer 类队列排在 packet 队列之后 configurationTable.entries[Ports_ComPacketQueue::NUM_CONSTANTS Ports_ComBufferQueue::FILE].depth ComFprimeConfig::QueueDepths::file; configurationTable.entries[Ports_ComPacketQueue::NUM_CONSTANTS Ports_ComBufferQueue::FILE].priority ComFprimeConfig::QueuePriorities::file; // 分配器标识为 0MallocAllocator 会忽略该值 ComFprime::comQueue.configure(configurationTable, 0, ComFprime::Allocation::memAllocator);队列类型枚举定义于 ComFprime.fppPorts_ComPacketQueue含EVENTS、TELEMETRYU8 枚举Ports_ComBufferQueue含FILE。可见comQueue实际由三个子队列构成events优先级 0 最高、tlm优先级 2 最低、file居中。注意上表中的优先级是子队列内部相对优先级与 5.1 中Priorities.comQueue 29RTOS 任务优先级含义不同二者并存、互不替代。5.3 Buffer Manager 缓冲池配置module BuffMgrmodule BuffMgr为commsBufferManager提供缓冲池bins常量ComFprimeConfig.fpp常量默认值说明frameAccumulatorSize2048frameAccumulator内部缓冲大小字节commsBuffSize2048bin[0] 普通通信缓冲大小字节commsFileBuffSize3000bin[1] 文件通信缓冲大小字节commsBuffCount20bin[0] 缓冲数量commsFileBuffCount30bin[1] 缓冲数量commsBuffMgrId200缓冲池管理 ID这些常量在commsBufferManager的configComponents阶段写入Svc::BufferManager::BufferBins结构并调用setupComFprime.fppmemset(ConfigObjects::ComFprime_commsBufferManager::bins, 0, sizeof(...bins)); ConfigObjects::ComFprime_commsBufferManager::bins.bins[0].bufferSize ComFprimeConfig::BuffMgr::commsBuffSize; ConfigObjects::ComFprime_commsBufferManager::bins.bins[0].numBuffers ComFprimeConfig::BuffMgr::commsBuffCount; ConfigObjects::ComFprime_commsBufferManager::bins.bins[1].bufferSize ComFprimeConfig::BuffMgr::commsFileBuffSize; ConfigObjects::ComFprime_commsBufferManager::bins.bins[1].numBuffers ComFprimeConfig::BuffMgr::commsFileBuffCount; ComFprime::commsBufferManager.setup(ComFprimeConfig::BuffMgr::commsBuffMgrId, 0, ComFprime::Allocation::memAllocator, bins);同理frameAccumulator在configComponents阶段以FprimeFrameDetector作为帧检测器完成配置Svc::FrameDetectors::FprimeFrameDetector frameDetector; ComFprime::frameAccumulator.configure( ConfigObjects::ComFprime_frameAccumulator::frameDetector, 1, ComFprime::Allocation::memAllocator, ComFprimeConfig::BuffMgr::frameAccumulatorSize );5.4 分配器Allocator整个子拓扑的内存分配统一走ComFprime::Allocation::memAllocator其实现位于 ComFprimeSubtopologyConfig.cppnamespace ComFprime { namespace Allocation { // 该实例可在 ComFprime 子拓扑中替换为其他分配器 Fw::MallocAllocator mallocatorInstance; Fw::MemAllocator memAllocator mallocatorInstance; } // namespace Allocation } // namespace ComFprime默认使用Fw::MallocAllocator堆分配。对于安全关键/资源受限的嵌入式部署可在 ComFprimeSubtopologyConfig.hpp 声明的ComFprime::Allocation命名空间中替换为静态内存池等自定义Fw::MemAllocator实现无需改动子拓扑接线。5.5 生命周期管理comQueue、frameAccumulator、commsBufferManager三个带资源实例均注册了tearDownComponents阶段的清理逻辑comQueue.cleanup()、frameAccumulator.cleanup()、commsBufferManager.cleanup()见 ComFprime.fpp框架会自动在拓扑拆除阶段释放其分配的资源部署方无需额外处理。5.6 辅助定义文件子拓扑还附带两个轻量级辅助头文件供部署的TopologyDefs.hpp/PingEntries.hpp复用SubtopologyTopologyDefs.hpp定义ComFprime::SubtopologyState当前为空结构无需外部状态与ComFprime::TopologyStatePingEntries.hpp定义PingEntries命名空间当前无支持 Ping 的组件为空。6. 需求追溯矩阵需求 ID满足者实例/类型SVC-COMFPRIME-001framer—Svc.FprimeFramerSVC-COMFPRIME-002deframer—Svc.FprimeDeframerSVC-COMFPRIME-003router—Svc.FprimeRouterSVC-COMFPRIME-004SubtopologySVC-COMFPRIME-005FramingSubtopologySVC-COMFPRIME-006ComFprimeConfig7. 部署自检清单结合 SDD 与源码实现接入 ComFprime 时建议逐项确认基地址唯一性ComFprimeConfig.BASE_ID默认0x03000000不与部署中其他组件地址空间重叠速率组驱动已把某个RateGroupMemberOut接到comQueueRun变体 A/comQueue.run变体 B否则ComQueue不会输出排队的遥测/事件传输端点完整接线变体 A 的 4 根驱动线$recv、recvReturnIn、$send、ready均已接好变体 B 的 5 根 ComInterface 线2 出 3 入均已建立飞行侧挂接commandOut/cmdResponseIn已连命令分发器fileUplinkOut/fileUplinkReturnIn已连文件上行栈遥测/事件源已连comPacketQueueIn文件下行源已连bufferQueueIn缓冲池容量匹配BuffMgr的缓冲大小/数量应满足最坏情况下的飞行遥测速率与文件传输并发需求避免commsBufferManager分配失败导致丢帧。通过以上配置ComFprime 即可作为标准 F´ 通信栈的即插即用模块与Drv.TcpClient/Drv.Udp/Drv.PosixUartDriver等 ByteStream 驱动协同工作。如需 CCSDS 协议栈可参考 Svc/Subtopologies/ComCcsds 进行对比选型。【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址: https://gitcode.com/GitHub_Trending/fpr/fprime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
