嵌入式系统编程【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址https://gitcode.com/gh_mirrors/fpri/fprime点击查看免费下载本篇技术指南围绕 F´F Prime飞行软件框架中的Fw::PrmGet/Fw::PrmSet参数存取端口展开先讲清两个端口的接口契约与四种参数有效性状态再深入到Fw::PrmBuffer、Fw::ParamString的序列化实现与容量配置最后结合参数数据库组件Svc::PrmDb的源码还原参数从加载 → 读取 → 更新 → 保存的完整生命周期。读完本文你将掌握如何在 F´ 组件中定义、访问和持久化参数并理解底层缓冲区的字节布局与文件格式。Fw::PrmGet 端口图Fw::PrmSet 端口图1. 端口概述F´ 参数系统的统一存取接口在 F´ 框架中参数Parameter是可以在运行时被地面系统Ground SystemGSE或其它组件动态调整的配置数据用于在飞行软件不重新编译的情况下微调行为。为了让参数的生产方存储者与消费方使用者解耦F´ 定义了一对标准端口PortFw::PrmGet用于从存储中检索参数值。调用时传入参数 ID与一个目标缓冲区端口调用返回一个表示该值有效性的状态值Fw::PrmSet用于更新参数值。调用时传入参数 ID与一个携带新值的缓冲区无返回值。这一设计使得任何需要参数的组件都只需通过Fw.PrmGet输出端口Output Port连接到一个参数存储组件如Svc::PrmDb的对应输入端口即可按 ID 读取和更新参数而无需关心参数底层存储在哪里、以何种格式持久化。从源码结构看端口契约在 Fw/Prm/Prm.fpp 中以 FPPF´ Prime Parser语言正式声明是框架的规范化接口代码生成器会据此生成可供组件直接调用的 C 端口基类代码。2. 端口接口定义FPP 契约在 Fw/Prm/Prm.fpp 中两个端口与有效性枚举被定义在Fw模块下module Fw { type ParamBuffer Enum representing parameter validity enum ParamValid { UNINIT 0 VALID 1 INVALID 2 DEFAULT 3 } Port for getting a parameter port PrmGet( $id: FwPrmIdType Parameter ID ref val: ParamBuffer Buffer containing serialized parameter value ) - ParamValid Port for setting a parameter port PrmSet( $id: FwPrmIdType Parameter ID ref val: ParamBuffer Buffer containing serialized parameter value ) }接口契约要点要素说明参数 ID$id类型为FwPrmIdType在 config/FpConfig.hpp 中定义为typedef U32 FwPrmIdType;即 32 位无符号整数支持约 42.9 亿个独立参数 ID参数值ref val类型为Fw::ParamBuffer以**引用ref**方式传递PrmGet用其回填读取到的序列化值PrmSet用其携带待写入的序列化值PrmGet返回值ParamValid枚举标识本次读取的有效性状态两个端口在参数传递上都使用ID 序列化缓冲区的组合ID 定位参数条目缓冲区承载值的序列化字节从而支持任意可序列化类型标量、字符串、数组、结构体作为参数值。3. 参数有效性状态ParamValid 四种取值原 SDD 文档明确指出Fw::PrmGet端口具有以下返回值语义结合 Prm.fpp 中的枚举定义四种状态的完整含义如下| 值 | 枚举名 | 描述 | 典型产生场景 | | -- | ------ | ---- | ------------ | |0|PARAM_UNINIT| 仅用于组件内部表示参数尚未初始化即从未调用过loadParameters()| 组件启动早期、参数库还未加载任何文件时读取参数 | |1|PARAM_VALID| 参数成功从存储中检索由端口调用返回并用于组件内部 | 参数 ID 在数据库表中命中缓冲区被回填 | |2|PARAM_INVALID| 参数未能从存储中成功检索由端口调用返回并用于组件内部 | 参数 ID 未命中数据库或文件加载失败 | |3|PARAM_DEFAULT| 仅用于组件内部表示端口返回了PARAM_INVALID因此使用了为该参数指定的默认值| 消费组件实现了默认值回退逻辑 |需要特别说明的是UNINIT与DEFAULT两种状态只存在于消费参数的组件内部逻辑中不会由端口调用直接返回端口调用本身只返回VALID或INVALID。消费组件如Svc::PrmDb的调用方在收到INVALID后可自行决定是否使用默认值并把该决策记录为DEFAULT状态。这一点在Svc::PrmDb的端口处理器实现中得到了印证getPrm_handler在表中命中参数时返回Fw::ParamValid::VALID并回填缓冲区未命中时返回Fw::ParamValid::INVALID同时上报PrmIdNotFound警告事件见 Svc/PrmDb/PrmDbImpl.cpp。4. 承载值的序列化缓冲区Fw::PrmBufferFw::PrmBuffer类代表一个用于存放参数值序列化字节的缓冲区定义于 Fw/Prm/PrmBuffer.hpp实现于 Fw/Prm/PrmBuffer.cpp。4.1 类设计class ParamBuffer : public SerializeBufferBase { public: enum { SERIALIZED_TYPE_ID FW_TYPEID_PRM_BUFF, SERIALIZED_SIZE FW_PARAM_BUFFER_MAX_SIZE sizeof(FwBuffSizeType) }; ParamBuffer(const U8 *args, NATIVE_UINT_TYPE size); ParamBuffer(); ParamBuffer(const ParamBuffer other); virtual ~ParamBuffer(); ParamBuffer operator(const ParamBuffer other); NATIVE_UINT_TYPE getBuffCapacity() const; // ! returns capacity, not current size, of buffer U8* getBuffAddr(); const U8* getBuffAddr() const; private: U8 m_bufferData[FW_PARAM_BUFFER_MAX_SIZE]; // command argument buffer };关键设计点继承SerializeBufferBaseParamBuffer复用 F´ 框架统一的Fw::SerializeBufferBase基础设施见 Fw/Types/Serializable.hpp从而天然支持resetSer()/resetDeser()、serialize()/deserialize()等序列化操作并带有FwBuffSizeType长度字。内部固定数组数据存放在定长数组m_bufferData[FW_PARAM_BUFFER_MAX_SIZE]中容量由编译期宏决定见第 5 节避免动态内存分配符合嵌入式飞行软件对确定性的要求。类型标识SERIALIZED_TYPE_ID FW_TYPEID_PRM_BUFF其值46登记在 Fw/Cfg/SerIds.hpp用于序列化流中标识参数缓冲区类型。构造与拷贝从外部数据构造、拷贝构造、赋值运算符均通过SerializeBufferBase::setBuff()实现一旦序列化状态异常如传入尺寸超限会触发FW_ASSERT断言见 PrmBuffer.cpp体现框架尽早失败的防御式编程风格。容量与地址访问getBuffCapacity()返回缓冲区容量而非当前已用长度getBuffAddr()返回内部数组首地址供底层读写使用。4.2 与端口的关系在PrmGet端口调用中调用方传入一个空的ParamBuffer引用命中后存储端通过赋值val this-m_db[entry].val把数据库表中保存的序列化字节拷贝进调用方的缓冲区。在PrmSet调用中调用方把序列化好的新值放入缓冲区并传入存储端把缓冲区整体拷贝进表项。由于ParamBuffer重载了operator内部按长度拷贝端口两侧可以安全地直接赋值。5. 参数相关配置项容量与 ID 类型参数系统的容量与类型由 F´ 的全局配置文件 config/FpConfig.hpp 集中管理以下是关键宏| 宏 | 默认值 | 含义 | | -- | ------ | ---- | |FwPrmIdType|U32| 参数 ID 类型config/FpConfig.hpp | |FW_PARAM_BUFFER_MAX_SIZE|FW_COM_BUFFER_MAX_SIZE - sizeof(FwPrmIdType) - sizeof(FwPacketDescriptorType)| 参数序列化缓冲区的最大字节数config/FpConfig.hpp。即从通信缓冲总容量中扣除参数 ID4 字节与包描述符后得到的净载荷 | |FW_PARAM_STRING_MAX_SIZE|40| 参数字符串类型的最大字符数config/FpConfig.hpp |这些宏均以#ifndef保护包裹允许各部署项目在编译期覆盖默认值从而按任务需求调整参数缓冲区大小——这是 F´ 配置体系config/目录下所有*Cfg.hpp的通用模式。5.1 字符串参数类型Fw::ParamString当参数值为字符串时使用Fw::ParamString类型定义于 Fw/Prm/PrmString.hpp实现于 Fw/Prm/PrmString.cppclass ParamString : public Fw::StringBase { public: enum { SERIALIZED_TYPE_ID FW_TYPEID_PRM_STR, // 值 47见 SerIds.hpp SERIALIZED_SIZE FW_PARAM_STRING_MAX_SIZE sizeof(FwBuffSizeType) }; // 构造/赋值重载接受 const char*、StringBase、ParamString const char* toChar() const; NATIVE_UINT_TYPE getCapacity() const; private: char m_buf[FW_PARAM_STRING_MAX_SIZE]; };ParamString内部以定长char m_buf[40]存储字符串所有赋值路径都通过Fw::StringUtils::string_copy()进行带容量限制的拷贝杜绝缓冲区溢出getCapacity()返回FW_PARAM_STRING_MAX_SIZE序列化类型 ID 为FW_TYPEID_PRM_STR值47见 Fw/Cfg/SerIds.hpp。代码生成器在组件声明字符串参数类型时会自动生成使用该类型的代码。6. 端口的典型消费方Svc::PrmDb 参数数据库组件Fw::PrmGet/Fw::PrmSet端口在框架中最典型的落地实现是Svc::PrmDb组件。在 Svc/PrmDb/PrmDb.fpp 中可以看到端口如何被消费 Port to get parameter values guarded input port getPrm: Fw.PrmGet Port to update parameters async input port setPrm: Fw.PrmSetgetPrm为guarded互斥保护输入端口同步读取数据库表项保证并发读安全setPrm为async异步输入端口写入操作进入组件消息队列排队执行由PrmDbImpl::setPrm_handler处理。Svc::PrmDb的完整设计文档见 Svc/PrmDb/docs/sdd.md它明确了四条需求从文件加载参数PRMDB-001、提供读取接口PRMDB-002、提供更新接口PRMDB-003、提供保存命令PRMDB-004。6.1 加载与存储readParamFile 与内存表组件在初始化阶段调用PrmDbImpl::readParamFile()见 Svc/PrmDb/PrmDbImpl.cpp 起从文件读取参数并填入以参数 ID 为索引的内存表m_db[]表容量由 config/PrmDbImplCfg.hpp 中的PRMDB_NUM_DB_ENTRIES默认 25 条决定。每个表项包含used占用标志、id参数 ID与valParamBuffer值。读取过程对每条记录执行严格的字段校验分隔符、记录尺寸、参数 ID、参数值各阶段任何阶段失败都会上报PrmFileReadError警告事件并中止加载——从源码看错误枚举覆盖OPEN、DELIMITER、DELIMITER_SIZE、DELIMITER_VALUE、RECORD_SIZE、PARAMETER_ID、PARAMETER_VALUE等 11 个阶段见 PrmDb.fpp。6.2 读取与更新getPrm_handler / setPrm_handler读取PrmDbImpl.cpp线性遍历表项命中则val 表项.val并返回VALID未命中则上报PrmIdNotFound事件并返回INVALID。更新PrmDbImpl.cpp先在表中查找同名 ID找到则覆盖并上报PrmIdUpdated找不到则在空槽中添加新条目并上报PrmIdAdded表满则上报致命事件PrmDbFull。写入期间通过lock()/unLock()保护共享表防止与读取、保存并发冲突。6.3 保存命令PRM_SAVE_FILE组件通过异步命令PRM_SAVE_FILE见 PrmDb.fpp把内存中的整个参数表写回文件覆盖旧值。从 PrmDbImpl.cpp 起的实现可以看到写入使用Os::File以OPEN_WRITE模式打开构造函数指定的文件名逐条写入分隔符 记录尺寸 ID 值完成后上报PrmFileSaveComplete事件并携带写入的记录数。⚠️ 持久化要点SDD 原文强调除非执行了PRM_SAVE_FILE命令否则所有运行时参数更新在软件重启后都会丢失。因此参数更新的持久化是一个显式操作。6.4 参数文件格式Svc::PrmDbSDD 文档给出了参数文件如 Ref/PrmDb.dat、RPI/PrmDb.dat中每条参数的存储格式每个字段如下| 字段 | 大小字节 | 值 | | ---- | ------------ | -- | | 条目分隔符Entry Delimiter | 1 |0xA5PRMDB_ENTRY_DELIMITER见 config/PrmDbImplCfg.hpp | | 记录尺寸Record Size | 4 | ID 类型大小 参数值字节数 | | 参数 IDParameter ID |sizeof(FwPrmIdType)4 字节 | 参数 ID 的值 | | 参数值Parameter value | 参数值字节数 | 值的序列化字节 |该格式在 Svc/PrmDb/PrmDbImpl.cpp 的readParamFile()与PRM_SAVE_FILE_cmdHandler()中一一对应实现写入时recordSize sizeof(FwPrmIdType) 表项val.getBuffLength()见 PrmDbImpl.cpp读取时校验0xA5分隔符并把recordSize限定在[sizeof(U32), FW_PARAM_BUFFER_MAX_SIZE sizeof(U32)]范围内见 PrmDbImpl.cpp作为文件完整性的 sanity check。7. 如何在自定义组件中使用参数端口结合端口契约与Svc::PrmDb的用法在 F´ 组件中接入参数系统的标准套路如下声明输出端口在组件的.fpp文件中声明output port prmGetOut: Fw.PrmGet与可选output port prmSetOut: Fw.PrmSet实例化并连接在部署拓扑如Ref/Top/topology.fpp、RPI/Top/topology.fpp中把组件的输出端口连接到Svc::PrmDb的getPrm/setPrm输入端口初始化阶段加载在组件init()或启动序列中调用prmGetOut_out(0, PRM_ID_XXX, val)读取参数根据返回的ParamValid判断VALID使用缓冲区值INVALID使用代码内默认值并在内部标记为DEFAULT状态UNINIT说明参数库尚未加载运行时更新当需要修改参数时序列化新值到Fw::ParamBuffer并通过prmSetOut_out(...)发送随后由Svc::PrmDb异步入库如需落盘再向Svc::PrmDb下发PRM_SAVE_FILE命令。从Svc::PrmDb的单元测试看测试位于 Svc/PrmDb/test覆盖了加载、读取、更新、保存与各类错误路径运行fprime-util check --coverage可查看组件级覆盖率见 Svc/PrmDb/docs/sdd.md。8. 变更日志原 SDD 文档记录的唯一一次修订日期说明6/23/2015初始版本端口契约本身自 2015 年定稿以来保持稳定PrmGetID 缓冲区引用 ParamValid返回值与PrmSetID 缓冲区引用的组合至今仍是 F´ 框架参数子系统的一等公民接口被 Svc/PrmDb/PrmDb.fpp 等组件持续消费体现了 F´ 接口层稳定契约、可演进实现的设计哲学。9. 参考与延伸阅读端口契约FPP 定义Fw/Prm/Prm.fpp端口 SDD 原文档Fw/Prm/docs/sdd.md本文骨架来源缓冲区实现Fw/Prm/PrmBuffer.hpp、Fw/Prm/PrmBuffer.cpp字符串参数类型Fw/Prm/PrmString.hpp、Fw/Prm/PrmString.cpp全局容量配置config/FpConfig.hpp数据库容量配置config/PrmDbImplCfg.hpp消费组件定义Svc/PrmDb/PrmDb.fpp、Svc/PrmDb/PrmDbImpl.cpp消费组件 SDDSvc/PrmDb/docs/sdd.md示例参数文件Ref/PrmDb.dat赞分享嵌入式系统编程【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址https://gitcode.com/gh_mirrors/fpri/fprime点击查看免费下载相关推荐F´ 参数服务端口深度解析Fw::PrmGet / Fw::PrmSet 的接口契约、状态语义与 PrmDb 集成实战F´ 参数服务端口深度解析Fw::PrmGet / Fw::PrmSet 的接口契约、状态语义与 PrmDb 集成实战 导读 本篇技术指南围绕 F´F Pr嵌入式系统编程F´F Prime参数管理核心机制Fw::PrmGet / PrmSet 端口深入解析F´F Prime参数管理核心机制Fw::PrmGet / PrmSet 端口深入解析 F´F PrimeNASA JPL 开源的飞行软件与嵌入式系统嵌入式系统编程F´ (F Prime) 事件日志端口深度解析Fw::Log 与 Fw::LogText 端口的设计、序列化与使用指南F´ F Prime 事件日志端口深度解析Fw::Log 与 Fw::LogText 端口的设计、序列化与使用指南 导读 本文聚焦 F´F Prime飞行嵌入式系统编程上一篇命令行神器轻松获取iOS应用包的完整解决方案下一篇华硕笔记本性能调优神器5步掌握G-Helper完整使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
CompreFace 贡献指南:开发环境搭建、编码规范与贡献全流程 人工智能计算机视觉后端AI 应用 【免费下载链接】CompreFace Leading free and open-source face recognition system 项目地址: https://gitcode.com/gh_mirrors/co/CompreFace 点击查看 免费下载 本文基于 CompreFace 官方贡献指南 CONTRIBUTING.md 展开… · 2026/9/25 10:50:51
通往AI架构师的捷径!用Claude Skills+TaoToken搭建可复用Agent工作流,简历直接加分 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 10:50:51
【运维心得】OpenClaw 国内模型选型与 TaoToken 统一 Key 配置实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 11:22:54
AI辅助PLC编程实战:本地大模型+工业规范工作流 1. 项目概述:当PLC工程师开始把梯形图交给AI画干了十年PLC编程,我手边的博途V18安装包还没卸载,电脑右下角却已经常驻着一个本地运行的大模型窗口——不是用来查手册、不是用来翻译德文报错,而是真正在写OB1主循环、生成FC功能块、… · 2026/9/25 11:22:54
网络安全法催热五大岗位:等保合规、渗透测试、安全运营等人才身价看涨 最近身边做IT和做安全的同行都在聊同一个现象:网络安全法进入落地执行阶段后,企业突然发现网络安全管理“不搞不行了”。以前安全更像是锦上添花,预算排在最后面,团队可有可无;现在直接变成了经营合规里绕不开的一环&a… · 2026/9/25 11:22:48
RVC 变声器实战指南:10 分钟录音做出可用 AI 音色模型 RVC 变声器实战指南:10 分钟录音做出可用 AI 音色模型 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-Voice-Convers… · 2026/9/25 11:22:48
FlowGram.AI 工作流开发框架:从快速上手到画布、表单、变量引擎全解析 前端低代码工作流自动化流程编排 【免费下载链接】flowgram.ai FlowGram is an extensible workflow development framework with built-in canvas, form, variable, and materials that helps developers build AI workflow platforms faster and simpler. 项目地址࿱… · 2026/9/25 11:22:42
WeChatMsg 完整指南:微信聊天记录导出成存档、文档与年度报告的三条路径 WeChatMsg 完整指南:微信聊天记录导出成存档、文档与年度报告的三条路径 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_… · 2026/9/25 11:22:42
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37