GNU Radio教程 8.消息传递( 二 )


这些的返回值是一个用 PMT 符号填充的 PMT 向量,因此必须使用 PMT 运算符来操作它们 。
每个块都有内部方法来处理消息的发布和接收 。gr::::_post 方法接收一条消息并将其放入其队列中 。发布消息的模块使用块的 gr::::_post 方法作为访问消息队列的方式 。所以正确名字的消息队列会有一条新消息 。发布消息还具有唤醒处于等待状态的模块的线程 。因此,如果接受消息模块处于空闲等待状态,一旦发布消息,它就会唤醒并调用消息处理程序 。
三、从外部源发布消息
消息传递架构的一个重要特性是如何使用它来接收来自外部源的消息 。我们可以直接调用块的 gr::::_post 方法并传递消息 。因此任何带有输入消息端口的块都可以通过这种方式接收来自外部的消息 。
以下示例中使用模块作为流程图的 block 。它的目的是等待消息(PDU,协议数据单元,对等实体间通信的数据包) ,并将它们转换为普通流将其发布 。有效负载将作为普通流发送,而元数据将被解码为标签并标记在流上发送 。
因此,如果我们创建了一个src块作为 PDU to ,它有一个 PDU 输入端口,这就是我们将 PDU 消息注入流程图的方式 。这些 PDU 可能来自另一个块或流程图,但在这里,我们将手动创建和插入它们 。
PDU 的元数据部分是空的,因此是 pmt:: 对象 。有效载荷现在只是一个 16 个字节全为 1 的简单向量 。要发布消息,我们必须访问模块的 gr:: 类,我们使用 gr:::: 方法,然后调用 gr::::_post 方法将 PDU 传递到正确的端口.
所有这些机制都在文件 .py 的 QA 代码中进行了探索和测试 。
有一些通过 GRC 使用消息传递基础设施的示例:
四、使用消息作为命令
消息的一个重要用途是将命令发送到下游或上游模块 。这方面的例子包括:
1.gr::qtgui:::频率轴的缩放可以通过消息改变
2.gr::uhd:: 和 gr::uhd:::许多与收发器相关的设 置可以通过命令消息进行操作,例如频率、增益和 LO 偏移
3.gr::::,它从头解析器块接收关于有多少 有效负载项要处理的确认
没有特殊的 PMT 类型来编码命令,但是,强烈建议使用以下格式之一:
1.pmt::cons(KEY, VALUE):这种格式对于采用单个值的命令很有用 。将 KEY和 VALUE 分别视为参数名称和值 。对于 QT GUI 频率接收器,KEY 为 “freq”,VALUE 为新的中心频率,单位为 Hz 。
2.pmt::dict((KEY1: ), (KEY2: ), ...):这个和前面的格式 基 本一样,但是可以提供多个key/value对 。这在单个命令采用多个不能 分解为多个命令消息的参数时特别有用(例如,USRP 块可能在命令消息 中同时具有时间戳和中心频率,它们密切相关) 。
在这两种情况下,所有 KEY 都应该是 pmt::(即字符串) 。值可以是块需要的任何值 。
偏离这种格式可能很诱人,例如,QT 频率接收器可以简单地将浮点值作为命令消息,它仍然可以正常工作 。但是,有一些很好的理由坚持这种格式:
互操作性:使用标准格式的人越多,来自不同来源的块就越有可能一起工作
可检查性:如果消息同时包含值和键,则消息调试块将显示有关消息的更多 有用信息
直觉:这种格式非常通用,不太可能造成不够用的情况(特别是考虑到值本 身就是 PMT) 。作为一个反例,使用位置参数(例如“第一个参数是频率,第 二个参数是增益”)很容易被遗忘,或者在一个地方而不是另一个地方改变,等等 。
五、代码示例
请注意,除了下面的 C++ 或代码之外,如果将消息传递添加到块,您还需要编辑块的 YAML 文件 。添加相应的输入或输出条目(确保域设置为“消息”) 。您不需要指定数据类型 。您还应该确保标签值对应于注册的端口名称 。有关更多详细信息,请参见此处 。