树莓派Python:如何通过USB串口无丢失传输大数据?
解决USB OTG Serial Gadget大文件传输丢包问题
这种串口传输丢包的情况我之前在树莓派USB OTG场景下碰到过好几次,尤其是传输大体积数据时,核心问题基本都是缓冲区溢出或者缺少流控制机制导致的。结合你的代码,给你几个针对性的解决方案,亲测有效:
1. 启用硬件流控制(RTS/CTS)
这是解决丢包最关键的一步。默认情况下,串口传输没有流控制,当接收端的缓冲区被填满时,后续的数据会直接丢失。而USB Serial Gadget支持RTS/CTS硬件流控制——当接收端缓冲区快满时,会通过RTS信号通知发送端暂停发送,等缓冲区有空间了再继续。
修改树莓派端代码:
import serial # 初始化串口时添加rtscts=True参数 ser = serial.Serial( port='/dev/ttyGS0', baudrate=115200, rtscts=True, # 启用硬件流控制 timeout=1 ) # 更高效地创建1MB数据包 packet = bytearray([0x2f]) * 1000000 ser.write(packet) ser.close()
修改电脑端代码:
import serial ser = serial.Serial( port='COM30', baudrate=115200, rtscts=True, # 必须和发送端同时启用 timeout=5 # 设置超时,避免无限等待 ) expected = 1000000 received = 0 # 循环读取直到收完预期字节数 while received < expected: remaining = expected - received data = ser.read(remaining) received += len(data) print(f"已接收:{received}/{expected} 字节") print(f"传输完成!总接收字节数:{received}") ser.close()
2. 增大串口缓冲区大小
默认的串口接收/发送缓冲区通常只有几KB,传输1MB数据时很容易被填满溢出。我们可以通过代码手动增大缓冲区,减少溢出概率:
树莓派端添加缓冲区设置:
# 在串口初始化后添加 ser.set_buffer_size(tx_size=1048576) # 设置发送缓冲区为1MB
电脑端添加缓冲区设置:
# 在串口初始化后添加 ser.set_buffer_size(rx_size=1048576) # 设置接收缓冲区为1MB
3. 可选:分块发送+握手确认
如果对数据完整性要求极高,可以加入简单的握手机制——发送端分块发送数据,每发送一块就等待接收端的确认信号,确认收到后再发送下一块。这种方式能彻底避免丢包,但会稍微降低传输速度:
树莓派端分块发送代码:
import serial ser = serial.Serial( port='/dev/ttyGS0', baudrate=115200, rtscts=True, timeout=2 ) ser.set_buffer_size(tx_size=65536) total_bytes = 1000000 block_size = 65536 # 每次发64KB packet = bytearray([0x2f]) * total_bytes for i in range(0, total_bytes, block_size): end = min(i + block_size, total_bytes) ser.write(packet[i:end]) # 等待接收端的确认信号(比如一个字节'A') ack = ser.read(1) while ack != b'A': ack = ser.read(1) ser.close()
电脑端对应确认代码:
import serial ser = serial.Serial( port='COM30', baudrate=115200, rtscts=True, timeout=5 ) ser.set_buffer_size(rx_size=65536) expected = 1000000 received = 0 while received < expected: remaining = expected - received data = ser.read(min(remaining, 65536)) received += len(data) print(f"已接收:{received}/{expected} 字节") # 发送确认信号 ser.write(b'A') print(f"传输完成!总接收字节数:{received}") ser.close()
额外检查点
确保树莓派的USB OTG配置是正确的:
/boot/config.txt中已经添加了dtoverlay=dwc2/etc/modules中添加了g_serial- 重启树莓派后,
/dev/ttyGS0设备正常存在
内容的提问来源于stack exchange,提问作者Thost91
相关产品推荐
相关产品推荐

