- 嵌入式
- 系统编程
【免费下载链接】fprime
F´ - A flight software and embedded systems framework
本篇技术指南以 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):
| 包名 | 文档定位(原文) | 职责概括 |
|---|---|---|
Fw | Core classes, components, and ports | 框架核心:支撑框架运行的基础类、组件与端口,含各类组件的基类与系统核心类型 |
Os | Operating system abstraction layer | 操作系统抽象层:互斥量、队列、任务、文件系统等 OS 功能 |
Svc | Standard components | 标准服务组件:命令与数据处理组件,用于构建更完整的应用 |
Drv | Drivers for hardware functions | 硬件驱动:含示例块驱动及 Linux 硬件驱动 |
Utils | Classes 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/目录则为这些工具提供了单元测试与配套类型。
七、如何高效使用这份文档地图
- 顺着
\subpage找源码:mainpage 中的每个 subpage 名称(如SvcCmdDispatcherComponent)都对应仓库中一个组件目录(如Svc/CmdDispatcher/)。阅读任意组件的docs/子目录即可获得该组件的 SDD,阅读.fpp文件可查看接口模型。 - 以端口类型为线索追踪数据流:F´ 组件间通信全部经过
Fw包定义的类型化端口(Buffer、Cmd、Com、Log、Tlm、Time、Prm、Sched、Ping等)。遇到"这个组件和谁连接"的问题,可在对应.fpp中搜索端口名,或查看拓扑文件(如 Ref/Top/topology.fpp、RPI/Top/topology.fpp)中的连接声明。 - 结合示例部署阅读:仓库自带 Ref(标准参考应用,演示多数系统组件的接线方式)与 RPI(树莓派嵌入式示例)两个可构建部署,是理解 mainpage 所列组件如何协作的活教材;安装与构建步骤见 docs/INSTALL.md。
- 注意配置开关的裁剪:
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
相关推荐
F´ 飞行软件框架 C/C++ 文档生成系统:从 Doxygen 主页面到五大核心包的架构导航
F´ 飞行软件框架 C/C++ 文档生成系统:从 Doxygen 主页面到五大核心包的架构导航 F´(Flight Software and Embedded
嵌入式系统编程F´(F Prime)框架全面导读:从 NASA 深空起源到组件化飞行软件架构
F´(F Prime)框架全面导读:从 NASA 深空起源到组件化飞行软件架构 F´(F Prime)是 NASA 喷气推进实验室(JPL)为小型航天任务打造的
嵌入式系统编程Awakened PoE Trade伪属性处理:复杂物品修饰符的智能分组算法
Awakened PoE Trade伪属性处理:复杂物品修饰符的智能分组算法 在《Path of Exile》这款复杂的ARPG游戏中,装备和物品往往包含大量复
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考