mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 21:24:32 +02:00
IDF monitor update
This commit is contained in:
@@ -140,6 +140,8 @@ class Monitor(object):
|
||||
self._decode_panic = decode_panic
|
||||
self._reading_panic = PANIC_IDLE
|
||||
self._panic_buffer = b''
|
||||
self.gdb_exit = False
|
||||
self.start_cmd_sent = False
|
||||
|
||||
def invoke_processing_last_line(self):
|
||||
# type: () -> None
|
||||
@@ -149,43 +151,70 @@ class Monitor(object):
|
||||
# type: () -> None
|
||||
self.console_reader.start()
|
||||
self.serial_reader.start()
|
||||
self.gdb_exit = False
|
||||
self.start_cmd_sent = False
|
||||
try:
|
||||
while self.console_reader.alive and self.serial_reader.alive:
|
||||
try:
|
||||
item = self.cmd_queue.get_nowait()
|
||||
except queue.Empty:
|
||||
try:
|
||||
item = self.event_queue.get(True, 0.03)
|
||||
except queue.Empty:
|
||||
continue
|
||||
if self.gdb_exit is True:
|
||||
self.gdb_exit = False
|
||||
|
||||
time.sleep(0.3)
|
||||
try:
|
||||
# Continue the program after exit from the GDB
|
||||
self.serial.write(codecs.encode('+$c#63'))
|
||||
self.start_cmd_sent = True
|
||||
except serial.SerialException:
|
||||
pass # this shouldn't happen, but sometimes port has closed in serial thread
|
||||
except UnicodeEncodeError:
|
||||
pass # this can happen if a non-ascii character was passed, ignoring
|
||||
|
||||
event_tag, data = item
|
||||
if event_tag == TAG_CMD:
|
||||
self.handle_commands(data, self.target)
|
||||
elif event_tag == TAG_KEY:
|
||||
try:
|
||||
self.serial.write(codecs.encode(data))
|
||||
item = self.cmd_queue.get_nowait()
|
||||
except queue.Empty:
|
||||
try:
|
||||
item = self.event_queue.get(True, 0.03)
|
||||
except queue.Empty:
|
||||
continue
|
||||
|
||||
(event_tag, data) = item
|
||||
|
||||
if event_tag == TAG_CMD:
|
||||
self.handle_commands(data, self.target)
|
||||
elif event_tag == TAG_KEY:
|
||||
try:
|
||||
self.serial.write(codecs.encode(data))
|
||||
except serial.SerialException:
|
||||
pass # this shouldn't happen, but sometimes port has closed in serial thread
|
||||
except UnicodeEncodeError:
|
||||
pass # this can happen if a non-ascii character was passed, ignoring
|
||||
elif event_tag == TAG_SERIAL:
|
||||
self.handle_serial_input(data)
|
||||
if self._invoke_processing_last_line_timer is not None:
|
||||
self._invoke_processing_last_line_timer.cancel()
|
||||
self._invoke_processing_last_line_timer = threading.Timer(0.1, self.invoke_processing_last_line)
|
||||
self._invoke_processing_last_line_timer.start()
|
||||
# If no futher data is received in the next short period
|
||||
# of time then the _invoke_processing_last_line_timer
|
||||
# generates an event which will result in the finishing of
|
||||
# the last line. This is fix for handling lines sent
|
||||
# without EOL.
|
||||
elif event_tag == TAG_SERIAL_FLUSH:
|
||||
self.handle_serial_input(data, finalize_line=True)
|
||||
else:
|
||||
raise RuntimeError("Bad event data %r" % ((event_tag,data),))
|
||||
except KeyboardInterrupt:
|
||||
try:
|
||||
yellow_print("To exit from IDF monitor please use \"Ctrl+]\"")
|
||||
self.serial.write(codecs.encode('\x03'))
|
||||
except serial.SerialException:
|
||||
pass # this shouldn't happen, but sometimes port has closed in serial thread
|
||||
except UnicodeEncodeError:
|
||||
pass # this can happen if a non-ascii character was passed, ignoring
|
||||
elif event_tag == TAG_SERIAL:
|
||||
self.handle_serial_input(data)
|
||||
if self._invoke_processing_last_line_timer is not None:
|
||||
self._invoke_processing_last_line_timer.cancel()
|
||||
self._invoke_processing_last_line_timer = threading.Timer(0.1, self.invoke_processing_last_line)
|
||||
self._invoke_processing_last_line_timer.start()
|
||||
# If no further data is received in the next short period
|
||||
# of time then the _invoke_processing_last_line_timer
|
||||
# generates an event which will result in the finishing of
|
||||
# the last line. This is fix for handling lines sent
|
||||
# without EOL.
|
||||
elif event_tag == TAG_SERIAL_FLUSH:
|
||||
self.handle_serial_input(data, finalize_line=True)
|
||||
else:
|
||||
raise RuntimeError('Bad event data %r' % ((event_tag, data),))
|
||||
except SerialStopException:
|
||||
normal_print('Stopping condition has been received\n')
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
try:
|
||||
self.console_reader.stop()
|
||||
@@ -200,6 +229,13 @@ class Monitor(object):
|
||||
|
||||
def handle_serial_input(self, data, finalize_line=False):
|
||||
# type: (bytes, bool) -> None
|
||||
# Remove "+" after Continue command
|
||||
if self.start_cmd_sent is True:
|
||||
self.start_cmd_sent = False
|
||||
pos = data.find(b"+")
|
||||
if pos != -1:
|
||||
data = data[1:]
|
||||
|
||||
sp = data.split(b'\n')
|
||||
if self._last_line_part != b'':
|
||||
# add unprocessed part from previous "data" to the first line
|
||||
@@ -260,6 +296,7 @@ class Monitor(object):
|
||||
def __exit__(self, *args, **kwargs): # type: ignore
|
||||
""" Use 'with self' to temporarily disable monitoring behaviour """
|
||||
self.console_reader.start()
|
||||
self.serial_reader.gdb_exit = self.gdb_exit # write gdb_exit flag
|
||||
self.serial_reader.start()
|
||||
|
||||
def prompt_next_action(self, reason): # type: (str) -> None
|
||||
@@ -480,10 +517,25 @@ class Monitor(object):
|
||||
cmd = ['%sgdb' % self.toolchain_prefix,
|
||||
'-ex', 'set serial baud %d' % self.serial.baudrate,
|
||||
'-ex', 'target remote %s' % self.serial.port,
|
||||
'-ex', 'interrupt', # monitor has already parsed the first 'reason' command, need a second
|
||||
self.elf_file]
|
||||
process = subprocess.Popen(cmd, cwd='.')
|
||||
process.wait()
|
||||
|
||||
# Here we handling GDB as a process
|
||||
if True:
|
||||
# Open GDB process
|
||||
try:
|
||||
process = subprocess.Popen(cmd, cwd=".")
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
# We ignore Ctrl+C interrupt form external process abd wait responce util GDB will be finished.
|
||||
while True:
|
||||
try:
|
||||
process.wait()
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
pass # We ignore the Ctrl+C
|
||||
self.gdb_exit = True
|
||||
|
||||
except OSError as e:
|
||||
red_print('%s: %s' % (' '.join(cmd), e))
|
||||
except KeyboardInterrupt:
|
||||
@@ -499,7 +551,6 @@ class Monitor(object):
|
||||
subprocess.call(['stty', 'sane'])
|
||||
except Exception:
|
||||
pass # don't care if there's no stty, we tried...
|
||||
self.prompt_next_action('gdb exited')
|
||||
|
||||
def output_enable(self, enable): # type: (bool) -> None
|
||||
self._output_enabled = enable
|
||||
@@ -733,6 +784,8 @@ def main(): # type: () -> None
|
||||
yellow_print('--- Print filter: {} ---'.format(args.print_filter))
|
||||
|
||||
monitor.main_loop()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
if ws:
|
||||
ws.close()
|
||||
|
@@ -38,6 +38,7 @@ class SerialReader(StoppableThread):
|
||||
self.baud = serial_instance.baudrate
|
||||
self.serial = serial_instance
|
||||
self.event_queue = event_queue
|
||||
self.gdb_exit = False
|
||||
if not hasattr(self.serial, 'cancel_read'):
|
||||
# enable timeout for checking alive flag,
|
||||
# if cancel_read not available
|
||||
@@ -47,10 +48,27 @@ class SerialReader(StoppableThread):
|
||||
# type: () -> None
|
||||
if not self.serial.is_open:
|
||||
self.serial.baudrate = self.baud
|
||||
self.serial.rts = True # Force an RTS reset on open
|
||||
# We can come to this thread at startup or from external application line GDB.
|
||||
# If we come from GDB we would like to continue to run without reset.
|
||||
if self.gdb_exit is False:
|
||||
# This sequence of DTR/RTS and open/close set the serial port to
|
||||
# condition when GDB not make reset of the target by switching DTR/RTS.
|
||||
self.serial.rts = True # IO0=LOW
|
||||
self.serial.dtr = self.serial.dtr # usbser.sys workaround
|
||||
self.serial.open()
|
||||
self.serial.close()
|
||||
self.serial.rts = False # IO0=HIGH
|
||||
self.serial.dtr = False
|
||||
else: # if we exit from GDB, we don't need to reset the target
|
||||
self.serial.rts = False
|
||||
self.serial.dtr = True
|
||||
|
||||
# Current state not reset the target!
|
||||
self.gdb_exit = False
|
||||
self.serial.open()
|
||||
self.serial.rts = False
|
||||
self.serial.dtr = self.serial.dtr # usbser.sys workaround
|
||||
time.sleep(0.005) # Add a delay to meet the requirements of minimal EN low time (2ms for ESP32-C3)
|
||||
self.serial.rts = False # Set rts/dtr to the working state
|
||||
self.serial.dtr = self.serial.dtr # usbser.sys workaround
|
||||
try:
|
||||
while self.alive:
|
||||
try:
|
||||
|
Reference in New Issue
Block a user