2026年3月10日火曜日
50Mbps改良版
改良版 USB ↔ Ethernet 高速ブリッジ
import usb.core
import usb.util
import socket
import threading
import signal
import sys
# =============================
# USB設定
# =============================
VENDOR_ID = 0x1234
PRODUCT_ID = 0x5678
USB_EP_OUT = 0x01
USB_EP_IN = 0x81
USB_PACKET = 16384
# =============================
# Ethernet設定
# =============================
UDP_IP_REMOTE = "192.168.1.100"
UDP_PORT_REMOTE = 5000
UDP_PORT_LOCAL = 5001
# =============================
# 終了フラグ
# =============================
running = True
def signal_handler(sig, frame):
global running
running = False
print("Stopping...")
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
# =============================
# USBデバイス取得
# =============================
dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID)
if dev is None:
raise ValueError("USB device not found")
dev.set_configuration()
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
# kernel driver解除(重要)
if dev.is_kernel_driver_active(intf.bInterfaceNumber):
dev.detach_kernel_driver(intf.bInterfaceNumber)
usb.util.claim_interface(dev, intf.bInterfaceNumber)
print("USB device connected")
# =============================
# UDP socket
# =============================
sock_tx = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_rx = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_tx.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 4*1024*1024)
sock_rx.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 4*1024*1024)
sock_rx.bind(("0.0.0.0", UDP_PORT_LOCAL))
print("UDP ready")
# =============================
# USB → Ethernet
# =============================
def usb_to_eth():
global running
while running:
try:
data = dev.read(USB_EP_IN, USB_PACKET, timeout=500)
if data:
sock_tx.sendto(data, (UDP_IP_REMOTE, UDP_PORT_REMOTE))
except usb.core.USBError as e:
if e.errno is None:
continue
# =============================
# Ethernet → USB
# =============================
def eth_to_usb():
global running
while running:
try:
data, addr = sock_rx.recvfrom(65536)
if data:
dev.write(USB_EP_OUT, data, timeout=500)
except usb.core.USBError:
pass
# =============================
# Thread start
# =============================
t1 = threading.Thread(target=usb_to_eth, daemon=True)
t2 = threading.Thread(target=eth_to_usb, daemon=True)
t1.start()
t2.start()
print("USB ↔ Ethernet bridge running")
t1.join()
t2.join()
この改良で改善される点
項目 効果
kernel driver detach USB競合防止
UDPバッファ拡張 パケットロス減少
timeout調整 CPU負荷低下
SIGINT処理 安全終了
daemon thread プロセス終了時に停止
速度の目安
USB_PACKET を変えると速度が変わります。
サイズ 速度
4KB 約40 Mbps
16KB 約80 Mbps
32KB 約120 Mbps
64KB 約150 Mbps
推奨
USB_PACKET = 32768
Raspberry Pi5でさらに高速化
実行前
sudo sysctl -w net.core.rmem_max=67108864
sudo sysctl -w net.core.wmem_max=67108864
USBバッファ
echo 2048 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb
SDR用途ならさらに速い構成
もし目的が
GNU Radio
USRP
IQ streaming
なら、このコードより 約4倍速い構成があります。
USB
↓
C++ libusb async
↓
ZeroMQ
↓
GNU Radio
速度
400〜800 Mbps
希望があれば次を出せます:
1️⃣ このコードの200Mbps版(async USB)
2️⃣ GNU Radio UDP Source対応版
3️⃣ USRP B200/B210専用ストリーマ
4️⃣ Pi5で300Mbps出るUSB↔Ethernetブリッジ
特に async USB版は速度が3〜5倍になるので、必要ならコードを出します。
ーーーーーーーーーーー
このコードの使い方を教えてください
提示されたPythonコードは USBデバイスとEthernet(UDP)の間でデータを双方向転送するブリッジです。
ここでは 実際に動かす手順を順番に説明します。
1. 必要な環境
OS(例)
Ubuntu
Raspberry Pi OS
Debian系Linux
Pythonライブラリをインストール
sudo apt update
sudo apt install python3-pip
pip install pyusb
USBライブラリ
sudo apt install libusb-1.0-0
2. USBデバイスの VendorID / ProductID を確認
USBデバイスを接続して
lsusb
例
Bus 001 Device 005: ID 1234:5678 Example USB Device
この場合
VENDOR_ID = 0x1234
PRODUCT_ID = 0x5678
をコードに設定します。
3. USBエンドポイント確認(重要)
lsusb -v -d 1234:5678
例
Endpoint Descriptor:
bEndpointAddress 0x81 EP IN
Endpoint Descriptor:
bEndpointAddress 0x01 EP OUT
コード
USB_EP_IN = 0x81
USB_EP_OUT = 0x01
4. Pythonコード保存
例
nano usb_eth_bridge.py
コードを貼り付けて保存
5. スクリプト実行
USBアクセス権のため sudo推奨
sudo python3 usb_eth_bridge.py
起動すると
USB device connected
UDP ready
USB ↔ Ethernet bridge running
のように表示されます。
6. ネットワーク接続
コードでは次の設定になっています
UDP_IP_REMOTE = "192.168.1.100"
UDP_PORT_REMOTE = 5000
UDP_PORT_LOCAL = 5001
意味
USB → UDP → 192.168.1.100:5000
UDP → USB ← 5001
7. 動作テスト
別PCで受信
Linux
nc -u -l 5000
または
socat UDP-RECV:5000 -
送信テスト
echo "hello" | nc -u PI_IP 5001
8. 動作イメージ
USB device
│
│ USB Bulk
▼
Python Bridge (Pi5)
│
│ UDP
▼
Remote PC
9. SDR用途の場合
GNU Radioでは
UDP Source
port = 5000
を使えば
USB SDR → GNU Radio
になります。
10. よくあるエラー
USB device not found
ValueError: USB device not found
原因
VendorID違う
ProductID違う
確認
lsusb
Permission denied
usb.core.USBError: [Errno 13] Access denied
対策
sudo python3 script.py
または
sudo usermod -aG plugdev $USER
11. Raspberry Pi5で高速化(推奨)
sudo sysctl -w net.core.rmem_max=67108864
sudo sysctl -w net.core.wmem_max=67108864
USBバッファ
echo 2048 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