3

I have an SDR dongle connected on a Raspberry Pi 3 running Kali Linux Arm64. The SDR itself is this particular model

Trouble is, whenever I connect to the rtl_tcp server remotely, it exits:

rtl_tcp -a 192.168.200.132
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
[R82XX] PLL not locked!
Tuned to 100000000 Hz.
listening...
Use the device argument 'rtl_tcp=192.168.200.132:1234' in OsmoSDR (gr-osmosdr) source
to receive samples in GRC and control rtl_tcp parameters (frequency, gain, ...).
client accepted! 192.168.200.102 64098
Allocating 15 zero-copy buffers
Bus error

Testing with rtl_test -t is fine:

rtl_test -t
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
[R82XX] PLL not locked!
Sampling at 2048000 S/s.
No E4000 tuner found, aborting.

But testing with a sample rate results in the same undesired behavior.

rtl_test -s 2048000
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
[R82XX] PLL not locked!
Sampling at 2048000 S/s.

Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.

Reading samples in async mode...
Allocating 15 zero-copy buffers
Bus error

How do I keep this from happening, and get RTL-SDR to run properly?

Things I've tried

No change:

  1. I've used RTL-SDR in Kali's repos, as well as compiled from source using the git.osmocom.org/rtl-sdr.git repo — no change
  2. Increased the swap file size to 2 GB — no change

Some change:

Forcing synchronous mode in rtl_test did not produce the error.

rtl_test -s 2048000 -S
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
[R82XX] PLL not locked!
Sampling at 2048000 S/s.

Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.

Reading samples in sync mode...
(Samples are being lost but not reported.)

Introducting the b flag in rtl_tcp allows me to set the number of buffers, which doesn't seem to do much:

rtl_tcp -a 192.168.200.132 -b 1
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
[R82XX] PLL not locked!
Tuned to 100000000 Hz.
listening...
Use the device argument 'rtl_tcp=192.168.200.132:1234' in OsmoSDR (gr-osmosdr) source
to receive samples in GRC and control rtl_tcp parameters (frequency, gain, ...).
client accepted!
Allocating 1 zero-copy buffers
Bus error
Amin Shah Gilani
  • 8,675
  • 5
  • 37
  • 79

2 Answers2

1

I don't know if I can answer the question completely, but I have experienced similar errors when debugging a USB3 device. The problem seemed to occur, not because USB3 was unsupported (it was a USB3 adapter), but because the card driver couldn't allocate enough backplane bandwidth to dynamically allocate the particular USB pipe.

I'm not super familiar with RPi's - are you attempting to route the capture out over a USB-Ethernet/Wifi dongle? USB3 aside, I wonder if this is similar dynamic bandwidth allocation issue.

-- Something to do with the zero-copy buffer code was reported a while back: https://www.mail-archive.com/osmocom-sdr@lists.osmocom.org/msg01204.html from the description it manifests in a different way and also a workaround was applied.

jsr___
  • 141
  • 1
  • 10
  • 1
    The device in question is an RTL-SDR on USB2, and I'm trying to route the capture out to the ethernet port. However, it appears that the error is thrown in the capture phase, because `rtl_test` simply captures and dumps the data. – Amin Shah Gilani Feb 13 '19 at 00:07
  • Also, changing the number of buffers doesn't help the problem. I've updated the question with an example. Maybe I should try commenting out the code as in the email you linked. – Amin Shah Gilani Feb 13 '19 at 00:20
  • 1
    both USB2 and USB3 dynamically allocate data pipes with some up-front bandwidth as part of the USB protocol stack - this can fail in the underlying USB hardware driver depending on a range of things and from memory one of which in the case I saw was insufficient PCI (backplane) bandwidth - in other words dependent all the way down to the current hardware state. I think libusb can be compiled with a debug flag enabled to get more information. I ended up in the kernel source, xhci, to figure out what happened in the end. – jsr___ Feb 13 '19 at 00:56
  • 1
    Removing the zerocopy code worked for me! I believe this is a bug and needs to be addressed. – Amin Shah Gilani Feb 13 '19 at 01:19
