mirror of
https://github.com/espressif/esptool.git
synced 2025-10-20 22:09:59 +08:00
refactor(cli_mode): Improve CLI mode workflow code
This commit is contained in:
@@ -768,185 +768,213 @@ def main(argv=None, esp=None):
|
|||||||
operation_func = globals()[args.operation]
|
operation_func = globals()[args.operation]
|
||||||
operation_args = inspect.getfullargspec(operation_func).args
|
operation_args = inspect.getfullargspec(operation_func).args
|
||||||
|
|
||||||
if (
|
# Commands that don't require an ESP object (image generation, etc.)
|
||||||
operation_args[0] == "esp"
|
if operation_args[0] != "esp":
|
||||||
): # operation function takes an ESPLoader connection object
|
operation_func(args)
|
||||||
if args.before != "no_reset_no_sync":
|
return
|
||||||
initial_baud = min(
|
|
||||||
ESPLoader.ESP_ROM_BAUD, args.baud
|
|
||||||
) # don't sync faster than the default baud rate
|
|
||||||
else:
|
|
||||||
initial_baud = args.baud
|
|
||||||
|
|
||||||
if args.port is None:
|
# Commands that require an ESP object (flash read/write, etc.)
|
||||||
ser_list = get_port_list(
|
# 1) Get the ESP object
|
||||||
args.filterVids, args.filterPids, args.filterNames, args.filterSerials
|
#######################
|
||||||
)
|
|
||||||
log.print(f"Found {len(ser_list)} serial ports")
|
if args.before != "no_reset_no_sync":
|
||||||
else:
|
initial_baud = min(
|
||||||
ser_list = [args.port]
|
ESPLoader.ESP_ROM_BAUD, args.baud
|
||||||
open_port_attempts = os.environ.get(
|
) # don't sync faster than the default baud rate
|
||||||
"ESPTOOL_OPEN_PORT_ATTEMPTS", DEFAULT_OPEN_PORT_ATTEMPTS
|
else:
|
||||||
|
initial_baud = args.baud
|
||||||
|
|
||||||
|
if args.port is None:
|
||||||
|
ser_list = get_port_list(
|
||||||
|
args.filterVids, args.filterPids, args.filterNames, args.filterSerials
|
||||||
)
|
)
|
||||||
try:
|
log.print(f"Found {len(ser_list)} serial ports")
|
||||||
open_port_attempts = int(open_port_attempts)
|
else:
|
||||||
except ValueError:
|
ser_list = [args.port]
|
||||||
raise SystemExit("Invalid value for ESPTOOL_OPEN_PORT_ATTEMPTS")
|
open_port_attempts = os.environ.get(
|
||||||
if open_port_attempts != 1:
|
"ESPTOOL_OPEN_PORT_ATTEMPTS", DEFAULT_OPEN_PORT_ATTEMPTS
|
||||||
if args.port is None or args.chip == "auto":
|
)
|
||||||
log.warning(
|
try:
|
||||||
"The ESPTOOL_OPEN_PORT_ATTEMPTS (open_port_attempts) option "
|
open_port_attempts = int(open_port_attempts)
|
||||||
"can only be used with --port and --chip arguments."
|
except ValueError:
|
||||||
)
|
raise SystemExit("Invalid value for ESPTOOL_OPEN_PORT_ATTEMPTS")
|
||||||
else:
|
if open_port_attempts != 1:
|
||||||
esp = esp or connect_loop(
|
if args.port is None or args.chip == "auto":
|
||||||
args.port,
|
log.warning(
|
||||||
initial_baud,
|
"The ESPTOOL_OPEN_PORT_ATTEMPTS (open_port_attempts) option "
|
||||||
args.chip,
|
"can only be used with --port and --chip arguments."
|
||||||
open_port_attempts,
|
)
|
||||||
args.trace,
|
else:
|
||||||
args.before,
|
esp = esp or connect_loop(
|
||||||
)
|
args.port,
|
||||||
esp = esp or get_default_connected_device(
|
initial_baud,
|
||||||
ser_list,
|
args.chip,
|
||||||
port=args.port,
|
open_port_attempts,
|
||||||
connect_attempts=args.connect_attempts,
|
args.trace,
|
||||||
initial_baud=initial_baud,
|
args.before,
|
||||||
chip=args.chip,
|
)
|
||||||
trace=args.trace,
|
esp = esp or get_default_connected_device(
|
||||||
before=args.before,
|
ser_list,
|
||||||
|
port=args.port,
|
||||||
|
connect_attempts=args.connect_attempts,
|
||||||
|
initial_baud=initial_baud,
|
||||||
|
chip=args.chip,
|
||||||
|
trace=args.trace,
|
||||||
|
before=args.before,
|
||||||
|
)
|
||||||
|
|
||||||
|
if esp is None:
|
||||||
|
raise FatalError(
|
||||||
|
"Could not connect to an Espressif device "
|
||||||
|
f"on any of the {len(ser_list)} available serial ports."
|
||||||
)
|
)
|
||||||
|
|
||||||
if esp is None:
|
# 2) Print the chip info
|
||||||
raise FatalError(
|
########################
|
||||||
"Could not connect to an Espressif device "
|
|
||||||
f"on any of the {len(ser_list)} available serial ports."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
if esp.secure_download_mode:
|
||||||
|
log.print(f"Chip is {esp.CHIP_NAME} in Secure Download Mode")
|
||||||
|
else:
|
||||||
|
log.print(f"Chip is {esp.get_chip_description()}")
|
||||||
|
log.print(f"Features: {', '.join(esp.get_chip_features())}")
|
||||||
|
log.print(f"Crystal is {esp.get_crystal_freq()}MHz")
|
||||||
|
usb_mode = esp.get_usb_mode()
|
||||||
|
if usb_mode is not None:
|
||||||
|
log.print(f"USB mode: {usb_mode}")
|
||||||
|
read_mac(esp, args)
|
||||||
|
|
||||||
|
# 3) Upload the stub flasher
|
||||||
|
############################
|
||||||
|
|
||||||
|
if not args.no_stub:
|
||||||
if esp.secure_download_mode:
|
if esp.secure_download_mode:
|
||||||
log.print(f"Chip is {esp.CHIP_NAME} in Secure Download Mode")
|
log.warning(
|
||||||
else:
|
"Stub loader is not supported in Secure Download Mode, "
|
||||||
log.print(f"Chip is {esp.get_chip_description()}")
|
"setting --no-stub"
|
||||||
log.print(f"Features: {', '.join(esp.get_chip_features())}")
|
)
|
||||||
log.print(f"Crystal is {esp.get_crystal_freq()}MHz")
|
args.no_stub = True
|
||||||
usb_mode = esp.get_usb_mode()
|
elif not esp.IS_STUB and esp.stub_is_disabled:
|
||||||
if usb_mode is not None:
|
log.warning(
|
||||||
log.print(f"USB mode: {usb_mode}")
|
"Stub loader has been disabled for compatibility, setting --no-stub"
|
||||||
read_mac(esp, args)
|
)
|
||||||
|
args.no_stub = True
|
||||||
if not args.no_stub:
|
elif esp.CHIP_NAME in [
|
||||||
if esp.secure_download_mode:
|
|
||||||
log.warning(
|
|
||||||
"Stub loader is not supported in Secure Download Mode, "
|
|
||||||
"setting --no-stub"
|
|
||||||
)
|
|
||||||
args.no_stub = True
|
|
||||||
elif not esp.IS_STUB and esp.stub_is_disabled:
|
|
||||||
log.warning(
|
|
||||||
"Stub loader has been disabled for compatibility, setting --no-stub"
|
|
||||||
)
|
|
||||||
args.no_stub = True
|
|
||||||
elif esp.CHIP_NAME in [
|
|
||||||
"ESP32-H21",
|
"ESP32-H21",
|
||||||
"ESP32-H4",
|
"ESP32-H4",
|
||||||
]: # TODO: [ESP32H21] IDF-11509 [ESP32H4] IDF-12271
|
]: # TODO: [ESP32H21] IDF-11509 [ESP32H4] IDF-12271
|
||||||
log.warning(
|
log.warning(
|
||||||
f"Stub loader is not yet supported on {esp.CHIP_NAME}, "
|
f"Stub loader is not yet supported on {esp.CHIP_NAME}, "
|
||||||
"setting --no-stub"
|
"setting --no-stub"
|
||||||
)
|
)
|
||||||
args.no_stub = True
|
args.no_stub = True
|
||||||
else:
|
else:
|
||||||
try:
|
|
||||||
esp = esp.run_stub()
|
|
||||||
except Exception:
|
|
||||||
# The CH9102 bridge (PID: 0x55D4) can have issues on MacOS
|
|
||||||
if sys.platform == "darwin" and esp._get_pid() == 0x55D4:
|
|
||||||
log.print()
|
|
||||||
log.note(
|
|
||||||
"If issues persist, "
|
|
||||||
"try installing the WCH USB-to-Serial MacOS driver."
|
|
||||||
)
|
|
||||||
raise
|
|
||||||
|
|
||||||
if args.override_vddsdio:
|
|
||||||
esp.override_vddsdio(args.override_vddsdio)
|
|
||||||
|
|
||||||
if args.baud > initial_baud:
|
|
||||||
try:
|
try:
|
||||||
esp.change_baud(args.baud)
|
esp = esp.run_stub()
|
||||||
except NotImplementedInROMError:
|
except Exception:
|
||||||
log.warning(
|
# The CH9102 bridge (PID: 0x55D4) can have issues on MacOS
|
||||||
f"ROM doesn't support changing baud rate. "
|
if sys.platform == "darwin" and esp._get_pid() == 0x55D4:
|
||||||
f"Keeping initial baud rate {initial_baud}"
|
log.print()
|
||||||
)
|
log.note(
|
||||||
|
"If issues persist, "
|
||||||
|
"try installing the WCH USB-to-Serial MacOS driver."
|
||||||
|
)
|
||||||
|
raise
|
||||||
|
|
||||||
flash_attach(esp, args.spi_connection if hasattr(args, "spi_connection") else None)
|
# 4) Configure the baud rate and voltage regulator
|
||||||
if hasattr(args, "flash_size"):
|
##################################################
|
||||||
args.flash_size = flash_set_parameters(esp, args.flash_size)
|
|
||||||
|
|
||||||
# Detect flash size if "ALL" is specified
|
if args.override_vddsdio:
|
||||||
if getattr(args, "size", "") == "all":
|
esp.override_vddsdio(args.override_vddsdio)
|
||||||
if esp.secure_download_mode:
|
|
||||||
raise FatalError(
|
|
||||||
"Detecting flash size is not supported in secure download mode. "
|
|
||||||
"Set an exact size value."
|
|
||||||
)
|
|
||||||
size_str = detect_flash_size(esp)
|
|
||||||
if size_str is None:
|
|
||||||
raise FatalError(
|
|
||||||
"Detecting flash size failed. Set an exact size value."
|
|
||||||
)
|
|
||||||
log.print(f"Detected flash size: {size_str}")
|
|
||||||
args.size = flash_size_bytes(size_str)
|
|
||||||
|
|
||||||
# Check if we are writing past 16MB boundary
|
|
||||||
if esp.IS_STUB and args.operation != "dump_mem" and hasattr(args, "address") and hasattr(args, "size"):
|
|
||||||
if esp.CHIP_NAME != "ESP32-S3" and args.address + args.size > 0x1000000:
|
|
||||||
log.note(
|
|
||||||
"Flasher stub doesn't fully support flash size larger "
|
|
||||||
"than 16MB, in case of failure use --no-stub."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
if args.baud > initial_baud:
|
||||||
try:
|
try:
|
||||||
operation_func(esp, args)
|
esp.change_baud(args.baud)
|
||||||
finally:
|
except NotImplementedInROMError:
|
||||||
try: # Clean up AddrFilenamePairAction files
|
log.warning(
|
||||||
for address, argfile in args.addr_filename:
|
f"ROM doesn't support changing baud rate. "
|
||||||
argfile.close()
|
f"Keeping initial baud rate {initial_baud}"
|
||||||
except AttributeError:
|
)
|
||||||
pass
|
|
||||||
|
|
||||||
# Handle post-operation behaviour (reset or other)
|
# 5) Attach the flash chip and set its parameters
|
||||||
if operation_func == load_ram:
|
#################################################
|
||||||
# the ESP is now running the loaded image, so let it run
|
|
||||||
log.print("Exiting immediately.")
|
flash_attach(esp, args.spi_connection if hasattr(args, "spi_connection") else None)
|
||||||
elif args.after == "hard_reset":
|
if hasattr(args, "flash_size"):
|
||||||
|
args.flash_size = flash_set_parameters(esp, args.flash_size)
|
||||||
|
|
||||||
|
# 6) Perform argument processing and validation
|
||||||
|
###############################################
|
||||||
|
|
||||||
|
if getattr(args, "size", "") == "all":
|
||||||
|
if esp.secure_download_mode:
|
||||||
|
raise FatalError(
|
||||||
|
"Detecting flash size is not supported in secure download mode. "
|
||||||
|
"Set an exact size value."
|
||||||
|
)
|
||||||
|
size_str = detect_flash_size(esp)
|
||||||
|
if size_str is None:
|
||||||
|
raise FatalError("Detecting flash size failed. Set an exact size value.")
|
||||||
|
log.print(f"Detected flash size: {size_str}")
|
||||||
|
args.size = flash_size_bytes(size_str)
|
||||||
|
|
||||||
|
if ( # Check if we are writing/reading past 16MB boundary
|
||||||
|
esp.IS_STUB
|
||||||
|
and args.operation != "dump_mem"
|
||||||
|
and hasattr(args, "address")
|
||||||
|
and hasattr(args, "size")
|
||||||
|
):
|
||||||
|
if esp.CHIP_NAME != "ESP32-S3" and args.address + args.size > 0x1000000:
|
||||||
|
log.note(
|
||||||
|
"Flasher stub doesn't fully support flash size larger "
|
||||||
|
"than 16MB, in case of failure use --no-stub."
|
||||||
|
)
|
||||||
|
|
||||||
|
# 7) Run the selected operation
|
||||||
|
###############################
|
||||||
|
|
||||||
|
try:
|
||||||
|
operation_func(esp, args)
|
||||||
|
finally:
|
||||||
|
try: # Clean up AddrFilenamePairAction files
|
||||||
|
for address, argfile in args.addr_filename:
|
||||||
|
argfile.close()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 8) Reset the chip
|
||||||
|
###################
|
||||||
|
|
||||||
|
# Handle post-operation behaviour (reset or other)
|
||||||
|
if operation_func == load_ram:
|
||||||
|
# the ESP is now running the loaded image, so let it run
|
||||||
|
log.print("Exiting immediately.")
|
||||||
|
elif args.after == "hard_reset":
|
||||||
|
esp.hard_reset()
|
||||||
|
elif args.after == "soft_reset":
|
||||||
|
log.print("Soft resetting...")
|
||||||
|
# flash_finish will trigger a soft reset
|
||||||
|
esp.soft_reset(False)
|
||||||
|
elif args.after == "no_reset_stub":
|
||||||
|
log.print("Staying in flasher stub.")
|
||||||
|
elif args.after == "watchdog_reset":
|
||||||
|
if esp.secure_download_mode:
|
||||||
|
log.warning(
|
||||||
|
"Watchdog hard reset is not supported in Secure Download Mode, "
|
||||||
|
"attempting classic hard reset instead."
|
||||||
|
)
|
||||||
esp.hard_reset()
|
esp.hard_reset()
|
||||||
elif args.after == "soft_reset":
|
else:
|
||||||
log.print("Soft resetting...")
|
esp.watchdog_reset()
|
||||||
# flash_finish will trigger a soft reset
|
else: # args.after == 'no_reset'
|
||||||
esp.soft_reset(False)
|
log.print("Staying in bootloader.")
|
||||||
elif args.after == "no_reset_stub":
|
if esp.IS_STUB:
|
||||||
log.print("Staying in flasher stub.")
|
esp.soft_reset(True) # exit stub back to ROM loader
|
||||||
elif args.after == "watchdog_reset":
|
|
||||||
if esp.secure_download_mode:
|
|
||||||
log.warning(
|
|
||||||
"Watchdog hard reset is not supported in Secure Download Mode, "
|
|
||||||
"attempting classic hard reset instead."
|
|
||||||
)
|
|
||||||
esp.hard_reset()
|
|
||||||
else:
|
|
||||||
esp.watchdog_reset()
|
|
||||||
else: # args.after == 'no_reset'
|
|
||||||
log.print("Staying in bootloader.")
|
|
||||||
if esp.IS_STUB:
|
|
||||||
esp.soft_reset(True) # exit stub back to ROM loader
|
|
||||||
|
|
||||||
if not external_esp:
|
# 9) Finish and close the port
|
||||||
esp._port.close()
|
##############################
|
||||||
|
|
||||||
else:
|
if not external_esp:
|
||||||
operation_func(args)
|
esp._port.close()
|
||||||
|
|
||||||
|
|
||||||
def arg_auto_int(x):
|
def arg_auto_int(x):
|
||||||
|
Reference in New Issue
Block a user