ARTICLE DETAIL

资讯详情

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

F´ 通信协议(F Prime Protocol)帧格式详解:上下行数据封装的 0xDEADBEEF 帧结构

F´ 通信协议(F Prime Protocol)帧格式详解:上下行数据封装的 0xDEADBEEF 帧结构 F´ 通信协议F Prime Protocol帧格式详解上下行数据封装的 0xDEADBEEF 帧结构【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址: https://gitcode.com/GitHub_Trending/fpr/fprime导读F Prime 协议F Prime protocol是 F´F Prime飞行软件与嵌入式系统框架内置的一套极简通信协议用于地面站GDS与航天器或嵌入式目标之间的上行uplink与下行downlink链路数据封装。本文以 Svc/FprimeProtocol/docs/sdd.md 为骨架结合 Svc/FprimeFramer组帧、Svc/FprimeDeframer解帧与 FPP 类型定义 的源码实现完整讲解帧的 4 个字段、逐字节的内存布局、CRC 校验方式以及由该协议衍生的组帧/解帧/帧检测组件的工作机制。读完本文你将能够从字节层面理解 F´ 的一条通信帧如何构造、如何被校验以及如何在此基础上接入 F´ GDS 快速开展上下行联调。一、协议定位为快速上手 GDS 而生的极简协议F Prime 协议是 F´ 应用可选用的一种最小化通信协议其设计目标非常明确同时服务于**上行地面 → 航天器与下行航天器 → 地面**两条方向的数据传输目标是让开发者**快速接入 F´ GDS地面数据系统**开始联调不提供任何高级特性无加密、无重传、无分段重组、无纠错主要面向测试与初期验证场景在航天器端与地面GDS端两侧均有实现协议对称。从源码结构看仓库把该协议定义为独立的 FPP 模块Svc.FprimeProtocol见 FprimeProtocol.fpp并在其上构建了三个消费者消费者组件源码路径职责Svc::FprimeFramerSvc/FprimeFramer/FprimeFramer.cpp把 F´ 数据包封装成 F Prime 帧发送侧Svc::FprimeDeframerSvc/FprimeDeframer/FprimeDeframer.cpp把 F Prime 帧还原成 F´ 数据包接收侧Svc::FprimeFrameDetectorSvc/FrameAccumulator/FrameDetector/FprimeFrameDetector.cpp在字节流中识别并切分出完整帧流式接收这三者的存在印证了文档的定位协议本身极简但围绕它形成了完整的组帧 → 传输 → 检测 → 解帧链路。二、帧格式四个字段的精确内存布局F Prime 协议的一帧由4 个字段组成全部按大端big-endian序在线上传输字段宽度说明起始字Start word32 位4 字节标识帧开始取值固定为0xDEADBEEF负载长度Payload length32 位4 字节以字节为单位的负载数据长度负载数据Payload data变长一个 F Prime packetF´ 数据包长度由上一字段指定CRC32 位4 字节用于校验帧完整性的循环冗余校验值文档给出了默认配置下的帧格式图[!NOTE] 由于负载长度字段本身占 4 字节F Prime 协议**不支持超过 2^32 - 1 字节约 4 GB**的数据包。2.1 帧头与帧尾的 FPP 类型定义协议文档描述的帧结构在仓库中落成了可自动生成序列化代码的 FPP 类型定义Svc/FprimeProtocol/FprimeProtocol.fppmodule Svc { module FprimeProtocol { type TokenType U32 Describes the frame header format for the F Prime communications protocol struct FrameHeader { startWord: TokenType, lengthField: TokenType, } default { startWord 0xdeadbeef } Describes the frame trailer format for the F Prime communications protocol struct FrameTrailer { crcField: U32 } } }几个值得注意的实现细节TokenType被定义为U32因此起始字与负载长度字段均为 4 字节FrameHeader.startWord的默认值即0xdeadbeef——组帧时无需手动赋值解帧/检测时则用默认值对象作为比对基准FrameTrailer.crcField为 4 字节U32由组帧组件动态计算填充。由此一帧的固定开销为FrameHeader::SERIALIZED_SIZE FrameTrailer::SERIALIZED_SIZE 4 4 4 12字节帧头 8 字节 帧尾 4 字节其余为负载长度。2.2 负载一个 F´ 数据包F Prime packet文档强调负载字段内是一个 F Prime packet即 Fw::Com::ComPacket。其内部布局见 ComPacket.hpp 注释为| packet type (width FwPacketDescriptorType) | packet type-specific data |FwPacketDescriptorType包类型描述符至少占一个可配置宽度的字段用于标识包的类型。在默认配置default/config/ComCfg.fpp中dictionary type FwPacketDescriptorType U16即默认 2 字节、最大 65535 种包类型标识该宽度可通过配置调整因此文档中特别说明至少包含一个可配置宽度的FwPacketDescriptorType字段。序列化的具体动作在 ComPacket.cpp 中实现serializeBase()将m_type以FwPacketDescriptorType写入缓冲区deserializeBase()反向读出。实际承载的可以是遥测包、事件包、命令包等它们都继承自Fw::ComPacket。三、组帧实现FprimeFramer 如何构造一帧下行方向Svc::FprimeFramer组件负责把收到的 F´ 数据包包装成 F Prime 帧。其核心处理逻辑位于 FprimeFramer.cpp 的 dataIn_handler完整步骤如下计算帧总大小帧大小 FrameHeader::SERIALIZED_SIZE data.getSize() FrameTrailer::SERIALIZED_SIZE即帧头 负载 帧尾分配输出缓冲通过bufferAllocate_out端口申请一块能容纳整帧的Fw::Buffer若分配失败或缓冲不足则上报NoBufferAvailable告警事件并丢弃该包事件定义见 FprimeFramer.fpp序列化帧头header.set_lengthField(data.getSize())写入负载长度起始字无需赋值——正如源码注释所言0xDEADBEEF is already set as the default value for the header startWord field in the FPP type definition见 FprimeFramer.cpp序列化负载将原始数据包字节原样OMIT_LENGTH不额外写长度前缀拷贝进帧缓冲计算并序列化 CRC用Utils::Hash对帧头 负载做哈希取hashBuffer.asBigEndianU32()作为 32 位校验值写入帧尾FprimeFramer.cpp输出整帧通过dataOut端口送出帧缓冲所有权移交给下游如Svc::ComStub等通信适配组件归还原始缓冲通过dataReturnOut端口把输入的数据包缓冲归还给原发送者。组件对外端口FprimeFramer.fpp包括端口类型名称说明guarded inputdataIn接收待组帧的数据包Svc.ComDataWithContextoutputdataOut输出封装完成的帧sync input / outputdataReturnIn/dataReturnOut帧缓冲 / 原始数据缓冲的所有权归还通道outputbufferAllocate/bufferDeallocate帧缓冲的申请与释放sync input / outputcomStatusIn/comStatusOut与上游Svc::ComQueue联动的通信状态透传四、解帧实现FprimeDeframer 如何校验并还原上行方向Svc::FprimeDeframer组件接收一帧经过四道校验后把负载还原成 F´ 数据包FprimeDeframer.cpp 的 dataIn_handler最小长度检查若输入缓冲不足帧头 帧尾8 4 12 字节直接上报InvalidBufferReceived并丢弃起始字校验反序列化帧头后与默认FrameHeader对象的startWord0xDEADBEEF比对不一致则上报InvalidStartWord并丢弃FprimeDeframer.cpp长度校验按帧头lengthField计算期望帧大小 帧头 lengthField 帧尾与输入缓冲实际大小比对不符则上报InvalidLengthReceived并丢弃FprimeDeframer.cppCRC 校验定位到帧尾偏移处反序列化crcField对帧头 负载逐字节重新计算哈希与帧内携带的 CRC 比对不符则上报InvalidChecksum并丢弃FprimeDeframer.cpp。一个值得注意的细节在通过起始字与长度校验后解帧器会尝试从负载头部读取FwPacketDescriptorType并映射为 APID将其写入FrameContext透传给下游路由器FprimeDeframer.cpp若 APID 无效则置为INVALID_UNINITIALIZED交由下游组件处理。全部校验通过后解帧器用data.advance(FrameHeader::SERIALIZED_SIZE)跳过帧头、用setSize(... - FrameTrailer::SERIALIZED_SIZE)去掉帧尾从而把缓冲原地削成纯负载通过dataOut端口输出。五、流式帧检测FrameDetector 如何从字节流中切帧在真实的串口 / 网络链路上接收端往往拿到的是无边界连续的字节流。F´ 的Svc::FrameAccumulator组件借助帧检测器完成从流中识别完整帧的任务其中 F Prime 协议的检测器实现为 FprimeFrameDetector.cpp。其detect()核心逻辑与解帧校验高度一致但工作对象是环形缓冲CircularBuffer并返回三种状态返回状态含义触发条件MORE_DATA_NEEDED数据不足等待更多字节缓冲内字节数少于帧头 帧尾或少于lengthField声明的完整帧长NO_FRAME_DETECTED帧无效丢弃起始字不匹配、声明长度溢出/超容量、CRC 校验失败FRAME_DETECTED发现一帧起始字、长度、CRC 全部通过输出帧大小lengthField 12CRC 计算同样对帧头 负载逐字节进行并与帧尾crcField比对FprimeFrameDetector.cpp若 CRC 不符说明数据已损坏而F Prime 协议本身过于简单没有恢复手段只能丢弃该帧源码注释原文。此外检测器对长度字段做了溢出防护static_assert保证帧头/帧尾固定开销相加不溢出运行时再用显式的加法检查确保lengthField 12不会发生无符号回绕FprimeFrameDetector.cpp避免恶意或损坏帧引发越界。六、实战要点与约束小结基于文档与源码整理 F Prime 协议使用时的关键约束与建议帧固定开销 12 字节每帧 8 字节帧头0xDEADBEEF 4 字节长度 4 字节 CRC。对短负载如单条遥测而言开销占比可观适合测试链路不适合追求带宽利用率的场合单帧上限约 4 GB受 4 字节lengthField限制同时组帧侧在 FprimeFramer.cpp 中通过FW_ASSERT对帧大小与缓冲类型上限做了双重保护起始字是唯一同步标记解帧与帧检测都靠0xDEADBEEF对齐帧边界协议本身不含长度前缀式的自描述信息因此对字节错位 / 损坏的容错能力有限符合其测试用途定位CRC 计算范围覆盖帧头 负载共lengthField 8字节不含帧尾本身典型接入方式下行链路为Svc::ComQueue → Svc::FprimeFramer → 通信适配组件如 Svc::ComStub上行链路为通信适配组件 → Svc::FprimeDeframer → 数据分发或经由Svc::FrameAccumulator Svc::FprimeFrameDetector处理流式字节组件间交互细节可参考 Svc/FprimeFramer/docs/sdd.md 与 Svc/Interfaces/docs/sdd.mdFwPacketDescriptorType 宽度可配置默认U16default/config/ComCfg.fppF´ 的命令 / 事件 / 遥测 / 参数缓冲大小均以它为基准扣除描述符字节见 default/config/FpConstants.fpp修改配置会影响整条链路的缓冲布局。七、总结F Prime 协议以起始字 长度 负载 CRC的四字段结构为 F´ 的上下行链路提供了一套可快速联调、零依赖、易于调试的帧封装方案。虽然它刻意不做高级特性但仓库中围绕它实现的 FprimeFramer、FprimeDeframer 与 FprimeFrameDetector 构成了完整的组帧—传输—切帧—校验—还原闭环成为理解 F´ 通信栈底层字节行为、以及后续替换为其他帧协议如 CCSDS 系协议时的最佳对照样本。无论是接入 F´ GDS 做快速测试还是自研帧协议从读懂这 12 字节固定开销与0xDEADBEEF起始字开始都能让你对整条数据链路了然于胸。【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址: https://gitcode.com/GitHub_Trending/fpr/fprime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表