- 嵌入式
- 系统编程
【免费下载链接】fprime
F´ - A flight software and embedded systems framework
本篇技术指南聚焦 F´(Flight Software Framework)中"遥测通道字典"(Telemetry Channel Dictionary)的完整生命周期:如何通过组件 XML 声明一条遥测通道,如何由自动编码器(Autocoder)生成以TestTlm.md为代表的组件字典文档,以及生成的tlmWrite_*接口如何被实现代码调用、被接收侧组件反序列化消费。文章以仓库中Autocoders/Python/test/tlm1测试工程为主线,同时对照tlm_string、tlm_enum等变体,让读者掌握在 F´ 中"声明—生成—下发—接收"一条遥测通道的端到端方法,并能读懂任何 F´ 组件自动生成的字典文档。
一、什么是组件字典与遥测通道字典
在 F´ 的经典 XML 自动编码流程中,开发者先用 XML 描述组件的端口(ports)、命令(commands)、事件(events)、遥测通道(telemetry)和参数(params),自动编码器据此生成组件基类(*ComponentAc.hpp/cpp)以及配套的"组件字典"(Component Dictionary)文档。
tlm1测试工程的字典文档 docs/TestTlm.md 就是该流程最直接的产物,其完整内容如下:
# TestTlm Component Dictionary ## Telemetry Channel List |Channel Name|ID|Type|Description| |---|---|---|---| |somechan|100 (0x64)|U32|A test channel|这份文档虽短,却完整呈现了 F´ 遥测通道字典的四个核心元数据字段:
| 字段 | 取值 | 含义 |
|---|---|---|
| Channel Name | somechan | 通道名,即自动生成的tlmWrite_somechan()接口的后缀 |
| ID | 100 (0x64) | 通道唯一标识符,十进制与十六进制同时给出,用于通道寻址与解包 |
| Type | U32 | 通道数据类型,决定序列化/反序列化时使用的 F´ 类型系统 |
| Description | A test channel | 通道用途说明,源自 XML 定义中的<comment> |
二、通道的源头:XML 定义中的<telemetry>声明
字典文档中的每一行都来自组件 XML 中<telemetry>段的通道声明。tlm1工程的组件定义文件 TestComponentAi.xml 中声明了该通道:
<component name="TestTlm" kind="passive" namespace="Tlm"> <comment>A component with a single telemetry channel</comment> <ports> <port name="aport" data_type="Another::Test" kind="sync_input"> <comment>A test port</comment> </port> </ports> <telemetry> <channel id="100" name="somechan" data_type="U32" abbrev="T001-1234" high_yellow="10" high_red="20"> <comment> A test channel </comment> </channel> </telemetry> </component>对照字典文档可见,<channel>的id、name、data_type与<comment>分别映射为字典表中的 ID、Channel Name、Type 与 Description。此外该声明还包含了字典表中未展示但真实存在的进阶属性:
abbrev="T001-1234":通道缩写(缩写编号),用于地面系统对通道进行短标识引用;high_yellow="10"/high_red="20":通道高告警黄色/红色门限值,说明 F´ 通道定义在字典阶段就内置了限值监测语义,接收方与地面软件可据此进行告警判断。
组件本身为kind="passive"(被动组件)、namespace="Tlm",因此生成的基类为Tlm::TestTlmComponentBase,所有通道类型均落在Tlm命名空间下。从tlm_string、tlm_enum等变体看,data_type字段还支持string与自定义枚举类型,字典中的 Type 列会相应显示为string或枚举名(见后文第六节)。
三、字典文档的生成机制与阅读价值
docs/TestTlm.md由自动编码器在生成组件基类的同时自动产出,属于"面向人的可读产物",与其同源的结构化产物(如遥测通道 ID 到偏移/类型的映射)配合,构成了通道的完整描述。
对 F´ 开发者而言,这份字典的实用价值体现在三处:
- 通道 ID 的唯一性核对:
100 (0x64)同时给出十进制与十六进制,便于在多组件拓扑中避免 ID 冲突; - 数据类型与门限确认:Type 列与 XML 中的
data_type、high_yellow、high_red对应,是地面遥测配置(如 GDS)的输入依据; - 与实现代码的接口对应:通道名
somechan直接对应实现侧可调用的tlmWrite_somechan()接口。
四、运行时调用链:tlmWrite 下发与 tlmRecvPort 接收
字典与自动生成的基类共同支撑了通道的运行时数据流。实现组件 TestTelemImpl.cpp 中展示了通道的下发方式:
void TestTlmImpl::genTlm(U32 val) { printf("Writing value %d to telemetry.\n", val); this->tlmWrite_somechan(val); }关键点在于this->tlmWrite_somechan(val):该接口由自动编码器依据 XML 通道声明生成,参数类型即通道的data_type(此处为U32)。实现类 TestTelemImpl.hpp 继承自Tlm::TestTlmComponentBase,因此可直接调用该写接口。这解释了字典文档与代码之间的一一映射:字典里的每一行通道,都对应基类中一个可调用的tlmWrite_<name>接口。
通道数据离开组件后,通过Fw::Tlm输出端口进入遥测接收组件。tlm1工程使用自动编码器自带的telem_tester接收组件(定义于 TelemTestComponentAi.xml,组件名TelemTester,端口tlmRecvPort类型为Fw::Tlm),其处理函数在 TestTelemRecvImpl.cpp 中演示了完整的反序列化解析流程:
void TestTelemRecvImpl::tlmRecvPort_handler( NATIVE_INT_TYPE portNum, FwChanIdType id, Fw::Time &timeTag, Fw::TlmBuffer &val) { U32 tlmVal; val.deserialize(tlmVal); printf("ID: %d TLM value is %d. Time is %d:%d base: %d\n", id, tlmVal, timeTag.getSeconds(), timeTag.getUSeconds(), timeTag.getTimeBase()); }该处理函数揭示了 F´ 遥测数据包的四个组成要素:通道 ID(FwChanIdType id,即字典中的100)、时间标签(Fw::Time)、**序列化后的通道值(Fw::TlmBuffer)**以及端口号。接收侧必须按字典中的 Type(U32)调用对应的deserialize才能正确还原数值——这正是字典文档对消费端代码的关键约束。
五、端到端运行与单元测试验证
工程入口 main.cpp 展示了将上述元素串联为一条完整链路的接线方式:
TestTlmImpl testImpl("TestTlmImpl"); testImpl.init(); TestTelemRecvImpl tlmRecv("TestTlmRecv"); tlmRecv.init(); TestTimeImpl timeSource("TimeComp"); timeSource.init(); testImpl.set_Tlm_OutputPort(0, tlmRecv.get_tlmRecvPort_InputPort(0)); testImpl.set_Time_OutputPort(0, timeSource.get_timeGetPort_InputPort(0)); timeSource.setTime(Fw::Time(TB_NONE, 2, 3)); testImpl.genTlm(26);执行流程为:初始化三个组件 → 将TestTlmImpl的遥测输出端口接到TelemTester的tlmRecvPort输入端口 → 将时间输出端口接到时间源组件 → 调用genTlm(26)触发通道下发。接收侧将打印出ID: 100 TLM value is 26及时间标签,与字典中somechan = 100的定义严格对应,从而验证了"XML 声明 → 字典文档 → 自动生成接口 → 运行时下发 → 端口接收"全链路的正确性。
工程同时注册了 GTest 单元测试目标(见 CMakeLists.txt 中的register_fprime_ut()),测试代码 test/ut/main.cpp 基于自动生成的Tlm::TestTlmGTestBase构造ATester测试器,可对组件的通道行为进行 GTest 风格断言验证。
六、字典类型的扩展:字符串与枚举通道
同一套字典机制支持更丰富的通道类型,仓库中的两个变体工程提供了直接对照:
- 字符串通道:
tlm_string工程的字典 docs/TestTlm.md 在somechan(U32)之外额外声明了stringchan(ID101 (0x65),Type 为string),对应 XML 中data_type="string"的通道;接收侧需以字符串语义反序列化。 - 枚举通道:
tlm_enum工程的字典 docs/TestTlm.md 中somechan的类型列显示为自定义枚举名SomeEnum,说明data_type可直接引用用户定义的枚举类型,字典文档会如实呈现该类型名。
这两个变体证明:字典表中 Type 列的取值空间由 F´ 类型系统决定,涵盖基础数值类型、字符串与用户自定义枚举,开发者可据此为不同业务语义的遥测量选择合适的通道类型。
七、构建集成与进一步探索
tlm1作为自动编码器回归测试工程,其构建方式展示了 F´ 模块的标准接入模式(CMakeLists.txt):将组件 XML 与实现源码列入SOURCE_FILES,通过register_fprime_module()注册模块,并通过EXCLUDE_FROM_ALL TRUE从全量构建中排除该测试模块;UT 部分则通过register_fprime_ut()注册。
读者可继续阅读以下仓库文件加深理解:
- 组件 XML 定义:TestComponentAi.xml
- 端口 XML 定义:TestPortAi.xml
- 通道下发实现:TestTelemImpl.cpp
- 通道接收实现:TestTelemRecvImpl.cpp
- 接收组件模板定义:TelemTestComponentAi.xml
- 字典变体对比:tlm_string 字典 与 tlm_enum 字典
小结
docs/TestTlm.md看似只是一张三列小表,实则是 F´ 自动编码流程在"遥测字典"层面的浓缩投影:从 XML<telemetry>声明的完整参数(ID、名称、类型、缩写、告警门限),到自动生成的tlmWrite_somechan()接口,再到接收侧按字典类型反序列化的端口处理函数,一条遥测通道的端到端设计在这一测试工程中被完整闭环验证。掌握"字典文档 ↔ XML 声明 ↔ 自动生成接口"三者的对应关系,是阅读任意 F´ 组件字典、并在此基础上构建地面遥测配置与告警逻辑的起点。
- 嵌入式
- 系统编程
【免费下载链接】fprime
F´ - A flight software and embedded systems framework
相关推荐
WebUI Forge 训练实操指南:4 步练出你的第一个 Textual Inversion 嵌入
WebUI Forge 训练实操指南:4 步练出你的第一个 Textual Inversion 嵌入 跟着本文走完 4 个步骤,你就能在 WebUI Forge
嵌入式系统编程F´ 组件事件字典(Event Component Dictionary)全解析:从 XML 定义到自动生成的 Markdown 字典
F´ 组件事件字典(Event Component Dictionary)全解析:从 XML 定义到自动生成的 Markdown 字典 本文围绕 F´(F Pr
嵌入式系统编程WezTerm 插件管理指南:深入解析 `wezterm.plugin` 模块的加载、更新与自研流程
WezTerm 插件管理指南:深入解析 wezterm.plugin 模块的加载、更新与自研流程 wezterm.plugin 是 WezTerm 内建的 Lu
嵌入式系统编程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考