Мониторинг буферов в GNU Radio

У меня есть вопрос относительно буферизации между блоками в GNU Radio. Я знаю, что каждый блок в GNU (включая пользовательские блоки) имеет буферы для хранения элементов, которые будут отправлены или получены. В моем проекте есть определенная последовательность, которую я должен поддерживать для синхронизации событий между блоками. Я использую радио GNU на платформе Xilinx ZC706 FPGA с FMCOMMS5.

В радио-компаньоне GNU я создал специальный блок, который управляет выходным портом GPIO на плате. Кроме того, у меня есть независимый исходный блок, который подает информацию в блок FMCOMMS GNU. Последовательность, которую я пытаюсь сохранить, заключается в том, что в радио GNU я сначала отправляю данные в блок FMCOMMS, во-вторых, я хочу убедиться, что данные были получены блоком FMCOMMS (по сути, путем проверки буфера), затем, наконец, я хочу контролировать выход GPIO.

Судя по моим наблюдениям, буфер исходного блока, похоже, не отправляет элементы, пока не заполнится. Это вызовет серьезную проблему в моем проекте, поскольку это означает, что данные GPIO будут отправляться до или параллельно с отправкой элементов в другие блоки GNU. Это потому, что я устанавливаю значение 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

ОС: образ Linaro 14.04, работающий на FPGA

0

Решение

Или есть способ убедиться, что каждый отдельный элемент вывода отправляется как непрерывный поток в следующий блок (ы)?

Нет, это не так, как работает GNU Radio (вообще!):

Некоторое время назад я написал статья это объясняет, как GNU Radio работает с буферами, и каковы они на самом деле. Хотя архитектура буферов GNU Radio в памяти может представлять для вас меньший интерес, позвольте мне вкратце рассказать о ее динамике:

  • Буферы, которые (general_)work функции вызываются с поведением для всего, что практично, как линейно адресуемые кольцевые буферы. Вы получаете случайное количество образцов одновременно (ограниченное минимальными числами, кратными числами), и все, что вы не потребляете, будет передано вам в следующий раз work называется.
  • Эти буферы, следовательно, отслеживают, сколько вы израсходовали, и, следовательно, сколько свободного места в буфере.
  • Входной буфер, который видит блок, на самом деле является выходным буфером «восходящего» блока в потоковом графе.
  • Вычисления GNU Radio контролируются противодавлением: любой блок work метод будет немедленно вызван в бесконечном цикле, если:
    1. Там достаточно ввода для блока, чтобы сделать работу,
    2. Там достаточно места в буфере вывода для записи.
  • Поэтому, как только один блок заканчивает свою work вызов, блок восходящего потока информируется, что есть новое свободное пространство вывода, таким образом, как правило, приводит к его запуску
  • Это приводит к высокой параллельности, так как даже смежные блоки могут работать одновременно без конфликта
  • Эта архитектура поддерживает большие порции входных элементов, особенно для блоков, которые занимают относительно много времени на компьютере: пока блок все еще работает, его входной буфер уже заполняется порциями сэмплов; когда он закончится, скорее всего, он сразу же будет вызван снова со всем доступным входным буфером, уже заполненным новыми выборками.
  • Эта архитектура является асинхронной: даже если два блока являются «параллельными» в вашем потоковом графе, нет определенного временного соотношения между количеством элементов, которые они производят.

Я даже не убежден, что переключение GPIO время от времени на основе вычисления скорости в этой полностью недетерминированной модели графика потоков данных является хорошей идеей для начала. Может быть, вы бы предпочли рассчитать «временные метки», при которых следует переключать GPIO, и посылать кортежи команд (timestamp, gpio state) некоторому объекту в вашей FPGA, который сохраняет абсолютное время? На шкале распространения радиосигнала и высокоскоростной обработки сигналов время ЦП действительно неточно, и вы должны использовать тот факт, что у вас есть FPGA для фактической реализации детерминированной синхронизации, и использовать программное обеспечение, работающее на ЦП (то есть, GNU Radio), чтобы определить когда это должно произойти.

Есть ли способ контролировать буфер, чтобы я мог определить, когда была отправлена ​​моя первая часть бит данных?

Кроме этого, метод для асинхронного оповещения другого другого блока о том, что, да, вы обработали N выборок, будет либо иметь один блок, который просто наблюдает за выходами обоих блоков, которые вы хотите синхронизировать, и использует идентичное количество выборки из обоих входов, или реализовать что-то с помощью передачи сообщений. Опять же, я подозреваю, что это не решение вашей реальной проблемы.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]