十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

F´ ComSplitter 组件解析:Com 缓冲流的分发实现、构建目标与单元测试

F´ ComSplitter 组件解析:Com 缓冲流的分发实现、构建目标与单元测试 嵌入式系统编程【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址https://gitcode.com/gh_mirrors/fp/fprime点击查看免费下载本文以 F´F Prime飞行软件框架中Svc::ComSplitter组件Svc/ComSplitter/README.md为核心讲解其如何将一路 Com 输入端口上的通信缓冲流复制分发到多路输出端口并完整梳理该组件目录的redo构建目标、源码实现与单元测试验证。读完本文你将掌握 ComSplitter 的端口模型、分发语义、连接策略以及如何通过 F´ 的 CMake/UT 体系构建与测试该组件。ComSplitter 组件定位与端口模型ComSplitter 是 F´ 框架中的一个 passive被动组件功能单一而明确把一个 Com 缓冲流拆分split并转发到多个下游消费者。其 FPP 定义位于 Svc/ComSplitter/ComSplitter.fppmodule Svc { A component for splitting a Com buffer stream passive component ComSplitter { Com input port sync input port comIn: Fw.Com Com output port output port comOut: [5] Fw.Com } }端口模型由两部分组成comIn同步输入端口单实例类型为Fw.Com。这是一个sync input port意味着comIn_handler在调用者的执行上下文中同步执行ComSplitter 自身不引入线程或队列。comOut输出端口数组容量固定为5每个输出端口同样是Fw.Com类型。输出端口数组使得组件可以同时连接多个下游接收者例如多个遥测下行链路、日志记录器或通信栈。Fw.Com端口本身定义在 Fw/Com/Com.fppmodule Fw { type ComBuffer Port for passing communication packet buffers port Com( ref data: ComBuffer Buffer containing packet data context: U32 Call context value; meaning chosen by user ) }也就是说每次通过comIn传入的是一个Fw::ComBuffer引用含context上下文值ComSplitter 收到后会把该缓冲内容原样复制并分发给所有已连接的comOut输出端口。从源码结构看Svc/ComSplitter/ComSplitter.hppSvc::ComSplitter类继承自自动生成的ComSplitterComponentBase构造函数接收组件名init(instance)用于按实例号初始化组件私有成员comIn_handler是唯一的业务处理入口并声明了ComSplitterComponentBaseFriend作为白盒测试友元类。分发语义逐端口复制转发核心分发逻辑集中在 Svc/ComSplitter/ComSplitter.cpp 的comIn_handler实现中void ComSplitter :: comIn_handler( NATIVE_INT_TYPE portNum, Fw::ComBuffer data, U32 context ) { FW_ASSERT(portNum 0); NATIVE_INT_TYPE numPorts getNum_comOut_OutputPorts(); FW_ASSERT(numPorts 0); for(NATIVE_INT_TYPE i 0; i numPorts; i) { if( isConnected_comOut_OutputPort(i) ) { // Need to make a copy because we are passing by reference!: Fw::ComBuffer dataToSend data; comOut_out(i, dataToSend, 0); } } }其执行流程可拆解为四步入参断言FW_ASSERT(portNum 0)确认调用来自唯一的输入端口 0。端口数检查通过getNum_comOut_OutputPorts()获取输出端口数组容量并断言大于 0此处恒为 5。逐端口遍历对每个输出端口 i 调用isConnected_comOut_OutputPort(i)判断是否已连接。未连接的输出端口会被静默跳过这是 ComSplitter 支持部分连接的关键设计——上层只需连接实际需要的下游数量。复制转发对已连接的端口注释明确说明了原因——data是以引用方式传入的而comOut_out也会以引用传递因此必须显式构造一份Fw::ComBuffer dataToSend data副本再通过comOut_out(i, dataToSend, 0)发送避免多个下游拿到同一引用造成数据竞争或意外修改。值得注意的是发送时传入的context固定为0且每次转发都是独立副本因此每个下游消费者看到的都是完整、独立的缓冲数据互不影响。构建目录的 redo 目标继承自原 README组件目录下的 README.md 记录了该目录基于redo构建系统的可用目标。主目标Main targets目标作用Dictionary生成Dictionary目录内含供 ISF Ground Support EquipmentGSE使用的字典Docs生成Docs目录内含 ISF 风格的组件文档Interface生成Interface目录内含组件接口定义NCSL生成NCSL目录内含非注释源代码行数non-commented source lines of code统计README重新生成这份README文件Template生成Template目录内含 ISF 组件模板all构建Build/$TARGET/$MODE/lib.a组件库TARGET与MODE为环境变量clean清理本目录及其子目录的构建产物refresh从Model重新生成ComSplitterComponentAi.xmlall目标的参数约定TARGET可选值为 Darwin、Linux、PI、CORTEX160未设置时默认使用本机环境Darwin 或 LinuxMODE可选值为 Unit、Integration、Flight未设置时默认 Unit。注意refresh目标中提到的ComSplitterComponentAi.xml属于该组件的历史ISF 时代描述文件在当前仓库中已由 ComSplitter.fpp 取代。辅助目标Helper targets仅在开发或调试构建系统时直接调用目标作用Table生成Table目录包含 ISF XML 中未体现的表接口部分default.a构建Build/target/mode/lib.a组件库default.ncsl.txt生成 NCSL 统计文件default.o构建形如Build/target/mode/path/file.o的目标文件path可为空现代 CMake 构建与单元测试仓库现状当前 F´ 已迁移到 CMake 构建体系ComSplitter 的构建配置位于 Svc/ComSplitter/CMakeLists.txt通过register_fprime_module()注册模块将ComSplitter.fpp自动生成端口与组件骨架代码与ComSplitter.cpp手工实现一起编译单元测试部分则通过register_fprime_ut()注册测试源为ComSplitter.fpp、test/ut/ComSplitterTester.cpp与test/ut/ComSplitterMain.cpp。该模块同时被顶层 Svc/CMakeLists.txt 纳入 Svc 库的模块清单。单元测试采用 F´ 的 GTest 测试框架Fw/Test/UnitTest.hpp、gtest/gtest.h。Svc/ComSplitter/test/ut/ComSplitterTester.cpp 中的test_nominal()验证了核心分发行为构造 4 字节测试数据{0xde,0xad,0xbe,0xef}循环 3 次修改首字节后依次从comIn注入端口连接采用部分连接策略connectPorts()中只连接 5 个comOut输出端口中的3 个for (i 0; i 3; i)注入 3 帧后断言from_comOut历史总数为93 帧 × 3 个已连接端口并逐条比对每次转发的内容与原始缓冲逐字节一致memcmp校验长度与内容。这一测试恰好印证了源码中的跳过未连接端口逻辑若 5 个端口全部连接则历史应为 15 条。测试入口 Svc/ComSplitter/test/ut/ComSplitterMain.cpp 通过TEST(TestNominal, Nominal)运行上述用例VxWorks 目标除外。典型使用场景结合端口模型与分发语义ComSplitter 在 F´ 拓扑中适用于以下场景均为仓库源码可支撑的推断性描述一对多广播将同一路遥测/指令数据流同时送往下行链路、日志系统等多个消费者数据流分路在通信栈中把上游单一数据源分发给多个并行处理或记录模块拓扑解耦借助未连接端口自动跳过的特性同一组件实例可在不同部署中按需连接 15 个下游而无需修改组件本身。若需要更多输出路数可参照 FPP 定义按需调整comOut数组容量当前为 5并重新运行自动编码流程生成对应代码。小结ComSplitter 是 F´ 框架中一个简洁而实用的被动组件以comIn为单输入、comOut[5]为多输出通过逐端口复制Fw::ComBuffer实现缓冲流的一对多分发。其源码ComSplitter.cpp、FPP 定义ComSplitter.fpp与单元测试ComSplitterTester.cpp三者相互印证构成完整的定义—实现—验证闭环目录 README 中记录的redo目标则保留了该组件在 ISF 构建体系下的历史工作流可作为理解 F´ 构建演进背景的参考。赞分享嵌入式系统编程【免费下载链接】fprimeF´ - A flight software and embedded systems framework项目地址https://gitcode.com/gh_mirrors/fp/fprime点击查看免费下载相关推荐F´F PrimeComSplitter 组件详解Com 缓冲区流分发与多路复制F´F PrimeComSplitter 组件详解Com 缓冲区流分发与多路复制 F´F Prime是一个面向飞行软件与嵌入式系统的组件化框架。 Sv嵌入式系统编程F´ 组件代码生成器单元测试实战指南FppTest/component 测试套件解析与 fprime-util 构建运行流程F´ 组件代码生成器单元测试实战指南FppTest/component 测试套件解析与 fprime util 构建运行流程 本指南以 F´F Prime嵌入式系统编程F´ (F Prime) DpManager 组件基于规则的单元测试Abstract State、规则组与随机场景解析F´ F Prime DpManager 组件基于规则的单元测试Abstract State、规则组与随机场景解析 导读 本文以 Svc/DpManager/嵌入式系统编程上一篇如何使用Linux Optimizer自动化优化你的Linux服务器新手入门教程下一篇Qwik-UI贡献者教程如何为开源组件库提交你的第一个PR创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表