F´(F Prime)Fw::Time 端口深度解析:飞行软件时间戳的传递、序列化与比较机制
嵌入式系统编程【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址https://gitcode.com/gh_mirrors/fpri/fprime点击查看免费下载导读Fw::Time是 F´F Prime飞行软件与嵌入式系统框架中用于在系统内传递时间戳time stamp的标准端口遥测telemetry、事件events以及其他需要时间信息的组件都依赖它。本文将围绕 Fw/Time/docs/sdd.md 的设计文档结合仓库内端口定义、Fw::Time数据类型实现、配置项与单元测试完整解析该端口的作用、Fw::Time类的内部结构与运算语义以及它如何通过序列化在组件间流转。读完本文你将掌握Fw::Time端口的定义方式、时间基准Time Base与时间上下文Time Context的配置含义、时间戳序列化格式以及时间比较/加减运算的边界行为能够在自己的 F´ 组件中正确使用或扩展这一机制。1. 端口定位与核心职责根据 Fw/Time/docs/sdd.md 的说明TheFw::Timeport is used to pass time stamps around the system, either for telemetry and events or other uses.Fw::Time端口用于在系统各处传递时间戳——无论是遥测数据、事件EVENT报文还是其他需要时间信息的用途。它是 F´ 中时间信息流通的标准管道负责提供时间的组件如Svc::Time通过该端口对外输出当前时间遥测/事件采集链路则通过该端口获取时间戳并打入下行报文。1.1 FPP 端口定义端口在 FPP 语言中的定义位于 Fw/Time/Time.fppmodule Fw { type Time Time port port Time( ref $time: Fw.Time The U32 cmd argument ) }关键点端口名与数据类型同名均为Time归属Fw模块端口通过引用ref传递一个Fw.Time类型的参数$time即调用方传入一个Fw::Time对象引用由被调用方填充/读取该端口没有返回值无return子句时间值完全依靠引用参数带出这与后续Svc::Time组件中timeGetPort的同步调用模式一致。2. 端口设计上下文Design2.1 端口图设计文档给出的端口框图如上图所示图片源文件为 Fw/Time/docs/img/TimeBDD.jpg其含义可以解读为左侧PortType Time命名空间Fw描述了端口类型Time其关联操作return() : Time表明该端口最终返回一个Fw::Time类型的值右侧DataType Time是端口使用的数据类型明确标注其来源头文件为Fw/Time/Time.hpp、命名空间为Fw与左侧端口引用的Time类型完全对应。2.2 端口使用的可序列化类型Fw::Time设计文档指出Fw::Timeis a class that stores the time base (project specific), seconds and microseconds of the time stamp.即Fw::Time是一个类存储了时间戳的时间基准time base项目相关、秒与微秒三部分信息。在仓库实现中Fw/Time/Time.hpp 进一步表明它继承自Fw::Serializable是一个标准的可序列化对象内部还额外维护了一个时间上下文time context字段用于记录如重启计数、节点编号等用户自定义信息。3. Fw::Time 数据类型源码级剖析3.1 内部成员与内存布局Fw/Time/Time.hpp 定义了其序列化后的尺寸常量enum { SERIALIZED_SIZE sizeof(FwTimeBaseStoreType) sizeof(FwTimeContextStoreType) sizeof(U32) sizeof(U32) };四个成员分别为见 Fw/Time/Time.hpp成员类型含义m_secondsU32秒部分m_usecondsU32微秒部分m_timeBaseTimeBase枚举时间基准由系统/项目定义m_timeContextFwTimeContextStoreTypeU8用户可设值如重启计数、节点号等在默认配置FW_USE_TIME_BASE 1、FW_USE_TIME_CONTEXT 1下时间戳序列化占用2 1 4 4 11字节若在 config/FpConfig.hpp 中关闭时间基准或时间上下文特性序列化体积可相应缩减。3.2 时间基准与存储类型定义config/FpConfig.hpp时间基准枚举与配套存储类型定义在 config/FpConfig.hppenum TimeBase { TB_NONE, //! No time base has been established TB_PROC_TIME, //! Indicates time is processor cycle time. Not tied to external time TB_WORKSTATION_TIME, //! Time as reported on workstation where software is running. For testing. TB_DONT_CARE 0xFFFF //! Dont care value for sequences. If FwTimeBaseStoreType is changed, value should be changed }; #define FW_CONTEXT_DONT_CARE 0xFF //! Dont care value for time contexts in sequences typedef U16 FwTimeBaseStoreType; typedef U8 FwTimeContextStoreType;需要理解的关键语义TB_NONE尚未建立时间基准Fw::Time的默认构造状态即为此值Time()构造时将m_timeBase置为TB_NONETB_PROC_TIME处理器周期时间不绑定外部时钟适合嵌入式环境下的相对计时TB_WORKSTATION_TIME软件运行所在工作站的系统时间主要用于主机/桌面测试场景TB_DONT_CARE与FW_CONTEXT_DONT_CARE序列sequence等场景中表示不关心的占位值用于指令序列文件中的时间匹配FwTimeBaseStoreTypeU16与FwTimeContextStoreTypeU8是时间基准与上下文的存储类型保证其在序列化与跨平台传输时尺寸确定。此外 config/FpConfig.hpp 提供了两个特性开关直接影响Fw::Time的序列化行为与比较逻辑#ifndef FW_USE_TIME_BASE #define FW_USE_TIME_BASE 1 //! Whether or not to use the time base #endif #ifndef FW_USE_TIME_CONTEXT #define FW_USE_TIME_CONTEXT 1 //! Whether or not to serialize the time context #endif从 Fw/Time/Time.cpp 的实现可以看到当FW_USE_TIME_BASE关闭时反序列化会将m_timeBase强制置为TB_NONE当FW_USE_TIME_CONTEXT关闭时上下文被强制置 0——这说明这两个特性开关既控制序列化字节流也决定了对端解析后的默认值。3.3 构造与赋值 APIFw/Time/Time.hpp 提供了多组构造与设置方法覆盖从仅秒/微秒到基准上下文秒/微秒的完整组合Time(); // 默认构造0 秒、0 微秒、TB_NONE、上下文 0 Time(U32 seconds, U32 useconds); // 仅秒与微秒基准为 TB_NONE Time(TimeBase timeBase, U32 seconds, U32 useconds); Time(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 useconds); void set(U32 seconds, U32 useconds); // 覆盖设置保留原基准与上下文 void set(TimeBase timeBase, U32 seconds, U32 useconds); void set(TimeBase timeBase, FwTimeContextStoreType context, U32 seconds, U32 useconds);配套的读取接口为getSeconds()、getUSeconds()、getTimeBase()、getContext()。set(U32, U32)这类只传秒/微秒的重载会保留对象已有的基准与上下文而不是重置为默认值这一点在复用时间对象时应特别注意。3.4 序列化与反序列化Fw::Time作为Fw::Serializable的派生类实现了serialize/deserialize见 Fw/Time/Time.cpp其字节流顺序为可选FW_USE_TIME_BASE时间基准FwTimeBaseStoreType可选FW_USE_TIME_CONTEXT时间上下文FwTimeContextStoreType秒U32微秒U32。每一步都检查SerializeStatus任一环节失败即立即返回错误状态。正是因为实现了这套标准序列化接口Fw::Time才能被嵌入遥测通道Tlm、事件Log等报文缓冲区随下行数据一起传回地面。3.5 比较运算基准不同则不可比Fw::Time实现了、!、、、、全部比较运算符底层统一委托给静态方法Time::compareFw/Time/Time.cpp比较结果类型为Time::Comparison枚举LT -1、EQ 0、GT 1、INCOMPARABLE 2在FW_USE_TIME_BASE开启时若两个时间基准不同返回INCOMPARABLE在FW_USE_TIME_CONTEXT开启时若上下文不同同样返回INCOMPARABLE仅当基准与上下文一致时才按先比秒、后比微秒的字典序给出LT/EQ/GT。因此在业务代码中跨基准例如把TB_PROC_TIME与TB_WORKSTATION_TIME的时间戳直接比较会得到不可比结论这是设计上防止语义错乱时间比较的刻意约束。3.6 时间算术add / sub / add(seconds, useconds)Fw/Time/Time.cpp 提供了三种时间运算static Time add(const Time a, const Time b)两个时间相加要求基准与上下文相同否则触发FW_ASSERT断言微秒部分相加后若 1000000则向秒进位并断言结果微秒uSeconds 1999999防止溢出static Time sub(const Time minuend, const Time subtrahend)被减数减减数断言被减数不小于减数若微秒不够减则从秒借 1等价于微秒 1000000 再减正确实现跨秒借位void add(U32 seconds, U32 useconds)就地增加秒与微秒同样处理微秒进位并断言m_useconds 1999999。这些运算在测量任务执行耗时、计算时间差等场景中非常实用其借位/进位逻辑已被单元测试覆盖见第 5 节。3.7 零时间与全局常量静态工厂方法static Time zero(TimeBase timeBase TB_NONE)返回基准可指定、秒/微秒/上下文全为 0的时间对象全局常量extern const Time ZERO_TIME;定义于 Fw/Time/Time.cpp是默认构造的零时间Fw::ZERO_TIME可直接用于时间是否已初始化的判断——例如 Fw/Time/test/ut/TimeTest.cpp 中验证了非默认构造的时间与ZERO_TIME不相等、默认构造的时间与ZERO_TIME相等。4. 在系统中的应用Svc::Time 与遥测/事件链路Fw::Time端口在实际部署中由时间服务组件对外提供。仓库中的 Svc/Time/Time.fpp 给出了标准用法passive component Time { ... sync input port timeGetPort: Fw.Time ... }Svc::Time组件暴露名为timeGetPort的同步输入端口端口类型正是Fw.Time。外部组件如遥测通道Svc::TlmChan、事件记录器Svc::ActiveLogger、命令调度器等在生成遥测或事件报文时通过该端口同步获取当前时间戳并填入报文。整套链路可以概括为时间源Svc::Time及其平台实现如Svc::LinuxTime维护并持续更新时间需要时间戳的组件通过Fw::Time端口同步调用timeGetPort传入Fw::Time引用参数时间服务填充引用对象的秒/微秒/基准/上下文后返回调用方将Fw::Time序列化进 Tlm/Log 报文缓冲区随遥测或事件下行到地面系统。这一端口传递引用 对象可序列化的组合正是Fw::Time在整个框架中通用性强的根本原因——它不绑定任何特定组件任何模块都可以声明并使用该端口获取或转发时间戳。5. 单元测试验证仓库的单元测试位于 Fw/Time/test/ut/TimeTest.cpp覆盖了该数据类型的全部核心行为测试用例验证内容InstantiateTest构造Time(TB_NONE, 1, 2)后基准、上下文、秒、微秒字段取值正确MathTest相等/不等/大于/小于/大于等于比较add求和1000s1000us 4000s2000us 5000s3000us常规减法微秒借位减法2s1us - 1s999999us 0s2usCopyTest拷贝构造、赋值运算符、set方法均能完整复制四个字段ZeroTimeEquality非零时间与Fw::ZERO_TIME不等默认构造时间与Fw::ZERO_TIME相等其中MathTest对微秒进位加法与借位减法的断言正是对 Fw/Time/Time.cpp 中进位/借位分支的直接验证可作为理解Fw::Time时间运算语义的最佳示例。6. 变更记录设计文档末尾给出了本模块的变更历史见 Fw/Time/docs/sdd.mdDateDescription6/19/2015Initial Version小结与实战要点端口形态Fw::Time是无返回值、以ref引用方式传递Fw.Time参数的端口FPP 定义见 Fw/Time/Time.fpp数据类型Fw::Time存储时间基准 时间上下文 秒 微秒四个字段序列化尺寸与字段取舍受 config/FpConfig.hpp 中的TimeBase枚举、FW_USE_TIME_BASE、FW_USE_TIME_CONTEXT控制运算语义比较运算要求基准与上下文一致否则返回INCOMPARABLEadd/sub内置微秒进位/借位逻辑均以断言保护接入方式参照 Svc/Time/Time.fpp 声明sync input port timeGetPort: Fw.Time即可在自己的组件中接收系统时间戳验证手段阅读并运行 Fw/Time/test/ut/TimeTest.cpp 可快速理解构造、比较、算术与零时间语义。如需进一步了解时间在遥测与事件报文中的落地方式可继续阅读 Fw/Tlm 与 Fw/Log 目录下的相关实现与文档。赞分享嵌入式系统编程【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址https://gitcode.com/gh_mirrors/fpri/fprime点击查看免费下载相关推荐F´ 框架中的 Fw::Time 端口时间戳传递、Fw::Time 数据类型与序列化机制详解F´ 框架中的 Fw::Time 端口时间戳传递、Fw::Time 数据类型与序列化机制详解 导读 Fw::Time 端口是 NASA F´F Prime嵌入式系统编程F´ (F Prime) 事件日志端口深度解析Fw::Log 与 Fw::LogText 端口的设计、序列化与使用指南F´ F Prime 事件日志端口深度解析Fw::Log 与 Fw::LogText 端口的设计、序列化与使用指南 导读 本文聚焦 F´F Prime飞行嵌入式系统编程F´ 框架中的 Fw::Time 与 Fw::TimeInterval时间戳与时间间隔端口的深度解析F´ 框架中的 Fw::Time 与 Fw::TimeInterval时间戳与时间间隔端口的深度解析 本文围绕 F´F Prime飞行软件与嵌入式系统框架嵌入式系统编程上一篇模拟人生1宽屏补丁完整指南让经典游戏完美适配现代显示器下一篇ESPHome 配置避坑3 步从 YAML 跑通第一台设备固件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

