当前位置: 首页 > 工具软件 > GNU Units > 使用案例 >

GNU Radio中协议数据包的传递方式

谯皓君
2023-12-01

All the blocks presented so far operate as "infinite stream" blocks, i.e., they simply continue working as long as items are fed into their inputs. The low pass filter is a good example: Every new item is interpreted as a new sample, and the output is always the low-pass filtered version of the input. It does not care about the content of the signal, be it noise, data or whatever.

When handling packets (or PDUs, protocol data units), such a behaviour is not enough. There must be a way to identify PDU boundaries, i.e. tell which byte is the first of this packet and how long it is.

GNU Radio supports two ways to do this: Message passing and tagged stream blocks.

The first is an asynchronous method to directly pass PDUs from one block to another. On a MAC layer, this is probably the preferred behaviour. A block could receive a PDU, add a packet header, and pass the entire packet (including the new header) as a new PDU to another block.

Tagged stream blocks are regular streaming blocks which use stream tags to identify PDU boundaries. This allows mixing blocks which know about PDUs and blocks that don't care about them. There are also blocks to switch between message passing and tagged stream blocks.

https://blog.csdn.net/yuan1164345228/article/details/51872160?utm_source=blogxgwz9&utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-3&spm=1001.2101.3001.4242

在GNU Radio中,所有的模块都基于无限的“数据流”的概念。也就是说,流图中的模块只要在模块的输入端有数据传入,就会不断的被处理。以低通滤波器为例,每个输入的数据都认为是一个需要处理的采样点,而每个输出都是经过低通处理的输入数据,滤波器不会关心输入信号是有用信号还是噪声。

当处理数据包或协议数据单元(PDU,protocol data unit)时,这种机制就显得无能为力,系统必须能够识别数据包的边界,即数据包的开始以及数据包的长度。

针对数据包的传输,GNU Radio中支持两种机制:消息机制和标签机制。

标签机制中仍然采用“数据流”的概念,在传送数据流的基础上,并行传送一路“标签流”。与数据不同的是,标签用于传送控制信息和与数据相关的信息。标签与数据流中特定的采样点相关联,并与数据等时同步地向后续的模块传送,这就使得信号处理模块能够识别出需要进行某种操作的采样点或者是将发生某种事件的采样点。标签机制主要的不足是实际上标签只能在模块的work函数内部才能够访问,而且只能沿着一个方向传送。

消息机制采用异步的方式,将协议数据单元在模块之间进行传输。消息机制允许模块之间的双向通信,另外,消息机制的消息传递接口为外部应用和GNU Radio模块之间提供了一种更为方便的通信方式。比如说,通过这种机制,工作于MAC层的模块可以将从应用程序之外接收到的协议数据单元添加帧头,并将上层数据包转变为新的协议数据单元向下一个模块传送。

(1)消息传递接口

gr::basic_block是GNU Radio中所有模块的基类,其中定义了消息传递接口。每个模块都具有一组消息队列用于存储输入的消息,并将消息发送到其它模块的消息队列。模块的消息输入和输出接口名称为PMT类型,通过PMT符号进行区分,并在模块的构造函数中进行声明。注册输入和输出消息接口的函数分别为:

voidmessage_port_register_in(pmt::pmt_t port_id)

voidmessage_port_register_out(pmt::pmt_t port_id)

现在,通过接口名称我们已经能够将消息端口进行区分,其它模块如果希望通过这个端口接收消息,必须对该端口进行订阅;当其它模块需要发送消息时,也是向特定的端口发布消息。订阅和发布消息的API接口如下:

void message_port_pub(pmt::pmt_t port_id,pmt::pmt_t msg);

void message_port_sub(pmt::pmt_t port_id,pmt::pmt_t target);

voidmessage_port_unsub(pmt::pmt_t port_id,pmt::pmt_t target);

(2)消息处理函数

使用消息的模块中必须声明一个消息处理函数对输入的消息进行处理,当完成对一个消息端口的订阅后,需要将该端口与消息处理函数进行绑定,在GNU Radio中,使用了Boost库提供的bind函数来完成该操作。

set_msg_handler(pmt::pmt_t port_id,

    boost::bind(&block_class::message_handler_function, this, _1));

 类似资料: