fix stm8loader.py
This commit is contained in:
BIN
scripts/boot2.bin
Normal file
BIN
scripts/boot2.bin
Normal file
Binary file not shown.
@@ -35,7 +35,7 @@ class STM8BootloaderError(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
class STM8Bootloader:
|
class STM8Bootloader:
|
||||||
def __init__(self, port: str, verbose: bool = False, reset_pin: str = 'rts+dtr'):
|
def __init__(self, port: str, verbose: bool = False, reset_pin: str = 'rts+dtr', boot2_file: str = None):
|
||||||
"""
|
"""
|
||||||
Initialize STM8 Bootloader
|
Initialize STM8 Bootloader
|
||||||
|
|
||||||
@@ -43,6 +43,7 @@ class STM8Bootloader:
|
|||||||
port: Serial port name
|
port: Serial port name
|
||||||
verbose: Whether to display detailed debug information
|
verbose: Whether to display detailed debug information
|
||||||
reset_pin: Reset pin type ('rts+dtr', 'rts', 'dtr' or 'none')
|
reset_pin: Reset pin type ('rts+dtr', 'rts', 'dtr' or 'none')
|
||||||
|
boot2_file: boot2 binary file path
|
||||||
"""
|
"""
|
||||||
self.port = port
|
self.port = port
|
||||||
self.verbose = verbose
|
self.verbose = verbose
|
||||||
@@ -53,6 +54,9 @@ class STM8Bootloader:
|
|||||||
self.in_boot2 = False
|
self.in_boot2 = False
|
||||||
self.script_dir = os.path.dirname(os.path.abspath(__file__))
|
self.script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
# Store boot2 file path
|
||||||
|
self.default_boot2_file = boot2_file
|
||||||
|
|
||||||
def log(self, message: str, level: str = "INFO"):
|
def log(self, message: str, level: str = "INFO"):
|
||||||
"""
|
"""
|
||||||
Print log information
|
Print log information
|
||||||
@@ -229,8 +233,14 @@ class STM8Bootloader:
|
|||||||
True: Send successful, False: Send failed
|
True: Send successful, False: Send failed
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# If file path is not absolute, make it relative to script directory
|
# If file path is not absolute, make it relative to current working directory
|
||||||
if not os.path.isabs(bin_file):
|
if not os.path.isabs(bin_file):
|
||||||
|
# Try to find file in current directory first
|
||||||
|
current_dir_file = os.path.join(os.getcwd(), bin_file)
|
||||||
|
if os.path.exists(current_dir_file):
|
||||||
|
bin_file = current_dir_file
|
||||||
|
else:
|
||||||
|
# Fallback to script directory
|
||||||
bin_file = os.path.join(self.script_dir, bin_file)
|
bin_file = os.path.join(self.script_dir, bin_file)
|
||||||
|
|
||||||
with open(bin_file, 'rb') as f:
|
with open(bin_file, 'rb') as f:
|
||||||
@@ -240,7 +250,7 @@ class STM8Bootloader:
|
|||||||
self.log(f"File {bin_file} is empty", "ERROR")
|
self.log(f"File {bin_file} is empty", "ERROR")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.log(f"Read {len(data)} bytes of boot2 program", "DEBUG")
|
self.log(f"Read {len(data)} bytes of boot2 program from {bin_file}", "DEBUG")
|
||||||
|
|
||||||
# Byte reversal
|
# Byte reversal
|
||||||
reversed_data = bytes(reversed(data))
|
reversed_data = bytes(reversed(data))
|
||||||
@@ -420,16 +430,25 @@ class STM8Bootloader:
|
|||||||
self.in_boot2 = False
|
self.in_boot2 = False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def upload_boot2(self, boot2_file: str = "boot2.bin") -> bool:
|
def upload_boot2(self, boot2_file: str = None) -> bool:
|
||||||
"""
|
"""
|
||||||
Upload boot2 program to MCU
|
Upload boot2 program to MCU
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
boot2_file: boot2 binary file path
|
boot2_file: boot2 binary file path (if None, use default)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True: Upload successful, False: Upload failed
|
True: Upload successful, False: Upload failed
|
||||||
"""
|
"""
|
||||||
|
# Use provided file or default
|
||||||
|
if boot2_file is None:
|
||||||
|
if self.default_boot2_file:
|
||||||
|
boot2_file = self.default_boot2_file
|
||||||
|
else:
|
||||||
|
# Fallback to script directory
|
||||||
|
boot2_file = os.path.join(self.script_dir, "boot2.bin")
|
||||||
|
|
||||||
|
self.log("Starting boot2 program upload...", "INFO")
|
||||||
|
|
||||||
# 1. Switch to 9600 bps
|
# 1. Switch to 9600 bps
|
||||||
self.close()
|
self.close()
|
||||||
@@ -717,9 +736,10 @@ class STM8Bootloader:
|
|||||||
self.list_directory(path)
|
self.list_directory(path)
|
||||||
|
|
||||||
elif cmd == 'reload':
|
elif cmd == 'reload':
|
||||||
# Reset and upload boot2
|
# Reset and upload boot2 with optional file path
|
||||||
|
boot2_file = args[1] if len(args) > 1 else None
|
||||||
self.log("Executing reset and to upload boot2...", "INFO")
|
self.log("Executing reset and to upload boot2...", "INFO")
|
||||||
if not self.upload_boot2():
|
if not self.upload_boot2(boot2_file):
|
||||||
self.log("Reset upload failed", "ERROR")
|
self.log("Reset upload failed", "ERROR")
|
||||||
else:
|
else:
|
||||||
self.log("Reset upload successful", "INFO")
|
self.log("Reset upload successful", "INFO")
|
||||||
@@ -838,7 +858,7 @@ Command List:
|
|||||||
|
|
||||||
ls [path] - List directory contents, files show size, directories only names
|
ls [path] - List directory contents, files show size, directories only names
|
||||||
|
|
||||||
reload - Reset MCU and upload boot2 program
|
reload [file] - Reset MCU and upload boot2 program
|
||||||
|
|
||||||
help - Display this help information
|
help - Display this help information
|
||||||
|
|
||||||
@@ -865,23 +885,23 @@ def main():
|
|||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
epilog="""
|
epilog="""
|
||||||
Examples:
|
Examples:
|
||||||
%(prog)s COM3 # Enter interactive mode
|
%(prog)s /dev/ttyUSB0 # Enter interactive mode
|
||||||
%(prog)s COM3 -r 0x8000 256 # Read memory
|
%(prog)s /dev/ttyUSB0 -r 0x8000 256 # Read memory
|
||||||
%(prog)s COM3 -w 0x8000 firmware.bin # Write file
|
%(prog)s /dev/ttyUSB0 -w 0x8000 firmware.bin # Write file
|
||||||
%(prog)s COM3 -w 0x8000 "AABBCC" # Write hex string
|
%(prog)s /dev/ttyUSB0 -w 0x8000 "AABBCC" # Write hex string
|
||||||
%(prog)s COM3 -g 0x8000 # Jump execution
|
%(prog)s /dev/ttyUSB0 -g 0x8000 # Jump execution
|
||||||
%(prog)s --list-ports # List available serial ports
|
%(prog)s --list-ports # List available serial ports
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
# Serial port related parameters
|
# Serial port related parameters
|
||||||
parser.add_argument('port', nargs='?', help='Serial port name (e.g., COM3, /dev/ttyUSB0)')
|
parser.add_argument('port', nargs='?', help='Serial port name (e.g., /dev/ttyUSB0, COM3)')
|
||||||
parser.add_argument('-b', '--baudrate', type=int, default=BOOT2_BAUDRATE,
|
parser.add_argument('-b', '--baudrate', type=int, default=BOOT2_BAUDRATE,
|
||||||
help=f'Serial port baud rate (default: {BOOT2_BAUDRATE})')
|
help=f'Serial port baud rate (default: {BOOT2_BAUDRATE})')
|
||||||
|
|
||||||
# boot2 upload parameters
|
# boot2 upload parameters
|
||||||
parser.add_argument('--boot2', default='boot2.bin',
|
parser.add_argument('--boot2', default='boot2.bin',
|
||||||
help='boot2 program file path (default: boot2.bin in script directory)')
|
help='boot2 program file path (default: boot2.bin in current directory or script directory)')
|
||||||
parser.add_argument('--skip-boot2', action='store_true',
|
parser.add_argument('--skip-boot2', action='store_true',
|
||||||
help='Skip automatic boot2 upload, directly enter interactive mode')
|
help='Skip automatic boot2 upload, directly enter interactive mode')
|
||||||
|
|
||||||
@@ -922,8 +942,12 @@ Examples:
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Handle boot2 file path
|
||||||
|
boot2_file = args.boot2
|
||||||
|
|
||||||
# Create bootloader instance
|
# Create bootloader instance
|
||||||
loader = STM8Bootloader(args.port, verbose=args.verbose, reset_pin=args.reset_pin)
|
loader = STM8Bootloader(args.port, verbose=args.verbose,
|
||||||
|
reset_pin=args.reset_pin, boot2_file=boot2_file)
|
||||||
|
|
||||||
# Open serial port
|
# Open serial port
|
||||||
loader.open(baudrate=args.baudrate)
|
loader.open(baudrate=args.baudrate)
|
||||||
@@ -934,7 +958,7 @@ Examples:
|
|||||||
# If not in boot2 and not skipping boot2 upload, must upload boot2
|
# If not in boot2 and not skipping boot2 upload, must upload boot2
|
||||||
if not in_boot2 and not args.skip_boot2:
|
if not in_boot2 and not args.skip_boot2:
|
||||||
print("[INFO] Not in boot2 mode, starting boot2 program upload...")
|
print("[INFO] Not in boot2 mode, starting boot2 program upload...")
|
||||||
if not loader.upload_boot2(args.boot2):
|
if not loader.upload_boot2():
|
||||||
print("[ERROR] boot2 upload failed")
|
print("[ERROR] boot2 upload failed")
|
||||||
loader.close()
|
loader.close()
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
Reference in New Issue
Block a user