Skip to content

Commit 9d55aae

Browse files
committed
feat: reconnect after serial lost connection
1 parent d01209c commit 9d55aae

1 file changed

Lines changed: 50 additions & 5 deletions

File tree

  • pytest-embedded-serial/pytest_embedded_serial

pytest-embedded-serial/pytest_embedded_serial/serial.py

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,20 +189,65 @@ def _event_loop(self):
189189
return
190190

191191
if _e == 'read':
192-
if time.time() - last_data_time > 5.0:
193-
logging.warning('No data received from serial port for over 5 seconds.')
194-
last_data_time = time.time()
195-
196192
if self._block_reading:
197193
continue
198194

199195
try:
200196
s = self._s.read_all()
197+
201198
if s:
202199
last_data_time = time.time()
203200

201+
if time.time() - last_data_time > 15.0:
202+
logging.warning('No data received from serial port for over 15 seconds.')
203+
last_data_time = time.time()
204+
except OSError as e:
205+
logging.error(f'OSError detected: {e}. Serial connection may be lost.')
206+
if self._s.closed:
207+
logging.error('Serial port is already closed. Exiting event loop.')
208+
return
209+
210+
port = self._s.port
211+
port_config = {
212+
'baudrate': self._s.baudrate,
213+
'bytesize': self._s.bytesize,
214+
'parity': self._s.parity,
215+
'stopbits': self._s.stopbits,
216+
'timeout': self._s.timeout,
217+
'xonxoff': self._s.xonxoff,
218+
'rtscts': self._s.rtscts,
219+
}
220+
for attempt in range(1, 4):
221+
delay = attempt * 1.5
222+
logging.warning(
223+
f'Attempting to reconnect to serial port {port} (try {attempt}/3) after {delay}s...'
224+
)
225+
time.sleep(delay)
226+
try:
227+
self._s.close()
228+
self._s = pyserial.serial_for_url(port, **port_config)
229+
logging.info(f'Successfully reconnected to serial port {port}.')
230+
break
231+
except Exception as e:
232+
logging.warning(f'Reconnection attempt {attempt} failed: {e}')
233+
else:
234+
logging.error(
235+
f'Failed to reconnect to serial port {port} after 3 attempts. Exiting event loop.'
236+
)
237+
return
238+
239+
continue
240+
241+
except Exception as e:
242+
logging.warning(
243+
'unknown error: %s.\nRecommend to close the serial process by `dut.serial.close()`', str(e)
244+
)
245+
return
246+
247+
try:
204248
self._q.put(s)
205-
except OSError:
249+
except OSError as e:
250+
logging.warning(f'OSError. Error msg: {e}')
206251
return
207252
except Exception as e:
208253
logging.warning(

0 commit comments

Comments
 (0)