Browse Source

Merge branch 'contrib/github_pr_8788' into 'master'

Add idf.py monitor argument --no-reset (-R) (GitHub PR)

Closes IDFGH-7189, IDFGH-7301, and IDFGH-5963

See merge request espressif/esp-idf!18010
Martin Gano 3 years ago
parent
commit
89f754183e

+ 9 - 0
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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 

+ 4 - 2
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,

+ 6 - 0
tools/idf_monitor_base/argument_parser.py

@@ -17,6 +17,12 @@ def get_parser():  # type: () -> argparse.ArgumentParser
         default=os.environ.get('ESPTOOL_PORT', '/dev/ttyUSB0')
     )
 
+    parser.add_argument(
+        '--no-reset',
+        help='Do not reset the chip on monitor startup',
+        action='store_true'
+    )
+
     parser.add_argument(
         '--disable-address-decoding', '-d',
         help="Don't print lines about decoded addresses from the application ELF file",

+ 5 - 4
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,10 @@ class SerialHandler:
             console_reader.stop()
             serial_reader.stop()
         elif cmd == CMD_RESET:
-            self.serial_instance.setRTS(low)
+            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:

+ 4 - 3
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

+ 16 - 1
tools/idf_py_actions/serial_ext.py

@@ -81,7 +81,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
         """
@@ -92,6 +92,12 @@ 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:
+                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)
             monitor_args += ['-p', esp_port]
 
@@ -132,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']
 
@@ -259,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'],
+                        '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,