PySerial写STM32串口:Mac/Linux不遵守波特率,Windows正常
STM32 USB串口设备在MacOS/Linux下PySerial写入超速导致超时问题
设备厂商将核心板从Teensy更换为STM32后,原有的PySerial文件上传代码仅在Windows下正常运行,MacOS和Linux环境中数据写入速度远超设定的波特率(直接以文件读取速度写入),导致设备无法接收完整数据并触发写入超时。
目前通过在非Windows系统中添加time.sleep(0.000087)字节间延迟作为临时方案,但效果不稳定:多数情况可行,但偶尔仍会触发设备读取超时,疑似存在数据损坏问题。
简化后的Python 3代码
import serial import os import time # 假设getHumanReadableSize是已实现的工具函数 def getHumanReadableSize(size): for unit in ['B', 'KB', 'MB']: if size < 1024: return f"{size:.2f}{unit}" size /= 1024 return f"{size:.2f}GB" _SERIAL_SETTINGS = {'baudrate': 115200, 'bytesize': 8, 'parity': 'N', 'stopbits': 1, 'xonxoff': False, 'dsrdtr': False, 'rtscts': False, 'timeout': 3, 'write_timeout': None, 'inter_byte_timeout': None} # port已根据系统提前识别 ser = serial.Serial(port) ser.applySettings(_SERIAL_SETTINGS) # file和file_size已从外部传入 bytes_sent = 0 fname = os.path.basename(file) report_every_n_bytes = 512 with open(file, mode='rb') as binary_file: # 发送文件接收命令:格式为 "WR=filename,size\n" cmd = b'WR=' + fname.encode('utf-8') + b', ' + str(file_size).encode('utf-8') + b'\n' ser.write(cmd) response = ser.readline() # 设备应返回 "OK Write filename, size\n" byte = binary_file.read(1) print(f'{fname} - Data sent: {getHumanReadableSize(bytes_sent)} - Data remaining: {getHumanReadableSize(file_size - bytes_sent)} - Speed: 0.00B/s', end='', flush=True) start_time = time.time() while byte: ser.write(byte) ser.flush() # 临时 workaround:非Windows系统手动添加延迟 # if platform.system() != 'Windows': time.sleep(0.000087) bytes_sent += 1 byte = binary_file.read(1) if bytes_sent % report_every_n_bytes == 0: elapsed = time.time() - start_time speed = bytes_sent / elapsed if elapsed > 0 else 0 print(f'\r{fname} - Data sent: {getHumanReadableSize(bytes_sent)} - Data remaining: {getHumanReadableSize(file_size - bytes_sent)} - Speed: {getHumanReadableSize(speed)}/s ', end='', flush=True) # 最终进度报告 elapsed = time.time() - start_time speed = bytes_sent / elapsed if elapsed > 0 else 0 print(f'\r{fname} - Data sent: {getHumanReadableSize(bytes_sent)} - Data remaining: {getHumanReadableSize(file_size - bytes_sent)} - Speed: {getHumanReadableSize(speed)}/s ') # 检查设备响应,预期为“OK, Write complete.”,实际收到“ERROR Write Timed Out” response = ser.readline() print(response)
已尝试的无效方案
- 降低波特率
- 分块写入(替代单字节写入)
- 单独或组合启用各类流控设置(xonxoff、dsrdtr、rtscts)
- 修改奇偶校验和停止位参数
补充细节
- 设备通过USB连接至PCB端口
- 写入操作完成后执行
ser.readline()时,收到设备返回的“ERROR Write Timed Out”错误 - 根据设备文档,该错误触发条件:收到
WR命令后,未接收到指定大小的数据,且10秒内无新数据传入 - 问题可稳定复现,仅操作系统不同时出现差异,多台同条件机器均会发生
疑问
- 代码或配置中遗漏了什么关键点?
- 若问题与底层设备驱动有关,具体机制是什么?该如何解决?
内容的提问来源于stack exchange,提问作者Jason Ramboz
相关产品推荐
相关产品推荐

