[prev in list] [next in list] [prev in thread] [next in thread]
List: gnuradio-discuss
Subject: [Discuss-gnuradio] UHD Simultaneous tx/rx Loopback Problem
From: Isaac Gerg <isaac.gerg () gergltd ! com>
Date: 2011-01-27 16:08:19
Message-ID: AANLkTin3CHv3bCLKm0v=qbfDOFhD6UqOyUpWNFv8nrUu () mail ! gmail ! com
[Download RAW message or body]
Using USRP 1.
I have 3 threads running. A rx, a tx, and a sendMessage thread. The rx
receives continuously. I send a burst every 10 seconds with the sendMessage
thread. sendMessage posts the message to a queue (mutex locked) which
triggers the tx thread to pull the message from the queue and send the
samples. Currently, I have jimmy rigged the tx thread to send one cycle of
a complex exp() instead of sending the message (for debugging purposes).
However, I dont see the message on the rx side of the house.
I look for the message by monitoring the abs() of each sample and printing
out a message when the abs > 0.01. I get about 10-20 samples that fit this
criteria every 10 seconds when I should be seeing a lot more. No matter how
I vary my tx buffer length, I seem to always see the same number of samples
at the rx end.
Ive gone through my code again and I dont understand why this isnt working.
Here is a dump:
Some setup code:
m_usrpSampsPerBlock = m_pDev->get_max_recv_samps_per_packet();
//
http://ettus-apps.sourcerepo.com/redmine/ettus/projects/uhd/repository/revisions/master/entry/host/examples/benchmark_rx_rate.cpp
// Flush rx buffer
// idg - This seems to do nothing.
uhd::rx_metadata_t md;
std::vector<std::complex<float> > buff(m_usrpSampsPerBlock);
while(m_pDev->recv(&buff.front(), buff.size(),
md,uhd::io_type_t::COMPLEX_FLOAT32,uhd::device::RECV_MODE_ONE_PACKET))
{
// NOP
}
//handle the error codes
stringstream msg;
switch(md.error_code)
{
case uhd::rx_metadata_t::ERROR_CODE_NONE:
m_pLogger->log("USRP flush OK",__FILE__,__LINE__);
break;
case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
//if (num_acc_samps == 0) continue;
msg << "Got timeout before all samples received, possible packet
loss, exiting loop...";
m_pLogger->log(msg.str(),__FILE__,__LINE__);
break;
case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
//if (num_acc_samps == 0) continue;
msg << "Overflow!";
m_pLogger->log(msg.str(),__FILE__,__LINE__);
break;
default:
msg << "Got error code 0x"<< md.error_code << ", exiting
loop...";
m_pLogger->log(msg.str(),__FILE__,__LINE__);
break;
}
//setup rx streaming
m_pSdev->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
--
The tx thread
Int32 burstSizeSamps = 100;
vector<complex<Float32> > vec(burstSizeSamps);
// Set up tx params. We wish to send a burst.
uhd::tx_metadata_t md;
md.start_of_burst = true;
md.end_of_burst = true;
Float32 v = 0;
for (Int32 k=0;k<vec.size();++k)
{
v = 2*M_PI*(Float32(k)/Float32(vec.size()));
vec[k] = complex<Float32>(cos(v), sin(v));
//cout << vec[k] << " ";
}
cout << endl;
// Send the entire contents of the buffer
// This should be the only place where data is sent over the air!
cout << "sending size [cpx samps]: " << vec.size() << endl;
m_pDev->send(&(vec.front()), vec.size(),
md,uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::SEND_MODE_FULL_BUFF);
}
the rx thread:
m_pLogger->log("CTransceiver::rxThread() started.",__FILE__,__LINE__);
uhd::set_thread_priority_safe();
uhd::rx_metadata_t md;
std::vector<std::complex<Float32> >* pBuff = NULL;
stringstream msg;
UInt64 blocksProcessed = 0;
CTimer myTimer;
myTimer.start();
while (!(m_shutdown))
{
// Rx data
pBuff = new vector<complex<Float32> >(m_usrpSampsPerBlock);
size_t num_rx_samps =
m_pDev->recv(&(pBuff->front()),pBuff->size(),md,uhd::io_type_t::COMPLEX_FLOAT32,uhd::device::RECV_MODE_ONE_PACKET);
msg.str("");
if (0 == num_rx_samps)
{
m_pLogger->log("No samps rx.",__FILE__,__LINE__);
}
//handle the error codes
switch(md.error_code)
{
case uhd::rx_metadata_t::ERROR_CODE_NONE:
break;
case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
//if (num_acc_samps == 0) continue;
msg << "Got timeout before all samples received, possible
packet loss, exiting loop...";
m_pLogger->log(msg.str(),__FILE__,__LINE__);
goto done_loop;
case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
//if (num_acc_samps == 0) continue;
msg << "Overflow!";
m_pLogger->log(msg.str(),__FILE__,__LINE__);
goto done_loop;
default:
msg << "Got error code 0x"<< md.error_code << ", exiting
loop...";
m_pLogger->log(msg.str(),__FILE__,__LINE__);
goto done_loop;
}
done_loop:
{
// Lock queue
boost::mutex::scoped_lock l(*m_pMutexRxQueue);
// Put data block on queue
m_pRxQueue->push_back(pBuff);
}
}
// another thread wakes up and if there are blocks on the queue, it sends
them to processBlock()
--
processBlock()
void CTransceiver::processBlock(vector<complex<Float32> >* pBlock)
{
//cout << pBlock->size() << endl;
for (Int32 k=0;k<pBlock->size();++k)
{
if (abs((*pBlock)[k]) > 0.01)
{
cout << " HERE " << (*pBlock)[k] << " " << k << endl;
}
}
delete pBlock;
}
--
My output (the logger wakes up every 1 second to write the message queue to
disk)
[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:274) USRP flush OK
[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:296)
CTransceiver::setupUsrp() setup complete.
[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:301)
CTransceiver::rxWorkerThread started.
[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:125)
CTransceiver::rxThread() started.
[2011-01-27|10:57:43 -0500] (../src/Transceiver.cpp:47)
CTransceiver::txThread() started.
sending size [cpx samps]: 100
HERE (-0.0129704,-0.0245979) 41
HERE (-0.0138554,-0.0418409) 42
HERE (-0.0126652,-0.0428785) 43
HERE (-0.00927763,-0.0444044) 44
HERE (-0.00708029,-0.044557) 45
HERE (-0.00366222,-0.0450758) 46
HERE (-0.00152593,-0.0452284) 47
HERE (0.00238044,-0.0451674) 48
HERE (0.00332652,-0.0452284) 49
HERE (0.00946074,-0.0398877) 50
HERE (-0.004944,-0.0150456) 51
[2011-01-27|10:57:52 -0500] (../src/Transceiver.cpp:389) Posted message to
Tx queue.
[2011-01-27|10:57:53 -0500] (../src/Transceiver.cpp:86)
CTransceiver::txThread() sent 1 messages.
sending size [cpx samps]: 100
HERE (0.00979644,0.00268563) 1374
HERE (-0.024659,-0.0125126) 1513
HERE (-0.0340892,-0.027131) 1514
HERE (-0.0344249,-0.0291757) 1515
HERE (-0.0332347,-0.0318918) 1516
HERE (-0.0297861,-0.0314646) 1517
HERE (-0.0299081,-0.0389416) 1518
HERE (-0.0249031,-0.0137944) 1519
[2011-01-27|10:58:02 -0500] (../src/Transceiver.cpp:389) Posted message to
Tx queue.
[2011-01-27|10:58:03 -0500] (../src/Transceiver.cpp:86)
CTransceiver::txThread() sent 1 messages.
sending size [cpx samps]: 100
HERE (0.0184027,-0.00933866) 2819
HERE (-0.00930815,-0.0262764) 2924
HERE (-0.00799585,-0.0425428) 2925
HERE (-0.00534074,-0.0445265) 2926
HERE (-0.00323496,-0.0449538) 2927
HERE (0.000549333,-0.0451979) 2928
HERE (0.00173956,-0.0447401) 2929
HERE (0.00778222,-0.04532) 2930
HERE (0.000671407,-0.0408643) 2931
[2011-01-27|10:58:12 -0500] (../src/Transceiver.cpp:389) Posted message to
Tx queue.
[2011-01-27|10:58:13 -0500] (../src/Transceiver.cpp:86)
CTransceiver::txThread() sent 1 messages.
--
Also, the code I got from the repo to flush the rx buffer doesnt seem to
work. Upon startup, I get a bunch of samples that trip the threshold
(abs()>0.01) before a message is even sent out. Why is this?
Any help would be greatly appreciated!
Thanks,
Isaac
[Attachment #3 (text/html)]
Using USRP 1.<br><br>I have 3 threads running. A rx, a tx, and a sendMessage thread. \
The rx receives continuously. I send a burst every 10 seconds with the sendMessage \
thread. sendMessage posts the message to a queue (mutex locked) which triggers the \
tx thread to pull the message from the queue and send the samples. Currently, I have \
jimmy rigged the tx thread to send one cycle of a complex exp() instead of sending \
the message (for debugging purposes). However, I dont see the message on the rx side \
of the house. <br> <br>I look for the message by monitoring the abs() of each sample \
and printing out a message when the abs > 0.01. I get about 10-20 samples that \
fit this criteria every 10 seconds when I should be seeing a lot more. No matter how \
I vary my tx buffer length, I seem to always see the same number of samples at the rx \
end.<br> <br>Ive gone through my code again and I dont understand why this isnt \
working. Here is a dump:<br><br>Some setup code:<br> m_usrpSampsPerBlock = \
m_pDev->get_max_recv_samps_per_packet();<br><br> // <a \
href="http://ettus-apps.sourcerepo.com/redmine/ettus/projects/uhd/repository/revisions \
/master/entry/host/examples/benchmark_rx_rate.cpp">http://ettus-apps.sourcerepo.com/re \
dmine/ettus/projects/uhd/repository/revisions/master/entry/host/examples/benchmark_rx_rate.cpp</a><br>
// Flush rx buffer<br> // idg - This seems to do nothing.<br> \
uhd::rx_metadata_t md;<br> std::vector<std::complex<float> > \
buff(m_usrpSampsPerBlock);<br> while(m_pDev->recv(&buff.front(), \
buff.size(), md,uhd::io_type_t::COMPLEX_FLOAT32,uhd::device::RECV_MODE_ONE_PACKET))<br>
{<br> // NOP<br> }<br> //handle the error codes<br> stringstream \
msg;<br> switch(md.error_code)<br> {<br> case \
uhd::rx_metadata_t::ERROR_CODE_NONE:<br> m_pLogger->log("USRP \
flush OK",__FILE__,__LINE__);<br> break;<br> case \
uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:<br> //if (num_acc_samps == 0) \
continue;<br> msg << "Got timeout before all samples received, \
possible packet loss, exiting loop...";<br> \
m_pLogger->log(msg.str(),__FILE__,__LINE__);<br> break;<br> case \
uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:<br> //if (num_acc_samps == 0) \
continue;<br> msg << "Overflow!";<br> \
m_pLogger->log(msg.str(),__FILE__,__LINE__);<br> break;<br> \
default:<br> msg << "Got error code 0x"<< \
md.error_code << ", exiting loop...";<br> \
m_pLogger->log(msg.str(),__FILE__,__LINE__);<br> break;<br> \
}<br><br> //setup rx streaming<br> \
m_pSdev->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);<br><br><br>-- \
<br> The tx thread<br> Int32 burstSizeSamps = 100;<br> \
vector<complex<Float32> > vec(burstSizeSamps);<br><br> // Set up tx \
params. We wish to send a burst.<br> uhd::tx_metadata_t md;<br> \
md.start_of_burst = true;<br> md.end_of_burst = true;<br><br> Float32 v = \
0;<br> for (Int32 k=0;k<vec.size();++k)<br> {<br> v = \
2*M_PI*(Float32(k)/Float32(vec.size()));<br> vec[k] = \
complex<Float32>(cos(v), sin(v));<br> //cout << vec[k] << " \
";<br> }<br> cout << endl;<br><br> // Send the entire contents of \
the buffer<br> // This should be the only place where data is sent over the \
air!<br> cout << "sending size [cpx samps]: " << vec.size() \
<< endl;<br> m_pDev->send(&(vec.front()), vec.size(), \
md,uhd::io_type_t::COMPLEX_FLOAT32, \
uhd::device::SEND_MODE_FULL_BUFF);<br>}<br><br>the rx thread:<br> \
m_pLogger->log("CTransceiver::rxThread() \
started.",__FILE__,__LINE__);<br> <br> \
uhd::set_thread_priority_safe();<br><br> uhd::rx_metadata_t md;<br> \
std::vector<std::complex<Float32> >* pBuff = NULL;<br> stringstream \
msg;<br><br> UInt64 blocksProcessed = 0;<br> CTimer myTimer;<br> \
myTimer.start();<br><br> while (!(m_shutdown))<br> {<br> // Rx data<br> \
pBuff = new vector<complex<Float32> >(m_usrpSampsPerBlock);<br><br> \
size_t num_rx_samps = \
m_pDev->recv(&(pBuff->front()),pBuff->size(),md,uhd::io_type_t::COMPLEX_FLOAT32,uhd::device::RECV_MODE_ONE_PACKET);<br>
msg.str("");<br><br> if (0 == num_rx_samps)<br> {<br> \
m_pLogger->log("No samps rx.",__FILE__,__LINE__);<br> }<br><br> \
//handle the error codes<br> switch(md.error_code)<br> {<br> case \
uhd::rx_metadata_t::ERROR_CODE_NONE:<br> break;<br> case \
uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:<br> //if (num_acc_samps == 0) \
continue;<br> msg << "Got timeout before all samples \
received, possible packet loss, exiting loop...";<br> \
m_pLogger->log(msg.str(),__FILE__,__LINE__);<br> goto \
done_loop;<br> case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:<br> \
//if (num_acc_samps == 0) continue;<br> msg << \
"Overflow!";<br> m_pLogger->log(msg.str(),__FILE__,__LINE__);<br> \
goto done_loop;<br> default:<br> msg << "Got \
error code 0x"<< md.error_code << ", exiting loop...";<br> \
m_pLogger->log(msg.str(),__FILE__,__LINE__);<br> goto \
done_loop;<br> }<br><br> done_loop:<br><br> {<br> // \
Lock queue<br> boost::mutex::scoped_lock l(*m_pMutexRxQueue);<br> // Put \
data block on queue<br> m_pRxQueue->push_back(pBuff);<br> }<br> \
}<br><br> // another thread wakes up and if there are blocks on the queue, it sends \
them to processBlock()<br><br> <br>--<br>processBlock()<br>void \
CTransceiver::processBlock(vector<complex<Float32> >* pBlock)<br>{<br> \
//cout << pBlock->size() << endl;<br> for (Int32 \
k=0;k<pBlock->size();++k)<br> {<br> if (abs((*pBlock)[k]) > \
0.01)<br> {<br> cout << " HERE " << \
(*pBlock)[k] << " " << k << endl;<br> }<br> \
}<br> delete pBlock;<br> }<br>--<br><br>My output (the logger wakes up every 1 \
second to write the message queue to disk)<br><br>[2011-01-27|10:57:42 -0500] \
(../src/Transceiver.cpp:274) USRP flush OK<br>[2011-01-27|10:57:42 -0500] \
(../src/Transceiver.cpp:296) CTransceiver::setupUsrp() setup complete.<br> \
[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:301) CTransceiver::rxWorkerThread \
started.<br>[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:125) \
CTransceiver::rxThread() started.<br>[2011-01-27|10:57:43 -0500] \
(../src/Transceiver.cpp:47) CTransceiver::txThread() started.<br> <br>sending size \
[cpx samps]: 100<br> HERE (-0.0129704,-0.0245979) 41<br> HERE \
(-0.0138554,-0.0418409) 42<br> HERE (-0.0126652,-0.0428785) 43<br> HERE \
(-0.00927763,-0.0444044) 44<br> HERE (-0.00708029,-0.044557) 45<br> HERE \
(-0.00366222,-0.0450758) 46<br> HERE (-0.00152593,-0.0452284) 47<br> HERE \
(0.00238044,-0.0451674) 48<br> HERE (0.00332652,-0.0452284) 49<br> HERE \
(0.00946074,-0.0398877) 50<br> HERE (-0.004944,-0.0150456) 51<br> \
[2011-01-27|10:57:52 -0500] (../src/Transceiver.cpp:389) Posted message to Tx \
queue.<br>[2011-01-27|10:57:53 -0500] (../src/Transceiver.cpp:86) \
CTransceiver::txThread() sent 1 messages.<br><br>sending size [cpx samps]: 100<br> \
HERE (0.00979644,0.00268563) 1374<br> HERE (-0.024659,-0.0125126) 1513<br> HERE \
(-0.0340892,-0.027131) 1514<br> HERE (-0.0344249,-0.0291757) 1515<br> HERE \
(-0.0332347,-0.0318918) 1516<br> HERE (-0.0297861,-0.0314646) 1517<br> HERE \
(-0.0299081,-0.0389416) 1518<br> HERE (-0.0249031,-0.0137944) \
1519<br>[2011-01-27|10:58:02 -0500] (../src/Transceiver.cpp:389) Posted message to Tx \
queue.<br>[2011-01-27|10:58:03 -0500] (../src/Transceiver.cpp:86) \
CTransceiver::txThread() sent 1 messages.<br> <br>sending size [cpx samps]: 100<br> \
HERE (0.0184027,-0.00933866) 2819<br> HERE (-0.00930815,-0.0262764) 2924<br> HERE \
(-0.00799585,-0.0425428) 2925<br> HERE (-0.00534074,-0.0445265) 2926<br> HERE \
(-0.00323496,-0.0449538) 2927<br> HERE (0.000549333,-0.0451979) 2928<br> HERE \
(0.00173956,-0.0447401) 2929<br> HERE (0.00778222,-0.04532) 2930<br> HERE \
(0.000671407,-0.0408643) 2931<br>[2011-01-27|10:58:12 -0500] \
(../src/Transceiver.cpp:389) Posted message to Tx queue.<br> [2011-01-27|10:58:13 \
-0500] (../src/Transceiver.cpp:86) CTransceiver::txThread() sent 1 \
messages.<br>--<br><br>Also, the code I got from the repo to flush the rx buffer \
doesnt seem to work. Upon startup, I get a bunch of samples that trip the threshold \
(abs()>0.01) before a message is even sent out. Why is this?<br> <br>Any help \
would be greatly appreciated!<br><br>Thanks,<br>Isaac<br>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic