diff --git a/scripts/boot2.bin b/scripts/boot2.bin index 807b531..baf8cc1 100644 Binary files a/scripts/boot2.bin and b/scripts/boot2.bin differ diff --git a/scripts/boot2.s b/scripts/boot2.s index f4dbb99..547eb7b 100644 --- a/scripts/boot2.s +++ b/scripts/boot2.s @@ -126,7 +126,7 @@ _cmd_exec: ; 直接执行收到的机器码 ld A, #0x81 ; ret code ld (X), A ; X point to checksum already - call rx_buffer + call rx_buffer+5 ld A, #SUCCESS_CODE jra _ack_then_back diff --git a/scripts/stm8loader.py b/scripts/stm8loader.py index 9b1493f..08c13ab 100644 --- a/scripts/stm8loader.py +++ b/scripts/stm8loader.py @@ -801,7 +801,7 @@ class STM8Bootloader: except Exception as e: self.log(f"Error: {e}", "ERROR") - elif cmd == 'read': + elif cmd == 'read' or cmd == 'r': if len(args) < 3: self.log("Usage: read [file]", "ERROR") continue @@ -825,7 +825,7 @@ class STM8Bootloader: except Exception as e: self.log(f"Error: {e}", "ERROR") - elif cmd == 'write': + elif cmd == 'write' or cmd == 'w': if len(args) < 3: self.log("Usage: write ", "ERROR") self.log("Example: write 0x8000 firmware.bin", "INFO") @@ -854,7 +854,7 @@ class STM8Bootloader: except Exception as e: self.log(f"Error: {e}", "ERROR") - elif cmd == 'exec': + elif cmd == 'exec' or cmd == 'x': if len(args) < 2: self.log("Usage: exec ", "ERROR") self.log("Example: exec 4F9D (CLR A; NOP)", "INFO") @@ -880,7 +880,7 @@ class STM8Bootloader: except Exception as e: self.log(f"Error: {e}", "ERROR") - elif cmd == 'go': + elif cmd == 'go' or cmd == 'g': if len(args) < 2: self.log("Usage: go ", "ERROR") continue @@ -916,28 +916,28 @@ class STM8Bootloader: """Display help information""" help_text = """ Command List: - read [file] - Read memory, optionally save to file + r/read [file] - Read memory, optionally save to file Example: read 0x8000 256 dump.bin - write - Write memory, supports file or hex string + w/write - Write memory, supports file or hex string Example: write 0x8000 firmware.bin Example: write 0x8000 AABBCCDDEEFF - exec - Execute machine code at specified address + x/exec - Execute machine code at *fixed* address Example: exec 4F9D (CLR A; NOP;) - go - Jump to specified address for execution + g/go - Jump to specified address for execution Example: go 0x8000 info - Display MCU information - ls [path] - List directory contents, files show size, directories only names + ls [path] - List directory contents, files show size reload [file] - Reset MCU and upload boot2 program help - Display this help information - exit / quit - Exit interactive mode + exit/quit - Exit interactive mode """ print(help_text) @@ -991,6 +991,8 @@ Examples: help='Write memory: ADDR is start address, FILE/HEX is file or hex string') parser.add_argument('-g', '--go', metavar='ADDR', help='Jump to address for execution') + parser.add_argument('-x', '--exec', metavar='HEX', + help='Execute machine code') # Other options parser.add_argument('--list-ports', action='store_true', @@ -1104,6 +1106,23 @@ Examples: loader.close() return 1 + elif args.exec: + command_executed = True + try: + addr = 0 + hex_str = args.exec.replace('0x', '').replace(' ', '') + if len(hex_str) % 2 != 0: + raise ValueError("Hex string length must be even") + machine_code = bytes.fromhex(hex_str) + if len(machine_code) > MAX_DATA_SIZE: + raise ValueError("Machine code too long (max {MAX_DATA_SIZE} bytes)") + if loader.exec_machine_code(addr, machine_code): + print(f"[INFO] Exec {len(machine_code)} bytes") + except Exception as e: + print(f"[ERROR] Exec failed: {e}") + loader.close() + return 1 + # If no command specified or need to enter interactive mode if not command_executed or args.interactive: loader.interactive_mode()