当 运行 rtl_tcp 或 rtl_test 时,rtl-sdr 因 "Bus error" 而崩溃

rtl-sdr crashes with "Bus error" when running rtl_tcp or rtl_test

我在 Raspberry Pi 3 运行ning Kali Linux Arm64 上连接了一个 SDR 加密狗。特别提款权本身就是这个特殊的 model

问题是,每当我远程连接到 rtl_tcp 服务器时,它都会退出:

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

rtl_test -t 测试没问题:

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.

但是使用采样率进行测试会导致同样的不良行为。

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

如何防止这种情况发生,并正确地将 RTL-SDR 变为 运行?

我尝试过的事情

无变化:

  1. 我在 Kali 的存储库中使用了 RTL-SDR,并使用 git.osmocom.org/rtl-sdr.git 存储库从源代码编译——没有变化
  2. 将交换文件大小增加到 2 GB — 没有变化

一些变化:

rtl_test 中强制同步模式没有产生错误。

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.)

rtl_tcp中引入b标志允许我设置缓冲区的数量,这似乎作用不大:

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

不知道能不能完整回答问题,我在调试USB3设备的时候也遇到过类似的错误。问题似乎出现了,不是因为不支持 USB3(它是 USB3 适配器),而是因为卡驱动程序无法分配足够的背板带宽来动态分配特定的 USB 管道。

我对 RPi 不是很熟悉 - 您是否试图通过 USB-Ethernet/Wifi 加密狗将捕获路由出去?除了USB3,我想知道这是否是类似的动态带宽分配问题。

-- 前一段时间报告了与零拷贝缓冲区代码有关的问题:https://www.mail-archive.com/osmocom-sdr@lists.osmocom.org/msg01204.html 从描述中它以不同的方式表现出来,并且还应用了解决方法。

我仍然不确定问题出在哪里,但根据@jsr 给我的指示,我继续删除了 zerocopy 代码并重新编译 rtl-sdr 并且它起作用了。

这是一个差异。这可能是程序中的错误,需要解决。

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) {

重新编译后,程序按预期运行:

~/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