Python 2.7 pyserial write函数阻塞无输出且不超时问题求助
解决树莓派3B上Python2.7+pySerial write操作永久挂起的问题
我之前在树莓派3B上用pySerial 2.x版本做串口开发时,也碰到过一模一样的write挂起问题——卡在serialposix.py的select调用上,只能靠Ctrl+C中断。结合我的排查经验,给你几个针对性的解决方案:
1. 给串口添加写超时,避免无限阻塞
这是最直接的解决办法,pySerial 2.7版本支持write_timeout参数,初始化串口时设置这个值,就能避免select无限等待:
import serial # 初始化串口时明确配置写超时与流控 connection = serial.Serial( port='/dev/ttyUSB0', # 根据你的实际串口设备调整,比如树莓派自带串口是/dev/ttyAMA0 baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1, # 保持正常读超时配置 write_timeout=2, # 设置2秒写超时,超时会抛出serial.SerialTimeoutException rtscts=False, # 禁用硬件流控,关键修复点! dsrdtr=False )
设置后,如果write操作超过2秒还没完成,会直接抛出超时异常,不会永久挂起,你可以在代码里捕获这个异常做重试或错误处理。
2. 修复字节编码的潜在问题
Python2.7中b'{}'.format(...)的写法可能会生成不符合预期的字节流——如果deviceData[deviceType][STATUSREQ]是普通str,用bytes格式字符串格式化可能导致编码异常,进而引发串口发送阻塞。建议直接将字符串编码为bytes:
# 替换原来的write语句,确保发送正确的字节流 status_req = deviceData[deviceType][STATUSREQ] # 根据你的设备通信协议调整编码,比如ascii/utf-8 connection.write(status_req.encode('ascii'))
3. 确保串口设备权限正确
树莓派上的串口设备(比如/dev/ttyAMA0或/dev/ttyUSB0)需要当前用户拥有读写权限,否则可能出现隐性的阻塞问题。执行以下命令将pi用户加入dialout组:
sudo usermod -a -G dialout pi
执行后注销重新登录,或者重启树莓派生效。
4. 匹配外设的流控配置
如果你的串口外设不支持硬件流控(RTS/CTS、DSR/DTR),树莓派串口默认的流控配置会导致select一直等待硬件就绪信号。前面初始化串口时设置的rtscts=False和dsrdtr=False就是为了禁用这些不需要的流控,一定要确认外设的流控设置和你的代码完全一致。
内容的提问来源于stack exchange,提问作者Ctrl S
相关产品推荐
相关产品推荐

