在编写质检脚本的时候需要程序关闭重连串口设备,但关闭串口成功后重连显示 PermissionError 错误,是权限不足拒绝重连,此时串口号是不变的,也没有其他程序占用。
解决1:完善关闭函数,确保缓冲区清空。
def disconnect(self):
"""断开串口连接并确保所有数据已发送"""
if self.ser:
try:
# 1. 确保所有输出数据已发送
logger.info("等待输出缓冲区数据发送完成...")
self.ser.flush() # 等待所有输出数据发送完成
# 2. 清空缓冲区
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
# 3. 关闭连接
self.ser.close()
logger.info("串口连接已安全关闭")
except Exception as e:
logger.error(f"关闭串口时出错: {str(e)}")
finally:
# 确保释放资源
self.ser = None
依旧报错。
解决2:独占模式访问以及强制释放机制
#连接参数
self.ser = serial.Serial(
port=self.port,
baudrate=self.baudrate,
timeout=5,
exclusive=True # Windows独占模式
)
def release_port(self):
"""强制释放串口资源(Windows专用)"""
port_name = self.port
if os.name != 'nt':
return False # 仅支持Windows
try:
# 使用Windows API强制关闭串口句柄
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
OPEN_EXISTING = 0x3
FILE_FLAG_OVERLAPPED = 0x40000000
# 构造设备路径
device_path = f"\\\\.\\{port_name}"
# 尝试打开设备
handle = ctypes.windll.kernel32.CreateFileW(
device_path,
GENERIC_READ | GENERIC_WRITE,
0, # 独占模式
None,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
None
)
if handle != -1:
# 成功打开表示端口可用,直接关闭
ctypes.windll.kernel32.CloseHandle(handle)
return True
except Exception:
pass
return False
def disconnect(self):
"""断开串口连接并确保释放资源"""
if self.ser:
try:
self.ser.close()
logger.info("串口连接已关闭")
except Exception as e:
logger.error(f"关闭串口时出错: {str(e)}")
finally:
# 确保释放资源
self.ser = None
release_port(self.port)
依旧报错
解决3:在错误处理中直接关闭串口
except (serial.SerialException, OSError) as e:
logger.error(f"串口连接错误: {str(e)}")
if "FileNotFoundError" in str(e):
logger.error("请检查串口设备是否存在或权限是否足够")
elif "PermissionError" in str(e):
logger.error("串口被占用,请关闭其他使用此端口的程序")
if self.ser:
self.disconnect()
成功解决
总结:
当程序异常终止或未正常关闭串口时,操作系统会认为端口仍在使用中,Windows 会锁定串口句柄,导致后续访问出现"拒绝访问"错误。
对于串口编程,这种即时处理资源冲突的方式是最可靠的。