监视GNU Radio中的缓冲区

时间:2018-07-12 08:46:29

标签: c++ fpga xilinx gnuradio gnuradio-companion

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

在GNU无线电同伴中,我创建了一个自定义模块,用于控制板上的GPIO输出端口。另外,我有一个独立的源块,它将信息馈入FMCOMMS GNU块。我要维护的顺序是,在GNU无线电中,我首先将数据发送到FMCOMMS块,其次我要确保FMCOMMS块消耗了数据(基本上是通过检查缓冲区),然后最后我想控制GPIO输出。

根据我的观察,源块缓冲区似乎没有发送完所有内容。这将在我的项目中引起一个重大问题,因为这意味着GPIO数据将在将项目发送到其他GNU块之前或与之并行发送。那是因为我要通过直接访问自定义块的“工作”功能中的GPIO地址来设置GPIO值。

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

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";
}

是否可以监视缓冲区,以便确定何时发送第一部分数据位?还是有办法确保每个输出项都像连续流一样发送到下一个块?

GNU Radio Companion版本:3.7.8

OS:FPGA上运行的Linaro 14.04映像

1 个答案:

答案 0 :(得分:1)

  

或者是否有办法确保每个输出项都像连续流一样发送到下一个块?

不,那不是GNU Radio的工作原理(完全没有!):

前一段时间,我写了article,解释了GNU Radio如何处理缓冲区以及缓冲区的实际含义。尽管您可能不太喜欢GNU Radio缓冲区的内存中体系结构,但让我快速总结一下它的动态:

  • 调用(general_work函数的缓冲区在所有实际可行的情况下都表现良好,例如可线性寻址的环形缓冲区。您会一次获得随机数量的样本(限制为最小数量,数量的倍数),所有您不消耗的样本将在下次调用work时交给您。
  • 这些缓冲区因此可以跟踪您已消耗了多少内存,从而可以了解缓冲区中有多少可用空间。
  • 一个块看到的输入缓冲区实际上是流程图中“上游”块的输出缓冲区。
  • GNU Radio的计算是背压控制的:只要满足以下条件,任何块的work方法都将立即在无限循环中调用:
    1. 该块有足够的输入来工作,
    2. 有足够的输出缓冲区空间可写。
  • 因此,一旦一个块完成其work调用,就会告知上游块有新的可用输出空间,因此通常导致其运行
  • 这导致高度并行性,因为即使相邻的块也可以同时运行而不会发生冲突
  • 这种体系结构倾向于使用大块的输入项,尤其是对于需要花费较长时间的计算机块而言:当该块仍在工作时,其输入缓冲区已经充满了样本块;完成后,可能会立即再次调用它,所有可用的输入缓冲区已经充满了新样本。
  • 这种架构是异步的:即使流程图中两个块“平行”,它们产生的项目数量之间也没有定义的时间关系。

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

  

是否可以监视缓冲区,以便确定何时发送第一部分数据位?

除此之外,一种异步告知另一个块(是的,您已经处理了N个样本)的方法将是拥有一个仅观察您要同步的两个块的输出并消耗一个块的块。来自两个输入的相同数量的样本,或者使用消息传递来实现某些目的。同样,我怀疑这不是您实际问题的解决方案。