4. 串口热插拔检测
任务说明
本案例实现一个串口热插拔检测工具,能够实时监测系统中串口设备的插入与拔出事件,并动态更新可用串口列表。程序启动时扫描当前所有串口设备并显示,随后持续监听系统串口变化,每当有新串口接入或已有串口移除时,自动刷新列表并打印事件信息。
实现方案
使用 pyserial 提供的 serial.tools.list_ports 模块获取当前串口列表,通过轮询方式周期性对比前后两次扫描结果,从而识别新增与移除的设备。轮询间隔设为1秒,兼顾实时性与系统资源占用。程序运行期间持续监听,直到用户按下 Ctrl+C 退出。
代码实现
import serial.tools.list_ports
import time
def get_serial_devices():
"""返回当前系统中所有可用串口设备列表"""
ports = serial.tools.list_ports.comports()
return {port.device: port.description for port in ports}
def main():
print("串口热插拔检测已启动,按 Ctrl+C 退出...")
print("-" * 50)
# 初始扫描
previous = get_serial_devices()
if previous:
print(f"当前检测到 {len(previous)} 个串口设备:")
for dev, desc in previous.items():
print(f" {dev} - {desc}")
else:
print("当前未检测到串口设备")
try:
while True:
time.sleep(1) # 轮询间隔 1 秒
current = get_serial_devices()
# 检测新增设备
added = set(current.keys()) - set(previous.keys())
for dev in added:
print(f"[插入] 检测到新串口: {dev} - {current[dev]}")
# 检测移除设备
removed = set(previous.keys()) - set(current.keys())
for dev in removed:
print(f"[拔出] 串口已移除: {dev} - {previous[dev]}")
# 若有变化则更新列表并打印当前状态
if added or removed:
previous = current
if current:
print(f"当前可用串口 ({len(current)} 个):")
for dev, desc in current.items():
print(f" {dev} - {desc}")
else:
print("当前无可用串口")
print("-" * 50)
except KeyboardInterrupt:
print("\n检测已停止")
if __name__ == "__main__":
main()
运行与验证
依赖安装:本程序仅需 pyserial 库,执行以下命令安装:
pip install pyserial
运行方式:在终端中执行:
python hotplug_detect.py
验证步骤与判定标准:
- 程序启动后,应打印当前系统中已连接的串口设备列表(若无设备则提示“当前未检测到串口设备”)。
- 插入一个USB转串口适配器,1秒内程序应打印
[插入]信息,并刷新显示当前可用串口列表。 - 拔出该适配器,1秒内程序应打印
[拔出]信息,并刷新列表。 - 按
Ctrl+C程序正常退出,无异常报错。
满足以上行为即判定热插拔检测功能实现正确。
检测逻辑说明
┌─────────────────────────────────────────────────────────────┐
│ 串口热插拔检测流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 初始扫描 │────▶│ 轮询等待1秒 │────▶│ 获取当前列表 │ │
│ └──────────┘ └──────────────┘ └──────┬───────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 与上一次列表对比 │ │
│ └───────┬─────────────────────┬───────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 有新增设备? │ │ 有移除设备? │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 打印事件信息,更新列表并显示当前串口状态 │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
该轮询方案不依赖操作系统底层事件通知机制,通过周期性对比串口列表快照实现插拔检测,具备良好的跨平台兼容性(Windows/Linux/macOS均可运行),且代码简洁、易于理解与扩展。