Ubuntu主机双USRP B200并行采样遇LIBUSB_ERROR_NO_MEM错误求助
问题分析与解决方法
问题背景
在Ubuntu服务器上通过USB连接两台USRP B200设备,单独使用指定命令采样无丢包,但同时启动两个设置num_recv_frames=1900的采样进程时,两台设备均触发USBError -11: LIBUSB_ERROR_NO_MEM错误,其中第一个进程直接终止。单独使用默认num_recv_frames或仅一台设备设为1900时可正常运行,因高采样率需求必须调整该参数避免溢出,需解决内存不足问题。
采样命令
单台设备采样命令:
./rx_samples_to_file --gain 55 --freq 1234e6 --rate 50e6 --ant "RX2" --ref "external" --wirefmt sc12 --file /recordings/test_1.iq --duration 60 --stats --progress --args num_recv_frames=1900,serial=0000001
第二台设备采样命令:
./rx_samples_to_file --gain 55 --freq 1234e6 --rate 50e6 --ant "RX2" --ref "external" --wirefmt sc12 --file /recordings/test_2.iq --duration 60 --stats --progress --args num_recv_frames=1900,serial=0000002
错误信息
进程1错误:
[...] 50.0002 Msps 49.9999 Msps terminate called after throwing an instance of 'uhd::usb_error' what(): RuntimeError: USBError -11: usb rx6 submit failed: LIBUSB_ERROR_NO_MEM Aborted (core dumped)
进程2错误:
Creating the usrp device with: num_recv_frames=1900,serial=0000002... [INFO] [UHD] linux; GNU C++ version 12.4.0; Boost_108600; UHD_4.7.0.HEAD-release [INFO] [B200] Detected Device: B200 [INFO] [B200] Operating over USB 3. [INFO] [B200] Detected bad USB state; resetting. [INFO] [B200] Detected Device: B200 [INFO] [B200] Operating over USB 3. Error: RuntimeError: USBError -11: usb rx6 submit failed: LIBUSB_ERROR_NO_MEM
原因分析
LIBUSB_ERROR_NO_MEM表示libusb无法分配足够的内存用于USB异步传输缓冲区。num_recv_frames参数控制USRP设备的USB接收队列帧数,每帧对应一块内存缓冲区。当两台设备同时设置1900帧时,总内存需求超出了系统USB子系统的内存限制或进程可用内存配额,导致缓冲区分配失败,进而触发设备重置或进程崩溃。
解决方法
1. 降低单台设备的num_recv_frames数值
通过减少单台设备的帧数,控制两台设备的总缓冲区内存在系统允许范围内。可以逐步测试合适的数值(比如从1500开始向下调整),确保两台设备同时运行时不触发内存错误,同时仍能满足高采样率下的无丢包需求。
示例调整后的命令:
# 第一台设备 ./rx_samples_to_file --gain 55 --freq 1234e6 --rate 50e6 --ant "RX2" --ref "external" --wirefmt sc12 --file /recordings/test_1.iq --duration 60 --stats --progress --args num_recv_frames=1200,serial=0000001 # 第二台设备 ./rx_samples_to_file --gain 55 --freq 1234e6 --rate 50e6 --ant "RX2" --ref "external" --wirefmt sc12 --file /recordings/test_2.iq --duration 60 --stats --progress --args num_recv_frames=1200,serial=0000002
2. 调整Linux系统USB缓冲区参数
修改usbfs的缓冲区大小限制,增加系统为USB设备分配的内存配额:
- 临时生效:执行以下命令重新挂载usbfs
其中sudo umount /proc/bus/usb sudo mount -t usbfs usbfs /proc/bus/usb -o devgid=$(id -g),devmode=664,buffer_size=33554432buffer_size设为32MB(可根据需求调整为更大值,比如64MB)。 - 永久生效:编辑
/etc/fstab文件,添加或修改usbfs挂载条目:
保存后执行usbfs /proc/bus/usb usbfs devgid=$(id -g),devmode=664,buffer_size=33554432 0 0sudo mount -a生效。
3. 优化硬件连接方式
- 将两台USRP设备分别连接到主板上不同的USB 3.0控制器,避免共享同一控制器的带宽和内存资源。
- 避免使用USB集线器,尽量直接连接到主板原生USB端口,减少信号衰减和资源竞争。
4. 使用单进程控制多设备
放弃两个独立进程的方式,编写自定义程序(Python或C++)通过UHD API同时初始化并控制两台USRP设备。单进程可以更高效地管理内存缓冲区,避免多进程重复分配资源导致的内存耗尽问题,同时还能更好地实现设备同步。
内容的提问来源于stack exchange,提问作者Nils
相关产品推荐
相关产品推荐

