mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
idf_monitor: Small fixes (baud rate, EOL, /dev/tty.X on macOS, Ctrl-T on failure)
* "make monitor" not passed the configured baud rate
Closes #436 https://github.com/espressif/esp-idf/issues/436
* Pass toolchain prefix from sdkconfig into monitor tool
* Allow setting EOL in idf_monitor.py, use CRLF by default
* Detect if /dev/tty.X is used on macOS, warn and replace with /dev/cu.X
* If a build fails or gdb exits, ignore Ctrl-T (allowing Ctrl-T Ctrl-A/F to be same key sequence everywhere)
* Add a note about winpty on Windows
Ref 02fdf8271d (commitcomment-21369196)
This commit is contained in:
parent
57486a1f61
commit
e477ce93e9
@ -83,12 +83,14 @@ endif
|
||||
simple_monitor: $(call prereq_if_explicit,%flash)
|
||||
$(MONITOR_PYTHON) -m serial.tools.miniterm --rts 0 --dtr 0 --raw $(ESPPORT) $(MONITORBAUD)
|
||||
|
||||
MONITOR_OPTS := --baud $(MONITORBAUD) --port $(ESPPORT) --toolchain-prefix $(CONFIG_TOOLPREFIX) --make "$(MAKE)"
|
||||
|
||||
monitor: $(call prereq_if_explicit,%flash)
|
||||
$(summary) MONITOR
|
||||
[ -f $(APP_ELF) ] || echo "*** 'make monitor' target requires an app to be compiled and flashed first."
|
||||
[ -f $(APP_ELF) ] || echo "*** Run 'make flash monitor' to build, flash and monitor"
|
||||
[ -f $(APP_ELF) ] || echo "*** Or alternatively 'make simple_monitor' to view the serial port as-is."
|
||||
[ -f $(APP_ELF) ] || exit 1
|
||||
$(MONITOR_PYTHON) $(IDF_PATH)/tools/idf_monitor.py --port $(ESPPORT) --make "$(MAKE)" $(APP_ELF)
|
||||
$(MONITOR_PYTHON) $(IDF_PATH)/tools/idf_monitor.py $(MONITOR_OPTS) $(APP_ELF)
|
||||
|
||||
.PHONY: erase_flash
|
||||
|
@ -102,6 +102,7 @@ Known Issues with idf_monitor
|
||||
Issues Observed on Windows
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- If you are using the supported Windows environment and receive the error "winpty: command not found" then run ``pacman -S winpty`` to fix.
|
||||
- Arrow keys and some other special keys in gdb don't work, due to Windows Console limitations.
|
||||
- Occasionally when "make" exits, it may stall for up to 30 seconds before idf_monitor resumes.
|
||||
- Occasionally when "gdb" is run, it may stall for a short time before it begins communicating with the gdbstub.
|
||||
|
@ -70,6 +70,8 @@ TAG_SERIAL = 1
|
||||
# regex matches an potential PC value (0x4xxxxxxx)
|
||||
MATCH_PCADDR = re.compile(r'0x4[0-9a-f]{7}', re.IGNORECASE)
|
||||
|
||||
DEFAULT_TOOLCHAIN_PREFIX = "xtensa-esp32-elf-"
|
||||
|
||||
class StoppableThread(object):
|
||||
"""
|
||||
Provide a Thread-like class which can be 'cancelled' via a subclass-provided
|
||||
@ -193,7 +195,7 @@ class Monitor(object):
|
||||
|
||||
Main difference is that all event processing happens in the main thread, not the worker threads.
|
||||
"""
|
||||
def __init__(self, serial_instance, elf_file, make="make"):
|
||||
def __init__(self, serial_instance, elf_file, make="make", toolchain_prefix=DEFAULT_TOOLCHAIN_PREFIX, eol="CRLF"):
|
||||
super(Monitor, self).__init__()
|
||||
self.event_queue = queue.Queue()
|
||||
self.console = miniterm.Console()
|
||||
@ -207,9 +209,16 @@ class Monitor(object):
|
||||
self.serial_reader = SerialReader(self.serial, self.event_queue)
|
||||
self.elf_file = elf_file
|
||||
self.make = make
|
||||
self.toolchain_prefix = DEFAULT_TOOLCHAIN_PREFIX
|
||||
self.menu_key = CTRL_T
|
||||
self.exit_key = CTRL_RBRACKET
|
||||
|
||||
self.translate_eol = {
|
||||
"CRLF": lambda c: c.replace(b"\n", b"\r\n"),
|
||||
"CR": lambda c: c.replace(b"\n", b"\r"),
|
||||
"LF": lambda c: c.replace(b"\r", b"\n"),
|
||||
}[eol]
|
||||
|
||||
# internal state
|
||||
self._pressed_menu_key = False
|
||||
self._read_line = b""
|
||||
@ -246,6 +255,7 @@ class Monitor(object):
|
||||
self.serial_reader.stop()
|
||||
else:
|
||||
try:
|
||||
key = self.translate_eol(key)
|
||||
self.serial.write(codecs.encode(key))
|
||||
except serial.SerialException:
|
||||
pass # this shouldn't happen, but sometimes port has closed in serial thread
|
||||
@ -327,7 +337,9 @@ class Monitor(object):
|
||||
.format(key_description(CTRL_A)))
|
||||
sys.stderr.write("--- Press any other key to resume monitor (resets target).\n")
|
||||
sys.stderr.write(ANSI_NORMAL)
|
||||
k = self.console.getkey()
|
||||
k = CTRL_T # ignore CTRL-T here, so people can muscle-memory Ctrl-T Ctrl-F, etc.
|
||||
while k == CTRL_T:
|
||||
k = self.console.getkey()
|
||||
finally:
|
||||
self.console.cleanup()
|
||||
if k == self.exit_key:
|
||||
@ -350,8 +362,8 @@ class Monitor(object):
|
||||
|
||||
def lookup_pc_address(self, pc_addr):
|
||||
translation = subprocess.check_output(
|
||||
["xtensa-esp32-elf-addr2line", "-pfia",
|
||||
"-e", self.elf_file, pc_addr],
|
||||
["%saddr2line" % self.toolchain_prefix,
|
||||
"-pfia", "-e", self.elf_file, pc_addr],
|
||||
cwd=".")
|
||||
if not "?? ??:0" in translation:
|
||||
sys.stderr.write(ANSI_YELLOW + translation + ANSI_NORMAL)
|
||||
@ -375,7 +387,7 @@ class Monitor(object):
|
||||
with self: # disable console control
|
||||
sys.stderr.write(ANSI_NORMAL)
|
||||
try:
|
||||
subprocess.call(["xtensa-esp32-elf-gdb",
|
||||
subprocess.call(["%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
|
||||
@ -404,12 +416,29 @@ def main():
|
||||
help='Command to run make',
|
||||
type=str, default='make')
|
||||
|
||||
parser.add_argument(
|
||||
'--toolchain-prefix',
|
||||
help="Triplet prefix to add before cross-toolchain names",
|
||||
default=DEFAULT_TOOLCHAIN_PREFIX)
|
||||
|
||||
parser.add_argument(
|
||||
"--eol",
|
||||
choices=['CR', 'LF', 'CRLF'],
|
||||
type=lambda c: c.upper(),
|
||||
help="End of line to use when sending to the serial port",
|
||||
default='CRLF')
|
||||
|
||||
parser.add_argument(
|
||||
'elf_file', help='ELF file of application',
|
||||
type=argparse.FileType('r'))
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.port.startswith("/dev/tty."):
|
||||
args.port = args.port.replace("/dev/tty.", "/dev/cu.")
|
||||
sys.stderr.write("WARNING: Serial ports accessed as /dev/tty.* will hang gdb if launched. ")
|
||||
sys.stderr.write("Using %s instead...\n" % args.port)
|
||||
|
||||
serial_instance = serial.serial_for_url(args.port, args.baud,
|
||||
do_not_open=True)
|
||||
serial_instance.dtr = False
|
||||
@ -428,7 +457,7 @@ def main():
|
||||
except KeyError:
|
||||
pass # not running a make jobserver
|
||||
|
||||
monitor = Monitor(serial_instance, args.elf_file.name, args.make)
|
||||
monitor = Monitor(serial_instance, args.elf_file.name, args.make, args.eol)
|
||||
|
||||
sys.stderr.write('--- idf_monitor on {p.name} {p.baudrate} ---\n'.format(
|
||||
p=serial_instance))
|
||||
|
Loading…
x
Reference in New Issue
Block a user