PaddleSpeech ERNIE-SAT 语音-文本联合预训练实战:基于 VCTK 的语音编辑与个性化语音合成全链路解析

PaddleSpeech ERNIE-SAT 语音-文本联合预训练实战:基于 VCTK 的语音编辑与个性化语音合成全链路解析

人工智能语音音频NLP媒体生成 【免费下载链接】PaddleSpeech Easy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation …

2026/9/25 10:59:37 阅读更多 →
BullMQ FIFO 队列:先进先出顺序的保证、默认任务选项与清理策略

BullMQ FIFO 队列:先进先出顺序的保证、默认任务选项与清理策略

后端消息队列任务调度 【免费下载链接】bullmq BullMQ - Message Queue and Batch processing for NodeJS, Python, .NET, Elixir, Rust and PHP based on Redis or PostgreSQL 项目地址: https://gitcode.com/gh_mirrors/bu/bullmq 点击查看 免费下载 FIFO&#x…

2026/9/25 10:59:37 阅读更多 →
Agent Skills实战:从技能定义到调度执行的完整指南

Agent Skills实战:从技能定义到调度执行的完整指南

聊一个最近在AI应用开发里绕不开的东西:agent-skills。说白了,就是给大模型配一套可复用的技能模块,让它不再只停留在“聊天”层面,而是能真正动手干活——查资料、算数据、发消息、操作文件、拉取第三方接口,甚至按一…

