☰
F´ 框架软件架构导读:基于 Doxygen 主页的组件库、端口模型与包结构全解析
2026/9/25 3:34:23 网站建设 项目流程
  • 嵌入式
  • 系统编程

【免费下载链接】fprime

F´ - A flight software and embedded systems framework

项目地址:https://gitcode.com/gh_mirrors/fpri/fprime
点击查看免费下载

本篇技术指南以 F´(F Prime)开源仓库中 docs/doxygen/mainpage.md 为骨架,系统梳理 F´ 自动生成文档的导航结构,并深入剖析其背后的软件分层:Fw(框架核心)、Os(操作系统抽象)、Svc(标准服务组件)、Drv(硬件驱动)与Utils(通用工具)。读完本文,你将掌握 F´ 各包的职责边界、核心端口/类在源码中的实际落点,以及如何顺着 Doxygen 文档树快速定位到具体的组件实现与测试代码。

一、mainpage.md:F´ 软件描述文档的总入口

mainpage.md是 F´ 工程 Doxygen 文档生成体系的主页面(mainpage)。文件首行的\mainpage指令声明了它在 Doxygen 文档树中的根节点地位,随后的一段文字明确了该文档的性质:

This is the F´ automatically generated documentation. The below guides represent the software description documentation (SDD) for the F´ components.

也就是说,这份文档是 F´软件描述文档(SDD)与C++ 代码文档(Namespace 与 Classes 部分)的统一入口。文件通过\page与\subpage指令将全部内容划分为五大包(package):

包名文档定位(原文)职责概括
FwCore classes, components, and ports框架核心:支撑框架运行的基础类、组件与端口,含各类组件的基类与系统核心类型
OsOperating system abstraction layer操作系统抽象层:互斥量、队列、任务、文件系统等 OS 功能
SvcStandard components标准服务组件:命令与数据处理组件,用于构建更完整的应用
DrvDrivers for hardware functions硬件驱动:含示例块驱动及 Linux 硬件驱动
UtilsClasses for general applications通用工具类:面向各种用途的通用类

这种组织方式与仓库目录一一对应(Fw/、Os/、Svc/、Drv/、Utils/五个顶层目录),构成了 F´ 源码阅读与二次开发的"地图"。

二、Fw 包:框架核心类、组件与端口

mainpage 对Fw包的定位是"提供支撑 F´ 的核心类、组件与端口,是组件构建的基类所在",并特别强调Fw::Types提供了系统中的核心类型。它通过 11 个\subpage展开以下子主题,每个子主题都能在源码中找到精确对应:

2.1 Buffer:可序列化缓冲区与 BufferSend/BufferGet 端口

FwBufferSerializableBufferGetBufferSend对应 Fw/Buffer/ 目录。其 FPP 模型 Fw/Buffer/Buffer.fpp 定义了:

  • type Buffer:缓冲区类型;
  • port BufferSend(ref fwBuffer: Fw.Buffer):用于发送缓冲区的输出端口;
  • port BufferGet($size: U32) -> Fw.Buffer:按指定大小获取缓冲区的输入端口。

缓冲区正是 F´ 组件间传递数据块(如遥测包、文件传输数据)的标准载体,BufferSend与BufferGet形成了"借出—归还"的典型缓冲管理模型,与Svc::BufferManager组件配合实现缓冲池分配。

2.2 Cmd:命令注册、发送与响应三端口

FwCmdFwCmdResponseFwCmdReg对应 Fw/Cmd/Cmd.fpp,是 F´ 命令链路的核心接口定义,包含:

  • port CmdReg(opCode: FwOpcodeType):组件向命令分发器注册自身可处理的命令码;
  • port Cmd(opCode, cmdSeq: U32, ref args: CmdArgBuffer):命令分发器向组件下发命令,参数经CmdArgBuffer序列化传递;
  • enum CmdResponse:命令响应状态码,取值OK = 0、INVALID_OPCODE = 1、VALIDATION_ERROR = 2、FORMAT_ERROR = 3、EXECUTION_ERROR = 4、BUSY = 5,覆盖了命令生命周期中"未注册、校验失败、反序列化失败、执行失败、组件忙"等全部失败形态;
  • port CmdResponse(opCode, cmdSeq, response: CmdResponse):组件向分发器回送执行结果。

这套端口被 Svc/CmdDispatcher/ 的CommandDispatcher实现,用于将地面指令路由到目标组件并汇总响应。

2.3 Com:通信包缓冲传递端口

