c++ - 在 GNU Radio 中监控缓冲区

标签 c++ fpga xilinx gnuradio gnuradio-companion

我有一个关于 GNU Radio block 之间缓冲的问题。我知道 GNU 中的每个 block (包括自定义 block )都有缓冲区来存储将要发送或接收的项目。在我的项目中,我必须保持一定的顺序来同步块(synchronized block)之间的事件。我在带有 FMCOMMS5 的 Xilinx ZC706 FPGA 平台上使用 GNU radio。

在 GNU radio companion 中,我创建了一个自定义 block 来控制电路板上的 GPIO 输出端口。此外,我有一个独立的源 block ,它正在将信息馈送到 FMCOMMS GNU block 中。我试图保持的顺序是,在 GNU radio 中,我首先将数据发送到 FMCOMMS block ,其次我想确保数据被 FMCOMMS block 消耗(主要是通过检查缓冲区),最后我想控制GPIO输出。

根据我的观察,源 block 缓冲区似乎直到它已满才发送项目。这将导致我的项目出现重大问题,因为这意味着 GPIO 数据将在将项目发送到其他 GNU block 之前或同时发送。那是因为我通过在自定义 block 的“工作”功能中直接访问其地址来设置 GPIO 值。

我尝试在自定义源的“工作”函数中使用 pc_output_buffers_full() 来监视缓冲区,但我总是得到 0.00。我不确定它是否应该在自定义 block 中使用,或者这种情况下的“缓冲区”是否与存储输出项的位置不同。这是一个显示问题的小代码片段:

char level_count = 0, level_val = 1;
vector<float> buff (1, 0.0000);
for(int i=0; i< noutput_items; i++)
{
    if(level_count < 20 && i< noutput_items)
    {
        out[i] = gr_complex((float)level_val,0);
        level_count++;
    }
    else if(i<noutput_items)
    {
        level_count = 0;
        level_val ^=1;
        out[i] = gr_complex((float)level_val,0);
    }
    buff = pc_output_buffers_full();
    for (int n = 0; n < buff.size(); n++)
        cout << fixed << setw(5) << setprecision(2) << setfill('0') << buff[n] << " ";
    cout << "\n";
}

有没有办法监控缓冲区,以便我可以确定我的第一部分数据位何时发送?或者有没有办法确保每个输出项都像连续流一样发送到下一个 block ?

GNU Radio Companion 版本:3.7.8

操作系统:在 FPGA 上运行的 Linaro 14.04 图像

最佳答案

Or is there a way to make sure that the each single output item is being sent like a continuous stream to the next block(s)?

不,这不是 GNU Radio 的工作方式(根本不是!):

不久前我写了一个article这解释了 GNU Radio 如何处理缓冲区,以及缓冲区实际上是什么。虽然您可能对 GNU Radio 缓冲区的内存架构不太感兴趣,但让我快速总结一下它的动态:

  • 调用 (general_)work 函数的缓冲区的行为类似于可线性寻址的环形缓冲区。您一次获得随机数量的样本(限制为最小数量、数量的倍数),所有您未消耗的样本都将在下次调用 work 时交给您。
  • 因此,这些缓冲区会跟踪您消耗了多少,从而跟踪缓冲区中有多少可用空间。
  • block 看到的输入缓冲区实际上是流图中“上游” block 的输出缓冲区。
  • GNU Radio 的计算是背压控制的:任何 block 的 work 方法将立即在无限循环中调用,因为:
    1. block 有足够的输入来工作,
    2. 有足够的输出缓冲区空间可以写入。
  • 因此,一旦一个 block 完成其work 调用,就会通知上游 block 有新的空闲输出空间,因此通常会导致它运行
  • 这导致了高并行性,因为即使是相邻的 block 也可以同时运行而不会发生冲突
  • 这种架构有利于大块的输入项目,尤其是对于需要相对较长时间才能进入计算机的 block :当 block 仍在工作时,其输入缓冲区已经充满了样本 block ;当它完成时,很可能会立即再次调用它,所有可用的输入缓冲区都已经充满了新样本。
  • 此架构是异步的:即使两个 block 在您的流程图中“平行”,它们生成的项目数量之间也没有明确的时间关系。

我什至不相信根据这个完全不确定的时序数据流图模型中的速度计算有时切换 GPIO 是一个好主意。也许您更愿意计算应该切换 GPIO 的“时间戳”,并将(时间戳、gpio 状态)命令元组发送到 FPGA 中保持绝对时间的某个实体?在 radio 传播和高速信号处理的规模上,CPU 时序确实不准确,您应该利用拥有 FPGA 的事实来实际实现确定性时序,并使用运行在CPU(即 GNU Radio)确定何时应该发生。

Is there a way to monitor the buffer so that I can determine when my first part of data bits have been sent?

除此之外,异步地告诉另一个 block ,是的,你已经处理了 N 个样本的方法是让一个 block 只观察你想要同步的两个 block 的输出并消耗一个来自两个输入的相同数量的样本,或者使用消息传递来实现某些东西。同样,我怀疑这不是您实际问题的解决方案。

关于c++ - 在 GNU Radio 中监控缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51301070/

相关文章:

c++ - 我可以在初始化列表中用 10 个相同的整数初始化 STL vector 吗?

arrays - VHDL 中数组切片的使用

memory - 如何在 spartan 3e fpga 中流式传输小视频?

embedded - I2C 主站到主站通信是否可行?

arm - 使用 AXI4Lite 读写的最小时钟周期数是多少

C++将多大小数组存储在变量中

c++ - 如何在成员访问中使用依赖模板默认参数

c++ - Arduino不读取 float 液位开关信号

fpga - 将 XILINX XPS 与 Microblaze 结合使用 - 对 fpga 进行编程的最快方法

fpga - Simulink 中两个复数向量的矩阵乘法