2026/9/25 10:58:36 阅读更多 →

最新新闻

从免费CRM到独立部署:小团队搭建私人CRM网站全记录

从免费CRM到独立部署:小团队搭建私人CRM网站全记录

上个月我终于把客户资料从微信聊天记录、Excel表格和记事本里统一搬了出来,全部塞进了一套自己部署的CRM系统里。项目代号DeskcommCRM,听起来像个大厂产品,其实是我基于开源组件和一台轻量云服务器搭起来的私人客户关系管理网站。到今天跑了1…

2026/9/25 12:52:24 阅读更多 →
逐行精读Tftpd64的tftpd_thread.c:TFTP状态机、OACK选项协商与重传策略完整实现

逐行精读Tftpd64的tftpd_thread.c:TFTP状态机、OACK选项协商与重传策略完整实现

逐行精读Tftpd64的tftpd_thread.c:TFTP状态机、OACK选项协商与重传策略完整实现 【免费下载链接】tftpd64 The working repository of the famous TFTP server. 项目地址: https://gitcode.com/gh_mirrors/tf/tftpd64 Tftpd64 是 Windows 平台上最著名的 TFT…

2026/9/25 12:52:24 阅读更多 →
Large Language Models for Summarizing Czech Historical Documents and Beyond

Large Language Models for Summarizing Czech Historical Documents and Beyond

