[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Discuss-gnuradio] usrp_basic_rx::stop appears to take a long time,
Re: [Discuss-gnuradio] usrp_basic_rx::stop appears to take a long time, and reading after stop always returns > 0 bytes
Tue, 29 May 2007 17:06:37 -0700
Mozilla Thunderbird 1.0.7 (Windows/20050923)
Eric Blossom wrote:
I tried it with 4K/16. I am now running at fusb_block_size = 16K and
fusb_nblocks = 512. I also tried with 16K/16. Results for both are similar.
On Fri, May 25, 2007 at 04:23:29PM -0700, Dave Gotwisner wrote:
I am working on an application that will tune to multiple frequencies,
and capture a small number of samples at each frequency for further
The program loop, is essentially, a series of configuration commands
(such as set_rx_frequency, etc.), followed by a start() command. I
then do read() until I get the requested number of samples. I then do
a stop(), and for the hell of it, loop on a read (until there is no
For the purpose of the test, I am using the default buffer sizes for
the ::make call (I also tried fusbBlockSize == 1024 and fusbNblocks =
8K). The decim rate used for the usrp_standard_rx constructor is 8. I
am trying to capture 100,000 samples at each frequency.
There's absolutely no reason to be using fusb_nblocks == 8192.
Try using fusb_block_size = 4096 and fusb_nblocks = 16
Changing to the larger block size significantly sped up the stop()
call. I have now dropped (improved) to about 6 captures a second,
instead of one every 8 seconds. The increased block size apparently
decreased the URB release overhead significantly.
What I am observing is that it takes a very small fraction of a second
to get to my 100,000 samples (as expected), but when I do the stop(),
it is hanging in the stop() command for 8 seconds. Drilling down, into
the usrp_basic_rx::stop() command, we spend 6 seconds in
d_ephandle->stop(), where it is trying to free up 8189 URB requests
in fusb_devhandle::_cancel_pending_rqsts() [1 IOCTL per
USBDEVFS_DISCARDURB call] and 2 seconds in
fusb_devhandle_linux::_reap. A capture that takes approximately 1/16
of a second shouldn't then take 8 seconds closing itself out.
Reading the documentation for the usrp_standard_rx class's start() and
stop() commands indicate they are to start and stop data transfers. The
read after stop returning forever was my mistake. I am used to read()
returning a size_t. The problem is, size_t is unsigned, and the usrp
read returns -1 (or in unsigned land, a very large number). Changing
from size_t to int fixed this problem.
The second observation, is that I loop forever (30 minutes before I
gave up) after doing the stop, where read() is still returning data
(valid or not, I don't know). I would expect that stop() should flush
any data, or at least, prevent any new data from coming into the
system, but this doesn't appear to be the case. Given my application,
I must tie the data for each sample to a specific frequency, so
guaranteeing that the first (through last) reads for any tuning
operation all apply to that tuning operation.
I looked at the example, and if my understanding of the code is right,
you never stop getting data from the USRP (or shut it off). You change
the frequency, and suck samples for a fixed period of time (throwing
them out [basically, the amount of time it would take to flush the old
data through the USB buffering system]) before capturing again (and
using them). Does my usrp_spectrum_sense.py understanding match
reality? I am not really a Python person. It seems to me that an
efficient start/stop implementation would be more effective than having
to read data that you never need.
In the GNU Radio code, which you don't appear to be using, we have
gnuradio-examples/python/usrp/usrp_spectrum_sense.py, which does
Is something broke, or (as is more likely the case), am I missing
something? Is anyone else trying to use libusrp in a similar manner?
something similar to what you are doing.
In our case, we want to walk a large frequency range, capturing data for
approximately 100 - 200 milliseconds per frequency, and would prefer to
have less than 50 milliseconds of overhead between captures. We also
need to do this on a potentially loaded CPU, so we need large enough
buffering to reduce the likelyhood of us overrunning (assuming other
tasks, such as games or other CPU hogs want much of the available CPU
resources). The amount of CPU resource we need should be out of the
available CPU after other things run, rather than as the highest
priority task. From calculations based upon your proposed buffering, I
get (4096*16)/32 MB/s) = ~2 milliseconds of buffering, we feel we need a
minimum of about 50 milliseconds of buffering, hence the large numbers
FYI, I tried building the trunk code on my ubuntu box, and when I did
the "./configure" command, it reported problems finding guile. If I
look at the packages on my machine, synaptic reports that guile 1.6.7-2
is installed on the machine, which should match the requirements from
the readme file.