FwComPort对应 Fw/Com/Com.fpp,定义了数据流(遥测下行、上行指令包等)传递的通用端口:

port Com( ref data: ComBuffer @< Buffer containing packet data context: U32 @< Call context value; meaning chosen by user )

context参数由用户自定义含义(如区分通道或方向),是下行数据链中连接各处理组件(如ComQueue、Framer、GroundInterface)的标准接口。

2.4 FilePacket:文件传输的分组协议

FwFilePacketClasses对应 Fw/FilePacket/ 目录。从源码 Fw/FilePacket/FilePacket.hpp 看,Fw::FilePacket是一个union 联合体,定义了文件传输的四种分组类型:

typedef enum { T_START = 0, //!< 起始包 T_DATA = 1, //!< 数据包 T_END = 2, //!< 结束包 T_CANCEL = 3 //!< 取消包 } ...

其下配套StartPacket、DataPacket、EndPacket、CancelPacket、Header、PathName等实现类,构成完整的文件上行/下行分包协议,被 Svc/FileDownlink/ 与 Svc/FileUplink/ 组件实际使用。

2.5 Log/LogText:事件日志与文本日志双端口

FwLogLogText对应 Fw/Log/Log.fpp,是 F´ 事件(Event)报告模型的定义:

  • enum LogSeverity:事件严重等级,FATAL = 1(致命不可恢复)、WARNING_HI = 2(严重但可恢复)、WARNING_LO = 3、COMMAND = 4(指令活动)、ACTIVITY_HI = 5、ACTIVITY_LO = 6、DIAGNOSTIC = 7(诊断信息);
  • port Log($id, ref timeTag: Fw.Time, $severity, ref args: LogBuffer):携带序列化参数的二进制事件端口;
  • port LogText($id, ref timeTag, $severity, ref $text: Fw.TextLogString):携带文本消息的文本事件端口,文档注释特别提示"用于开发与调试,飞行时关闭"。

日志消费方包括 Svc/ActiveLogger/(二进制事件记录)与 Svc/ActiveTextLogger/、Svc/PassiveConsoleTextLogger/(文本输出到控制台或文件)。

2.6 Obj 与 Port:对象注册与端口基类

  • FwObjClasses对应 Fw/Obj/ 目录。基类Fw::ObjBase(见 Fw/Obj/ObjBase.hpp)是整个"ISF 对象类层次"的根基,按编译开关决定是否存储对象名(FW_OBJECT_NAMES == 1)与提供对象注册(FW_OBJECT_REGISTRATION == 1);SimpleObjRegistry提供最简单的对象注册表实现。
  • FwPortClasses对应 Fw/Port/ 目录。Fw::PortBase(见 Fw/Port/PortBase.hpp)继承自ObjBase,是所有端口的公共基类,核心成员是连接对象指针m_connObj,并提供了isConnected()连接状态查询;当FW_PORT_TRACING == 1时还支持全局/单端口调用追踪(setTrace、ovrTrace)。其派生体系InputPortBase/OutputPortBase/InputSerializePort/OutputSerializePort构成了 F´ 类型化端口机制的基础——正是这种类型化端口连接,为系统提供了 README 所称的"强编译期正确性保证"。

2.7 Prm、Time、Tlm:参数、时间与遥测端口

  • FwPrmGetPrmSet对应 Fw/Prm/Prm.fpp,定义参数**读取(PrmGet)与写入(PrmSet)**端口,参数值经PrmBuffer序列化,由 Svc/PrmDb/ 参数数据库组件实现持久化。
  • FwTimePort对应 Fw/Time/Time.fpp,定义port Time(ref $time: Fw.Time),将Fw::Time(见 Fw/Time/Time.hpp)时间标签注入各组件;时间源通常由 Svc/Time/ 或 Svc/LinuxTime/ 提供。
  • FwTlmPort对应 Fw/Tlm/Tlm.fpp,定义遥测通道上报Tlm($id, ref timeTag, ref val: TlmBuffer)与按 ID 读取TlmGet两个端口,是 Svc/TlmChan/ 遥测通道存储与 Svc/TlmPacketizer/ 遥测组包的关键接口。

2.8 Types:全系统核心类型

FwTypeClasses对应 Fw/Types/ 目录,是 mainpage 特别点名的核心。其关键组件包括:

  • 序列化框架:Fw::Serializable(见 Fw/Types/Serializable.hpp)定义了纯虚接口serialize/deserialize以及SerializeStatus状态枚举——FW_SERIALIZE_OK、FW_SERIALIZE_FORMAT_ERROR、FW_SERIALIZE_NO_ROOM_LEFT、FW_DESERIALIZE_BUFFER_EMPTY、FW_DESERIALIZE_FORMAT_ERROR、FW_DESERIALIZE_SIZE_MISMATCH、FW_DESERIALIZE_TYPE_MISMATCH,覆盖了序列化/反序列化的全部成败形态;配套的SerializeBufferBase提供对U8/I8/U16/I16/U32/I32/U64/I64/F32/F64/bool/指针/原始缓冲的按位序列化重载,且 16/32/64 位整数均受FW_HAS_16_BIT、FW_HAS_32_BIT、FW_HAS_64_BIT编译开关控制——这正是 F´ 支持从 8 位 MCU 到 64 位多核处理器跨平台的关键设计。
  • 字符串体系:String、StringType、EightyCharString、InternalInterfaceString等长度受限字符串类型;
  • 分配器抽象:MemAllocator及MallocAllocator、MmapAllocator实现;
  • 类型定义:BasicTypes.hpp、PolyType(多态类型)、SerialBuffer等。

三、Os 包:操作系统抽象层

mainpage 对Os包的定位是"为 F´ 提供互斥量、队列、任务与文件系统等基本系统功能"。该包以"公共实现 + 平台后端"的两段式设计著称,从 Os/Queue.hpp 的注释即可印证:"实现分两部分,QueueCommon.cpp存放与 OS 无关的共享代码,.cpp文件存放 OS 特定后端(如Posix/Queue.cpp)"。

3.1 Queue:组件间消息队列

队列是 F´ 组件间消息传递的底层机制。Os::Queue(见 Os/Queue.hpp)提供:

  • QueueStatus状态枚举:QUEUE_OK、QUEUE_NO_MORE_MSGS、QUEUE_UNINITIALIZED、QUEUE_SIZE_MISMATCH、QUEUE_SEND_ERROR、QUEUE_RECEIVE_ERROR、QUEUE_INVALID_PRIORITY、QUEUE_EMPTY_BUFFER、QUEUE_FULL、QUEUE_UNKNOWN_ERROR;
  • QueueBlocking阻塞模式:QUEUE_BLOCKING(收消息阻塞等待)/QUEUE_NONBLOCKING(无消息立即返回);
  • create(name, depth, msgSize)创建队列,send/receive支持序列化缓冲与原始字节两种载荷形态,另提供getNumMsgs、getMaxMsgs(高水位)等诊断查询。

平台实现分散在 Os/Posix/IPCQueue.cpp、Os/Pthreads/(含 FIFO/优先级两种缓冲队列)以及 Os/MacOs/IPCQueueStub.cpp 等文件中。

3.2 Task:任务/线程抽象

Os::Task(见 Os/Task.hpp)抽象线程创建与调度:

  • TaskStatus枚举覆盖TASK_OK、TASK_INVALID_PARAMS、TASK_INVALID_STACK、TASK_UNKNOWN_ERROR、TASK_INVALID_AFFINITY、TASK_DELAY_ERROR、TASK_JOIN_ERROR、TASK_ERROR_RESOURCES、TASK_ERROR_PERMISSION;
  • 推荐签名start(name, routine, arg, priority, stackSize, cpuAffinity, identifier),并保留一个被DEPRECATED标记的旧签名以提示迁移;
  • 提供delay、join、suspend、resume、isStarted、CPU 亲和性设置与任务注册表(TaskRegistry)机制。

平台后端见 Os/Posix/Task.cpp、Os/Pthreads/、Os/Baremetal/Task.cpp 等。此外,mainpage 中以\subpage OsQueue单列队列主题,其余 OS 能力(互斥量 Os/Mutex.hpp、文件系统 Os/FileSystem.hpp、目录 Os/Directory.hpp、文件 Os/File.hpp、看门狗 Os/WatchdogTimer.hpp、系统资源 Os/SystemResources.hpp)同样遵循该抽象模式。

四、Svc 包:标准服务组件库

mainpage 指出Svc提供"命令与数据处理组件,用于构建更完整的应用"。它通过 25 个\subpage展开,与仓库Svc/目录逐项对应,可以归纳为几大类:

命令与序列链路

  • SvcCmdDispatcherComponent→ Svc/CmdDispatcher/:命令分发中枢,将Fw.Cmd端口收到的指令按 opcode 路由到注册组件;
  • SvcCmdSequencerComponent与SvcAMPCSSequenceClass→ Svc/CmdSequencer/:命令序列器,可加载.fseq序列文件(样例见 Svc/CmdSequencer/samples/)顺序/时间触发执行,支持 AMPCS 序列格式(对应 Svc/CmdSequencer/FPrimeSequence.cpp 等实现);
  • SvcPingPort→ Svc/Ping/、SvcWatchDogPort→ Svc/WatchDog/、SvcSchedPort→ Svc/Sched/:分别为健康检查的 Ping 端口、看门狗端口与周期性调度端口。

遥测、参数与健康

  • SvcTlmChanComponent→ Svc/TlmChan/:遥测通道数据库;SvcTlmPacketizerComponent与SvcTlmPacketizerComponentDictionary→ Svc/TlmPacketizer/:按字典将通道组包下行;
  • SvcPrmDbComponent→ Svc/PrmDb/:参数数据库;SvcPolyDbComponent→ Svc/PolyDb/、SvcPolyPort→ Svc/PolyIf/:多态参数读写;
  • SvcHealthComponent→ Svc/Health/:组件健康监控(基于 Ping 心跳)。

日志与会话

  • SvcActiveLoggerComponent→ Svc/ActiveLogger/、SvcActiveTextLoggerComponent→ Svc/ActiveTextLogger/、SvcPassiveConsoleTextLoggerComponent→ Svc/PassiveConsoleTextLogger/:事件日志三类消费组件;SvcAssertFatalAdapterComponent→ Svc/AssertFatalAdapter/:将断言失败适配为致命事件。

数据上下行与帧协议

  • SvcFileUplinkComponent→ Svc/FileUplink/、SvcFileDownlinkComponent→ Svc/FileDownlink/、SvcFileManagerComponent→ Svc/FileManager/:文件传输与文件系统操作;
  • SvcFramerComponent→ Svc/Framer/、SvcDeframerComponent→ Svc/Deframer/、SvcFramingProtocol→ Svc/FramingProtocol/:帧封装/解帧与可插拔帧协议(如 CCSDS);
  • SvcGenericHubComponent→ Svc/GenericHub/、SvcGenericRepeaterComponent:通用数据汇聚与转发;
  • SvcFatalPort→ Svc/Fatal/、SvcFatalHandlerComponent→ Svc/FatalHandler/:致命错误上报与处理(如落盘记录);
  • SvcBufferManagerComponent→ Svc/BufferManager/:缓冲池管理。

驱动辅助与时间

  • SvcRateGroupDriverComponent→ Svc/RateGroupDriver/:将速率组(Rate Group)驱动的周期信号分发给多个 Svc/ActiveRateGroup/(SvcActiveRateGroupComponent);
  • SvcLinuxTimeComponent→ Svc/LinuxTime/:Linux 时间源;SvcStaticMemoryComponent→ Svc/StaticMemory/:静态内存段管理。

以上每个组件目录内均同时存在.fpp模型文件(接口定义)、ComponentImpl.cpp/.hpp(实现)与test/或docs/(单元测试与文档),例如Svc/BufferManager.fpp、Svc/CmdDispatcher.fpp等,构成"模型—实现—验证"的完整开发闭环。

五、Drv 包:硬件驱动

mainpage 对Drv的定位是"提供支撑各种硬件功能的驱动,含示例块驱动以及支持 Linux 硬件功能的各类驱动"。其 7 个\subpage对应如下:

  • DrvBlockDriverComponent→ Drv/BlockDriver/:示例块驱动组件,含遥测(Drv/BlockDriver/Tlm.fppi)与事件定义,是编写驱动组件的最佳参照;
  • DrvByteStreamDriverModel→ Drv/ByteStreamDriverModel/:字节流驱动模型,定义了驱动领域的标准端口与状态。从 Drv/ByteStreamDriverModel/ByteStreamDriverModel.fpp 可见:
    • SendStatus:SEND_OK = 0(发送成功)/SEND_RETRY = 1(应重试)/SEND_ERROR = 2(发送出错,重试可能成功);
    • RecvStatus:RECV_OK = 0/RECV_ERROR = 1;
    • PollStatus:POLL_OK = 0(成功收到数据)/POLL_RETRY = 1(暂无数据,稍后再试)/POLL_ERROR = 2;
    • 以及ByteStreamSend、ByteStreamRecv端口。这一模型为上层组件与底层串口/网络驱动解耦提供了统一契约;
  • DrvIp→ Drv/Ip/:TCP/UDP 套接字公共实现(Drv/Ip/IpSocket.hpp、Drv/Ip/SocketReadTask.hpp 等);
  • DrvTcpClient→ Drv/TcpClient/、DrvTcpServer→ Drv/TcpServer/、DrvUdp→ Drv/Udp/:TCP 客户端/服务端与 UDP 组件;
  • DrvUartFramerComponent:对应 Linux UART 驱动 Drv/LinuxUartDriver/(含事件 Drv/LinuxUartDriver/Events.fppi 与遥测 Drv/LinuxUartDriver/Telemetry.fppi)。

仓库Drv/目录还包含GpioDriverPorts、I2cDriverPorts、SpiDriverPorts端口定义以及 Drv/LinuxGpioDriver/、Drv/LinuxI2cDriver/、Drv/LinuxSpiDriver/ 等 Linux 驱动实现,与 RPI 示例部署(RPI/README.md)中的嵌入式场景配套。

六、Utils 包:通用工具类

Utils提供"面向各种用途的通用类",mainpage 列出四个主题:

  • UtilsHashClass→ Utils/Hash/:哈希工具(CRC 等,与 Utils/CRCChecker.hpp 配合用于文件校验);
  • UtilsLockGuardClass→ Utils/LockGuard.hpp:RAII 风格的锁守卫,简化互斥量生命周期管理;
  • UtilsRateLimiterClass→ Utils/RateLimiter.hpp:速率限制器;
  • UtilsTokenBucketClass→ Utils/TokenBucket.hpp:令牌桶限流器,类内定义了MAX_TOKEN_BUCKET_TOKENS 1000的令牌上限,基于时间戳(依赖 Fw/Time/Time.hpp)计算令牌补充速率,用于平滑突发流量。

从源码结构可以推断,Utils的设计目标是提供与具体组件解耦、可在任意 F´ 应用中直接复用的基础能力;Utils/test/与Utils/Types/目录则为这些工具提供了单元测试与配套类型。

七、如何高效使用这份文档地图

  1. 顺着\subpage找源码:mainpage 中的每个 subpage 名称(如SvcCmdDispatcherComponent)都对应仓库中一个组件目录(如Svc/CmdDispatcher/)。阅读任意组件的docs/子目录即可获得该组件的 SDD,阅读.fpp文件可查看接口模型。
  2. 以端口类型为线索追踪数据流:F´ 组件间通信全部经过Fw包定义的类型化端口(Buffer、Cmd、Com、Log、Tlm、Time、Prm、Sched、Ping等)。遇到"这个组件和谁连接"的问题,可在对应.fpp中搜索端口名,或查看拓扑文件(如 Ref/Top/topology.fpp、RPI/Top/topology.fpp)中的连接声明。
  3. 结合示例部署阅读:仓库自带 Ref(标准参考应用,演示多数系统组件的接线方式)与 RPI(树莓派嵌入式示例)两个可构建部署,是理解 mainpage 所列组件如何协作的活教材;安装与构建步骤见 docs/INSTALL.md。
  4. 注意配置开关的裁剪:Fw与Os的诸多能力(如对象名、对象注册、端口追踪、16/32/64 位序列化)由 config/FpConfig.hpp 与 config/FpConfig.fpp 中的编译宏控制,跨平台移植时需核对FW_OBJECT_NAMES、FW_PORT_TRACING、FW_HAS_16_BIT等宏的取值。

八、总结

docs/doxygen/mainpage.md虽然只是 Doxygen 的一页导航,但它精确勾勒了 F´ 的架构骨架:Fw提供类型化端口与序列化核心,Os屏蔽操作系统差异,Svc提供开箱即用的服务组件,Drv统一硬件访问模型,Utils沉淀通用工具。以该页面为索引,配合各包源码(Fw/Buffer.fpp、Fw/Cmd.fpp、Os/Queue.hpp、Svc/CmdDispatcher.fpp、Drv/ByteStreamDriverModel.fpp等)逐一印证,即可快速建立对整个框架的完整认知,并为后续的组件开发、移植与系统集成打下坚实基础。

  • 嵌入式
  • 系统编程

【免费下载链接】fprime

F´ - A flight software and embedded systems framework

项目地址:https://gitcode.com/gh_mirrors/fpri/fprime
点击查看免费下载

相关推荐

上一篇:Wireshark VXLAN协议分析终极指南:解密虚拟扩展局域网
下一篇:Android应用启动优化:UltimateAndroidReference中的启动优化工具

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询