From 9266a7c52e078389e36fb90f1fba905683db5eae Mon Sep 17 00:00:00 2001 From: Nonoo Date: Sun, 17 Apr 2022 10:58:53 +0200 Subject: [PATCH 1/2] Add idf.py monitor argument --no-reset (-R) to prevent resetting the MCU target on monitor startup Add idf.py monitor argument --no-reset (-R) to prevent resetting the CPU on monitor startup idf.py monitor: fix type signature idf.py monitor: fix reset key shortcut when --no-reset (-R) argument is used idf.py monitor: change --no-reset (-R) argument descriptions in help idf.py monitor: simplify --no-reset (-R) argument checks idf.py monitor: add warning if --no-reset is used, but --port is not given idf.py monitor: ignore --no-reset if --port is not given --- tools/idf_monitor.py | 6 ++++-- tools/idf_monitor_base/argument_parser.py | 7 +++++++ tools/idf_monitor_base/serial_handler.py | 10 ++++++---- tools/idf_monitor_base/serial_reader.py | 7 ++++--- tools/idf_py_actions/serial_ext.py | 15 ++++++++++++++- 5 files changed, 35 insertions(+), 10 deletions(-) diff --git a/tools/idf_monitor.py b/tools/idf_monitor.py index 980743618f..40cb27fc06 100755 --- a/tools/idf_monitor.py +++ b/tools/idf_monitor.py @@ -75,6 +75,7 @@ class Monitor: print_filter, # type: str make='make', # type: str encrypted=False, # type: bool + reset=True, # type: bool toolchain_prefix=DEFAULT_TOOLCHAIN_PREFIX, # type: str eol='CRLF', # type: str decode_coredumps=COREDUMP_DECODE_INFO, # type: str @@ -109,7 +110,7 @@ class Monitor: if isinstance(self, SerialMonitor): socket_mode = serial_instance.port.startswith('socket://') self.serial = serial_instance - self.serial_reader = SerialReader(self.serial, self.event_queue) + self.serial_reader = SerialReader(self.serial, self.event_queue, reset) self.gdb_helper = GDBHelper(toolchain_prefix, websocket_client, self.elf_file, self.serial.port, self.serial.baudrate) if self.elf_exists else None @@ -124,7 +125,7 @@ class Monitor: cls = SerialHandler if self.elf_exists else SerialHandlerNoElf self.serial_handler = cls(b'', socket_mode, self.logger, decode_panic, PANIC_IDLE, b'', target, - False, False, self.serial, encrypted, self.elf_file) + False, False, self.serial, encrypted, reset, self.elf_file) self.console_parser = ConsoleParser(eol) self.console_reader = ConsoleReader(self.console, self.event_queue, self.cmd_queue, self.console_parser, @@ -343,6 +344,7 @@ def main() -> None: args.print_filter, args.make, args.encrypted, + not args.no_reset, args.toolchain_prefix, args.eol, args.decode_coredumps, diff --git a/tools/idf_monitor_base/argument_parser.py b/tools/idf_monitor_base/argument_parser.py index 2cff301d5f..937231596e 100644 --- a/tools/idf_monitor_base/argument_parser.py +++ b/tools/idf_monitor_base/argument_parser.py @@ -17,6 +17,13 @@ def get_parser(): # type: () -> argparse.ArgumentParser default=os.environ.get('ESPTOOL_PORT', '/dev/ttyUSB0') ) + parser.add_argument( + '--no-reset', '-R', + help='Do not reset the chip on monitor startup', + default=False, + action='store_true' + ) + parser.add_argument( '--disable-address-decoding', '-d', help="Don't print lines about decoded addresses from the application ELF file", diff --git a/tools/idf_monitor_base/serial_handler.py b/tools/idf_monitor_base/serial_handler.py index fc63d9237f..2fcdb41917 100644 --- a/tools/idf_monitor_base/serial_handler.py +++ b/tools/idf_monitor_base/serial_handler.py @@ -58,8 +58,8 @@ class SerialHandler: The class is responsible for buffering serial input and performing corresponding commands. """ def __init__(self, last_line_part, serial_check_exit, logger, decode_panic, reading_panic, panic_buffer, target, - force_line_print, start_cmd_sent, serial_instance, encrypted, elf_file): - # type: (bytes, bool, Logger, str, int, bytes,str, bool, bool, serial.Serial, bool, str) -> None + force_line_print, start_cmd_sent, serial_instance, encrypted, reset, elf_file): + # type: (bytes, bool, Logger, str, int, bytes,str, bool, bool, serial.Serial, bool, bool, str) -> None self._last_line_part = last_line_part self._serial_check_exit = serial_check_exit self.logger = logger @@ -71,6 +71,7 @@ class SerialHandler: self.start_cmd_sent = start_cmd_sent self.serial_instance = serial_instance self.encrypted = encrypted + self.reset = reset self.elf_file = elf_file def handle_serial_input(self, data, console_parser, coredump, gdb_helper, line_matcher, @@ -192,10 +193,11 @@ class SerialHandler: console_reader.stop() serial_reader.stop() elif cmd == CMD_RESET: - self.serial_instance.setRTS(low) + self.serial_instance.setDTR(high) # IO0=HIGH, default state + self.serial_instance.setRTS(low) # EN=LOW, chip in reset self.serial_instance.setDTR(self.serial_instance.dtr) # usbser.sys workaround time.sleep(reset_delay) - self.serial_instance.setRTS(high) + self.serial_instance.setRTS(high) # EN=HIGH, chip out of reset self.serial_instance.setDTR(self.serial_instance.dtr) # usbser.sys workaround self.logger.output_enabled = True elif cmd == CMD_MAKE: diff --git a/tools/idf_monitor_base/serial_reader.py b/tools/idf_monitor_base/serial_reader.py index e2a70841f9..31f8bc7a71 100644 --- a/tools/idf_monitor_base/serial_reader.py +++ b/tools/idf_monitor_base/serial_reader.py @@ -22,13 +22,14 @@ class SerialReader(Reader): event queue, until stopped. """ - def __init__(self, serial_instance, event_queue): - # type: (serial.Serial, queue.Queue) -> None + def __init__(self, serial_instance, event_queue, reset): + # type: (serial.Serial, queue.Queue, bool) -> None super(SerialReader, self).__init__() self.baud = serial_instance.baudrate self.serial = serial_instance self.event_queue = event_queue self.gdb_exit = False + self.reset = reset if not hasattr(self.serial, 'cancel_read'): # enable timeout for checking alive flag, # if cancel_read not available @@ -49,7 +50,7 @@ class SerialReader(Reader): self.serial.dtr = self.serial.dtr # usbser.sys workaround # Current state not reset the target! self.serial.open() - if not self.gdb_exit: + if not self.gdb_exit and self.reset: self.serial.dtr = high # Set dtr to reset state (affected by rts) self.serial.rts = low # Set rts/dtr to the reset state self.serial.dtr = self.serial.dtr # usbser.sys workaround diff --git a/tools/idf_py_actions/serial_ext.py b/tools/idf_py_actions/serial_ext.py index d2a2de37ec..a51ef69ea4 100644 --- a/tools/idf_py_actions/serial_ext.py +++ b/tools/idf_py_actions/serial_ext.py @@ -83,7 +83,7 @@ def action_extensions(base_actions, project_path): return result - def monitor(action, ctx, args, print_filter, monitor_baud, encrypted, timestamps, timestamp_format): + def monitor(action, ctx, args, print_filter, monitor_baud, encrypted, no_reset, timestamps, timestamp_format): """ Run idf_monitor.py to watch build output """ @@ -94,6 +94,10 @@ def action_extensions(base_actions, project_path): monitor_args = [PYTHON, idf_monitor] if project_desc['target'] != 'linux': + if no_reset and args.port is None: + sys.stderr.write('WARNING: --no-reset is ignored. Please specify the port with the --port argument in order to use this option.\n') + no_reset = False + esp_port = args.port or _get_default_serial_port(args) monitor_args += ['-p', esp_port] @@ -134,6 +138,9 @@ def action_extensions(base_actions, project_path): if encrypted: monitor_args += ['--encrypted'] + if no_reset: + monitor_args += ['--no-reset'] + if timestamps: monitor_args += ['--timestamps'] @@ -261,6 +268,12 @@ def action_extensions(base_actions, project_path): 'IDF Monitor will invoke encrypted-flash and encrypted-app-flash targets ' 'if this option is set. This option is set by default if IDF Monitor was invoked ' 'together with encrypted-flash or encrypted-app-flash target.'), + }, { + 'names': ['--no-reset', '-R'], + 'is_flag': True, + 'help': ('Disable reset on monitor startup. ' + 'IDF Monitor will not reset the MCU target by toggling DTR/RTS lines on startup ' + 'if this option is set.'), }, { 'names': ['--timestamps'], 'is_flag': True, From c02c0cc9b79a43f19fbe7963b289d6370f9f0403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ga=C5=88o?= Date: Tue, 10 May 2022 14:19:37 +0200 Subject: [PATCH 2/2] Tools: Add --no-reset option for IDF Monitor in order to avoid resetting the chip target upon connection Closes https://github.com/espressif/esp-idf/issues/8889 Closes IDFGH-7189, IDFGH-7301, IDFGH-5963 Closes https://github.com/espressif/esp-idf/issues/7651 Merges https://github.com/espressif/esp-idf/pull/8788 --- docs/en/api-guides/tools/idf-monitor.rst | 9 +++++++++ tools/idf_monitor_base/argument_parser.py | 3 +-- tools/idf_monitor_base/serial_handler.py | 1 - tools/idf_py_actions/serial_ext.py | 6 ++++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/en/api-guides/tools/idf-monitor.rst b/docs/en/api-guides/tools/idf-monitor.rst index e256248949..b289b36d19 100644 --- a/docs/en/api-guides/tools/idf-monitor.rst +++ b/docs/en/api-guides/tools/idf-monitor.rst @@ -184,6 +184,15 @@ To decode each address, IDF Monitor runs the following command in the background Set environment variable ``ESP_MONITOR_DECODE`` to ``0`` or call idf_monitor.py with specific command line option: ``idf_monitor.py --disable-address-decoding`` to disable address decoding. +Reset of the chip target on connect +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The reset of the target chip is performed using DTR and RTS serial lines. For preventing the reset of the target on idf monitor startup call idf_monitor.py with specific command line option: ``idf_monitor.py --no-reset``. + +.. note:: + + The same behavior can be achieved using ``idf.py monitor`` interface with specific command line option: ``--no-reset``. To prevent the reset on startup is required to call the command with explicitly set port ``idf.py monitor --no-reset -p [PORT]`` + + Launching GDB with GDBStub ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tools/idf_monitor_base/argument_parser.py b/tools/idf_monitor_base/argument_parser.py index 937231596e..b0233bcc4e 100644 --- a/tools/idf_monitor_base/argument_parser.py +++ b/tools/idf_monitor_base/argument_parser.py @@ -18,9 +18,8 @@ def get_parser(): # type: () -> argparse.ArgumentParser ) parser.add_argument( - '--no-reset', '-R', + '--no-reset', help='Do not reset the chip on monitor startup', - default=False, action='store_true' ) diff --git a/tools/idf_monitor_base/serial_handler.py b/tools/idf_monitor_base/serial_handler.py index 2fcdb41917..b3a71f64a2 100644 --- a/tools/idf_monitor_base/serial_handler.py +++ b/tools/idf_monitor_base/serial_handler.py @@ -193,7 +193,6 @@ class SerialHandler: console_reader.stop() serial_reader.stop() elif cmd == CMD_RESET: - self.serial_instance.setDTR(high) # IO0=HIGH, default state self.serial_instance.setRTS(low) # EN=LOW, chip in reset self.serial_instance.setDTR(self.serial_instance.dtr) # usbser.sys workaround time.sleep(reset_delay) diff --git a/tools/idf_py_actions/serial_ext.py b/tools/idf_py_actions/serial_ext.py index a51ef69ea4..fbfafd79df 100644 --- a/tools/idf_py_actions/serial_ext.py +++ b/tools/idf_py_actions/serial_ext.py @@ -95,7 +95,9 @@ def action_extensions(base_actions, project_path): if project_desc['target'] != 'linux': if no_reset and args.port is None: - sys.stderr.write('WARNING: --no-reset is ignored. Please specify the port with the --port argument in order to use this option.\n') + msg = ('WARNING: --no-reset is ignored. ' + 'Please specify the port with the --port argument in order to use this option.') + yellow_print(msg) no_reset = False esp_port = args.port or _get_default_serial_port(args) @@ -269,7 +271,7 @@ def action_extensions(base_actions, project_path): 'if this option is set. This option is set by default if IDF Monitor was invoked ' 'together with encrypted-flash or encrypted-app-flash target.'), }, { - 'names': ['--no-reset', '-R'], + 'names': ['--no-reset'], 'is_flag': True, 'help': ('Disable reset on monitor startup. ' 'IDF Monitor will not reset the MCU target by toggling DTR/RTS lines on startup '