Здравствуйте.
Работаю с модулем E502 через USB. Планирую переписывать стандартную прошивку BlackFin, для кастомной обработки потоковых данных, так что запускаю модуль в режиме работы с DSP, загружая штатную прошивку через X502_BfCheckFirmwareIsLoaded (собрана из исходников в VisualDSP без изменений). Собственно проблема: разрешаю синхронный поток данных с флагом X502_STREAM_ALL_IN и запускаю его, код чтения данных описан ниже, однако через какое-то время возникает ошибка "Произошло переполнение внутреннего буфера для потока синхронного ввода". В чём может быть проблема и что я делаю не так.
void CLcard::onStreamProcessed()
{
LcardErr err = X502_ERR_OK;
int32_t rcv_size;
uint32_t adc_size, din_size;
const int realBlockSize = 4096 * 20;
while (m_streamStarted && err == X502_ERR_OK)
{
std::vector<uint32_t> rcv_buf(realBlockSize);
std::vector<double> adc_data(realBlockSize);
std::vector<uint32_t> din_data(realBlockSize);
// принимаем данные (по таймауту)
rcv_size = X502_Recv(m_deviceHandel, rcv_buf.data(), realBlockSize, m_readTimeoutADC);
// результат меньше нуля означает ошибку
if (rcv_size < 0)
{
err = rcv_size;
logError("Error getting data: %s\1"_q.arg(errorToString(err)));
continue;
}
else if (rcv_size == 0)
{
logWarning("Zerro data in buffer");
continue;
}
// получаем номер логического канала, которому соответствует первый отсчет АЦП в массиве
uint32_t first_lch;
X502_GetNextExpectedLchNum(m_deviceHandel, &first_lch);
adc_size = realBlockSize;
din_size = realBlockSize;
// обрабатываем принятые данные, распределяя их на данные АЦП и цифровых входов
err = X502_ProcessData(m_deviceHandel, rcv_buf.data(), rcv_size, X502_PROC_FLAGS_VOLT, adc_data.data(), &adc_size, din_data.data(), &din_size);
if (err != X502_ERR_OK)
{
logError("Error getting data: %1"_q.arg(errorToString(err)));
continue;
}
QString dataMsg = "Block %1. Processed data = %2, Digit input = %3, Buff size: %4\n"_q.arg(QString::number(++m_lastBlockNum),
QString::number(adc_size),
QString::number(din_size),
QString::number(rcv_size));
// если приняли цифровые данные - выводим первый отсчет
if (din_size != 0)
{
uint32_t dinData = din_data[0];
QVector<bool> newDigValues = m_dio->uint32ToBoolVector(dinData);
QVector<bool> currentDigValue = m_dio->getInValues();
for (int i = 0; i < 16; i++)
{
if (currentDigValue[i] != newDigValues[i])
{
m_dio->setIn(i, newDigValues[i]);
}
}
dataMsg += "\t dinData = %1n"_q.arg(dinData);
emit sig_measureDIN(dinData);
}
// выводим по одному отсчету на канал. если обработанный блок
// начинается не с начала кадра, то в данном примере для
// вывода берем конец неполного кадра и начало следующего
for (uint32_t lch = 0; lch < (uint32_t)m_channelCount; lch++)
{
// определяем позицию первого отсчета, соответствующего заданному логическому каналу:
// либо с конца не полного кадра, либо из начала следующего
uint32_t pos = lch >= first_lch ? lch - first_lch : m_channelCount - first_lch + lch;
if (pos <= adc_size)
{
double measure = adc_data[pos];
dataMsg += "\t lch[%1] = %2 \n"_q.arg(QString::number(lch)).arg(QString::number(measure));
emit sig_measureADC(measure);
}
else
{
dataMsg += "\t lch[%1] = ---- \n"_q.arg(QString::number(lch));
}
}
log(dataMsg);
}
QMetaObject::invokeMethod(this, &CLcard::streamStop);
}