1

I'm still not sure what the problem is, but based on the indication @jsr gave me, I went ahead and removed the zerocopy code and recompiled rtl-sdr and it worked.

Here's a diff. This is likely a bug in the program and needs to be addressed.

diff --git a/src/librtlsdr.c b/src/librtlsdr.c
index 89ec903..61bcebc 100644
--- a/src/librtlsdr.c
+++ b/src/librtlsdr.c
@@ -1748,50 +1748,6 @@ static int _rtlsdr_alloc_async_buffers(rtlsdr_dev_t *dev)
        dev->xfer_buf = malloc(dev->xfer_buf_num * sizeof(unsigned char *));
        memset(dev->xfer_buf, 0, dev->xfer_buf_num * sizeof(unsigned char *));

-#if defined (__linux__) && LIBUSB_API_VERSION >= 0x01000105
-       fprintf(stderr, "Allocating %d zero-copy buffers\n", dev->xfer_buf_num);
-
-       dev->use_zerocopy = 1;
-       for (i = 0; i < dev->xfer_buf_num; ++i) {
-               dev->xfer_buf[i] = libusb_dev_mem_alloc(dev->devh, dev->xfer_buf_len);
-
-               if (dev->xfer_buf[i]) {
-                       /* Check if Kernel usbfs mmap() bug is present: if the
-                        * mapping is correct, the buffers point to memory that
-                        * was memset to 0 by the Kernel, otherwise, they point
-                        * to random memory. We check if the buffers are zeroed
-                        * and otherwise fall back to buffers in userspace.
-                        */
-                       if (dev->xfer_buf[i][0] || memcmp(dev->xfer_buf[i],
-                                                         dev->xfer_buf[i] + 1,
-                                                         dev->xfer_buf_len - 1)) {
-                               fprintf(stderr, "Detected Kernel usbfs mmap() "
-                                               "bug, falling back to buffers "
-                                               "in userspace\n");
-                               dev->use_zerocopy = 0;
-                               break;
-                       }
-               } else {
-                       fprintf(stderr, "Failed to allocate zero-copy "
-                                       "buffer for transfer %d\nFalling "
-                                       "back to buffers in userspace\n", i);
-                       dev->use_zerocopy = 0;
-                       break;
-               }
-       }
-
-       /* zero-copy buffer allocation failed (partially or completely)
-        * we need to free the buffers again if already allocated */
-       if (!dev->use_zerocopy) {
-               for (i = 0; i < dev->xfer_buf_num; ++i) {
-                       if (dev->xfer_buf[i])
-                               libusb_dev_mem_free(dev->devh,
-                                                   dev->xfer_buf[i],
-                                                   dev->xfer_buf_len);
-               }
-       }
-#endif
-
        /* no zero-copy available, allocate buffers in userspace */
        if (!dev->use_zerocopy) {
                for (i = 0; i < dev->xfer_buf_num; ++i) {

After recompiling, the program worked as expected:

~/sandbox/rtl-sdr# rtl_tcp -a 192.168.200.132 -f 89000 -b 100
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
[R82XX] PLL not locked!
[R82XX] PLL not locked!
Tuned to 89000 Hz.
listening...
Use the device argument 'rtl_tcp=192.168.200.132:1234' in OsmoSDR (gr-osmosdr) source
to receive samples in GRC and control rtl_tcp parameters (frequency, gain, ...).
client accepted!
set gain mode 1
set agc mode 0
set direct sampling 0
Disabled direct sampling mode
[R82XX] PLL not locked!
set offset tuning 0
set bias tee 0
set sample rate 1800000
[R82XX] PLL not locked!
ll+, now 1
set freq 24000000
set gain 495
ll+, now 2
set gain 495
set gain 495
set freq 106661000
ll+, now 3
ll+, now 4
ll+, now 5
ll+, now 6
Amin Shah Gilani
  • 8,675
  • 5
  • 37
  • 79