GNU Radio教程 8.消息传递


内容:
1 介绍
2 消息传递 API
2.1 消息处理函数
2.2 通过流程图连接消息
3 从外部来源发布from
4 使用消息作为命令
5 代码示例
5.1 C++
5.2
6 流程图示例
6.1 PDU
7 流程图示例:聊天应用程序
GNU Radio 最初是一个流系统,没有其他机制在块之间传递数据 。数据流是一种适用于样本、比特等的模型,但实际上并不是控制数据、元数据或数据包结构的正确机制(至少在处理链中的某个点) 。
我们通过引入标签流解决了部分问题(请参阅流标签) 。这是数据流的并行流 。不同之处在于标签旨在保存元数据和控制信息 。标签与数据流中的特定样本特别相关,并与数据一起向下游流动 。流标签同步传递模型允许其他模块识别已经发生或应该发生在特定item上事件或动作 。缺点是标签流实际上只能在工作函数内部访问,并且只能沿一个方向流动 。它的好处是它与数据是同步的 。
我们想要一个更通用的消息传递系统有几个原因 。第一个是允许下游模块与上游模块通信(不是流标签的单方向) 。第二个是允许我们以更简单的方式在外部应用程序和 GNU Radio 之间来回通信 。GNU Radio 的消息传递接口在异步的基础上处理这些情况 。
消息传递接口的实现依赖于 GNU Radio 中的多态类型 (PMT) 。
二、消息传递 API
消息传递接口设计在 gr:: 中,它是 GNU Radio 中所有块的父类 。每个块都有一组消息队列来保存传入的消息,并且可以将消息发布到其他块的消息队列中 。这些模块还区分输入和输出端口 。
块必须在其构造函数中声明其输入和输出消息端口 。消息端口由名称来描述,该名称实际上是 PMT 符号(i.e., an) 。注册新端口的 API 调用是:
在中:
消息端口现在可以通过该端口名称来识别 。其他可能想要在端口上发布或接收消息的块必须订阅它 。当一个块有消息要发送时,它们会使用以下 API 在特定端口上发布:
在中:
订阅通常以连接消息端口的形式完成,作为流程图的一部分,稍后将讨论 。在内部,当消息端口连接时,调用 gr:::: 方法 。
任何订阅了另一个块的输出消息端口的块都将在其发布时收到该消息 。在内部,当一个块发布消息时,它只是遍历所有已订阅它模块并使用 gr::::_post 方法将消息发送到该块的消息队列 。
2.1消息处理函数
一个模块如果订阅了其他模块的,那它必须声明一个消息处理函数来处理发送到它的消息 。使用gr::::r_in方法来注册一个端口之后,将消息处理程序绑定到此端口 。
从使用 C++11 的 GNU Radio V3.8 开始,使用函数来做到这一点:
在中:
当一条新消息被推送到端口的消息队列时,正是这个函数用于处理该消息 。'' 与注册输入端口时使用的 PMT 相同 。'::tion' 是类的成员函数,指定用于处理发送到此端口的消息 。
所有消息处理函数的原型是:
在中,等效函数为:
下面给出了示例:
2.2通过流程图连接消息
从流程图看,我们使用 gr:::: 方法来订阅块到其他块的消息 。假设块src有一个名为pdus的输出消息端口 ,而块dbg有一个名为print的输入端口 。流程图中的消息连接(在中)如下所示:
端口pdus上的src块发布的所有消息都将由端口print上的dbg接收 。请注意,我们只是使用字符串来定义端口,而不是 PMT 符号 。这便于用户更轻松地输入端口名称(作为参考,您可以在中使用 pmt:: 函数作为 pmt.("") 创建一个 PMT 符号) 。
用户还可以使用以下 API 调用,来查询模块的消息输入和消息输出端口的名称: