我有一个关于在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映像
答案 0 :(得分:1)
或者是否有办法确保每个输出项都像连续流一样发送到下一个块?
不,那不是GNU Radio的工作原理(完全没有!):
前一段时间,我写了article,解释了GNU Radio如何处理缓冲区以及缓冲区的实际含义。尽管您可能不太喜欢GNU Radio缓冲区的内存中体系结构,但让我快速总结一下它的动态:
general_
)work
函数的缓冲区在所有实际可行的情况下都表现良好,例如可线性寻址的环形缓冲区。您会一次获得随机数量的样本(限制为最小数量,数量的倍数),所有您不消耗的样本将在下次调用work
时交给您。work
方法都将立即在无限循环中调用:
work
调用,就会告知上游块有新的可用输出空间,因此通常导致其运行在这个完全不确定的时序数据流图模型中,我甚至都不相信基于速度计算有时切换GPIO是一个好主意。也许您想计算应该在其上切换GPIO的“时间戳”,并将命令元组(时间戳,gpio状态)发送到FPGA中保留绝对时间的某个实体?在无线电传播和高速率信号处理的规模上,CPU时序确实不准确,您应该使用一个事实,即您拥有一个FPGA来实际实现确定性时序,并使用在FPGA上运行的软件。 CPU(即GNU Radio)确定何时 。
是否可以监视缓冲区,以便确定何时发送第一部分数据位?
除此之外,一种异步告知另一个块(是的,您已经处理了N个样本)的方法将是拥有一个仅观察您要同步的两个块的输出并消耗一个块的块。来自两个输入的相同数量的样本,或者使用消息传递来实现某些目的。同样,我怀疑这不是您实际问题的解决方案。