文章主要内容与创新点总结 一、主要内容 本文聚焦捷克语文本摘要任务,尤其是历史文献摘要这一研究缺口,展开了系统性研究,具体内容如下: 研究背景:文本摘要旨在精简文本同时保留核心信息,当前该领域研究多集中于英语等资源丰富语言,而捷克语(尤其是历史捷克语)因语言…

2026/9/25 12:52:24 阅读更多 →
Windows 8.1原版镜像下载与校验:MSDN正式版、SHA1验证及UEFI/GPT安装指南

Windows 8.1原版镜像下载与校验:MSDN正式版、SHA1验证及UEFI/GPT安装指南

隔三差五就有人来问我:网上那些 Windows 8.1 纯净版、完美优化版、一键装机版,到底能不能用?我的回答一直没变——如果你需要的是一个稳定的 Windows 8.1 镜像下载,就老老实实找微软官方原版,尤其是带 MSDN 正式版字样…

2026/9/25 12:52:24 阅读更多 →
自建CRM系统全攻略:从LNMP架构到数据安全运维

自建CRM系统全攻略:从LNMP架构到数据安全运维

先说个背景。去年团队规模从三个人扩到十来个人的时候,我们做的第一件事不是换办公室,而是认真解决客户信息管理的问题。之前客户资料全躺在个人微信、Excel 表格和邮箱里,每个人记法还不一样,有人记在备注里,有人单独建了个文档&…

2026/9/25 12:52:24 阅读更多 →
开放式代码评审实践:让每一行代码都被认真读过

开放式代码评审实践:让每一行代码都被认真读过

1. 开放式代码评审:让每一行代码都被认真读过先聊个场景。你花了几个小时写了一个功能,提交了合并请求,两天后评审人才姗姗来迟,留下一句“LGTM”就合入了。你心里清楚,这份代码里有几处设计瑕疵,有些边界条…

2026/9/25 12:51:23 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →