У меня есть вопрос относительно буферизации между блоками в 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
Или есть способ убедиться, что каждый отдельный элемент вывода отправляется как непрерывный поток в следующий блок (ы)?
Нет, это не так, как работает GNU Radio (вообще!):
Некоторое время назад я написал статья это объясняет, как GNU Radio работает с буферами, и каковы они на самом деле. Хотя архитектура буферов GNU Radio в памяти может представлять для вас меньший интерес, позвольте мне вкратце рассказать о ее динамике:
general_
)work
функции вызываются с поведением для всего, что практично, как линейно адресуемые кольцевые буферы. Вы получаете случайное количество образцов одновременно (ограниченное минимальными числами, кратными числами), и все, что вы не потребляете, будет передано вам в следующий раз work
называется.work
метод будет немедленно вызван в бесконечном цикле, если:
work
вызов, блок восходящего потока информируется, что есть новое свободное пространство вывода, таким образом, как правило, приводит к его запускуЯ даже не убежден, что переключение GPIO время от времени на основе вычисления скорости в этой полностью недетерминированной модели графика потоков данных является хорошей идеей для начала. Может быть, вы бы предпочли рассчитать «временные метки», при которых следует переключать GPIO, и посылать кортежи команд (timestamp, gpio state) некоторому объекту в вашей FPGA, который сохраняет абсолютное время? На шкале распространения радиосигнала и высокоскоростной обработки сигналов время ЦП действительно неточно, и вы должны использовать тот факт, что у вас есть FPGA для фактической реализации детерминированной синхронизации, и использовать программное обеспечение, работающее на ЦП (то есть, GNU Radio), чтобы определить когда это должно произойти.
Есть ли способ контролировать буфер, чтобы я мог определить, когда была отправлена моя первая часть бит данных?
Кроме этого, метод для асинхронного оповещения другого другого блока о том, что, да, вы обработали N выборок, будет либо иметь один блок, который просто наблюдает за выходами обоих блоков, которые вы хотите синхронизировать, и использует идентичное количество выборки из обоих входов, или реализовать что-то с помощью передачи сообщений. Опять же, я подозреваю, что это не решение вашей реальной проблемы.
Других решений пока нет …