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

0 件のコメント:

コメントを投稿