From d3f092a7360f238b82a94d25ae0f951febac3b84 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 22 Jun 2012 14:38:43 +0900 Subject: [PATCH] failure handling --- tool/stlinkv2.py | 181 +++++++++++++++++++++++++++++------------------ 1 file changed, 112 insertions(+), 69 deletions(-) diff --git a/tool/stlinkv2.py b/tool/stlinkv2.py index ea78bcb..ab0d219 100755 --- a/tool/stlinkv2.py +++ b/tool/stlinkv2.py @@ -24,12 +24,13 @@ along with this program. If not, see . from struct import * import sys, time +import usb +from colorama import init as colorama_init, Fore, Back, Style # INPUT: binary file # Assumes only single ST-Link/V2 device is attached to computer. -import usb GPIOA=0x40010800 OPTION_BYTES_ADDR=0x1ffff800 @@ -107,7 +108,24 @@ SRAM_ADDRESS=0x20000000 BLOCK_SIZE=16384 # Should be less than (20KiB - 0x0038) BLOCK_WRITE_TIMEOUT=80 # Increase this when you increase BLOCK_SIZE -# This class only supports Gnuk (for now) + +class TimeOutError(Exception): + def __init__(self, msg): + self.msg = msg + def __str__(self): + return repr(self.msg) + def __repr__(self): + return "TimeoutError(" + self.msg + ")" + +class OperationFailure(Exception): + def __init__(self, msg): + self.msg = msg + def __str__(self): + return repr(self.msg) + def __repr__(self): + return "OperationFailure(" + self.msg + ")" + + class stlinkv2(object): def __init__(self, dev): self.__bulkout = 2 @@ -118,7 +136,7 @@ class stlinkv2(object): intf_alt = conf.interfaces[0] intf = intf_alt[0] if intf.interfaceClass != 0xff: # Vendor specific - raise ValueError("Wrong interface class") + raise ValueError("Wrong interface class.", intf.interfaceClass) self.__devhandle = dev.open() try: self.__devhandle.setConfiguration(conf) @@ -220,8 +238,7 @@ class stlinkv2(object): time.sleep(0.050) i = i + 1 if i >= 10: - print "ERROR: blank_check timeout" - break + raise TimeOutError("blank check") r0_value = self.read_reg(0) return r0_value == 0 @@ -246,13 +263,12 @@ class stlinkv2(object): time.sleep(0.050) i = i + 1 if i >= 10: - print "ERROR: option bytes write timeout" - break + raise TimeOutError("option bytes write") status = self.read_memory_u32(FLASH_SR) self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK) if (status & FLASH_SR_EOP) == 0: - print "ERROR: option bytes write error" + raise OperationFailure("option bytes write") def option_bytes_erase(self): self.write_memory_u32(FLASH_KEYR, FLASH_KEY1) @@ -276,7 +292,7 @@ class stlinkv2(object): self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK) if (status & FLASH_SR_EOP) == 0: - raise ValueError("option bytes erase failed") + raise OperationError("option bytes erase") def flash_write_internal(self, addr, data, off, size): prog = gen_prog_flash_write(addr,size) @@ -288,13 +304,12 @@ class stlinkv2(object): time.sleep(0.050) i = i + 1 if i >= BLOCK_WRITE_TIMEOUT: - print "ERROR: flash write timeout" - break + raise TimeOutError("flash write") status = self.read_memory_u32(FLASH_SR) if (status & FLASH_SR_PGERR) != 0: - print "ERROR: write to a location that was not erased" + raise OperationFailure("flash write: write to not erased part") if (status & FLASH_SR_WRPRTERR) != 0: - print "ERROR: write to a location that was write protected" + raise OperationFailure("flash write: write to protected part") def flash_write(self, addr, data): self.write_memory_u32(FLASH_KEYR, FLASH_KEY1) @@ -336,7 +351,7 @@ class stlinkv2(object): self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK) if (status & FLASH_SR_EOP) == 0: - raise ValueError("flash erase all failed") + raise OperationError("flash erase all") def flash_erase_page(self, addr): self.write_memory_u32(FLASH_KEYR, FLASH_KEY1) @@ -360,7 +375,7 @@ class stlinkv2(object): self.write_memory_u32(FLASH_CR, FLASH_CR_LOCK) if (status & FLASH_SR_EOP) == 0: - raise ValueError("flash page erase failed") + raise OperationError("flash page erase") def start(self): mode = self.stl_mode() @@ -373,9 +388,10 @@ class stlinkv2(object): self.enter_swd() s = self.get_status() if s != 0x0080: - raise ValueError("Status of core is not running") - if self.stl_mode() != 2: - raise ValueError("Failed to switch debug mode") + raise ValueError("Status of core is not running.", s) + mode = self.stl_mode() + if mode != 2: + raise ValueError("Failed to switch debug mode.", mode) USB_VENDOR_ST=0x0483 # 0x0483 SGS Thomson Microelectronics @@ -396,7 +412,7 @@ def compare(data_original, data_in_device): i = 0 for d in data_original: if ord(d) != data_in_device[i]: - raise ValueError("verify failed at %08x" % i) + raise ValueError("Verify failed at:", i) i += 1 def open_stlinkv2(): @@ -413,56 +429,26 @@ def help(): print "stlinkv2.py [-e]: Erase flash ROM" print "stlinkv2.py [-u]: Unlock flash ROM" print "stlinkv2.py [-s]: Show status" - print "stlinkv2.py [-n] [-r] FILE: Write content of FILE to flash ROM" + print "stlinkv2.py [-b] [-n] [-r] FILE: Write content of FILE to flash ROM" + print " -b: Enable blanck check" print " -n: Don't enable read protection" print " -r: Don't reset after write" -if __name__ == '__main__': - show_help = False - erase = False - no_protect = False - reset_after_successful_write = False - status_only = False - unlock = False - data = None - - while len(sys.argv) > 1: - if sys.argv[1] == '-h': - sys.argv.pop(1) - break - elif sys.argv[1] == '-e': - sys.argv.pop(1) - erase = True - break - elif sys.argv[1] == '-u': - sys.argv.pop(1) - unlock = True - break - elif sys.argv[1] == '-s': - sys.argv.pop(1) - status_only = True - break - elif sys.argv[1] == '-n': - no_protect = True - elif sys.argv[1] == '-r': - reset_after_successful_write = True - else: - filename = sys.argv[1] - f = open(filename) - data = f.read() - f.close() - sys.argv.pop(1) +def main(show_help, erase, no_protect, reset_after_successful_write, + skip_blank_check, status_only, unlock, data): if show_help or len(sys.argv) != 1: help() - exit(1) + return 1 stl = open_stlinkv2() if not stl: - ValueError("No ST-Link/V2 device found") + raise ValueError("No ST-Link/V2 device found.", None) + stl.start() core_id = stl.core_id() chip_id = stl.read_memory_u32(0xE0042000) + # FST-01 chip id: 0x20036410 print "CORE: %08x, CHIP_ID: %08x" % (core_id, chip_id) print "Flash ROM read protection:", @@ -474,38 +460,42 @@ if __name__ == '__main__': print "Option bytes: %08x" % stl.option_bytes_read() stl.enter_debug() - if stl.get_status() != 0x0081: - raise ValueError("status is not halt.") + status = stl.get_status() + if status != 0x0081: + raise ValueError("Status of core is not halt.", status) if protection: if status_only: - print "The MCU is now stopped. No way to run by STLink/V2. Please reset the board." - exit (0) + print "The MCU is now stopped." + return 0 elif not unlock: print "Please unlock flash ROM protection, at first. By invoking with -u option." - exit(1) + return 1 else: - blank = stl.blank_check() - print "Flash ROM blank check: %s" % blank + if not skip_blank_check: + blank = stl.blank_check() + print "Flash ROM blank check: %s" % blank + else: + blank = True if status_only: stl.reset_sys() stl.run() stl.exit_debug() - exit (0) + return 0 elif unlock: print "No need to unlock. Protection is not enabled." - exit(1) + return 1 if unlock: stl.reset_sys() stl.option_bytes_write(OPTION_BYTES_ADDR,RDP_KEY) print "Flash ROM read protection disabled. Reset the board, now." - exit(0) + return 0 if erase: if blank: print "No need to erase" - exit (0) + return 0 if not blank: print "ERASE ALL" @@ -513,7 +503,7 @@ if __name__ == '__main__': stl.flash_erase_all() if erase: - exit (0) + return 0 time.sleep(0.100) @@ -545,3 +535,56 @@ if __name__ == '__main__': stl.reset_sys() stl.run() stl.exit_debug() + + return 0 + +if __name__ == '__main__': + show_help = False + erase = False + no_protect = False + reset_after_successful_write = True + skip_blank_check=True + status_only = False + unlock = False + data = None + + while len(sys.argv) > 1: + if sys.argv[1] == '-h': + sys.argv.pop(1) + break + elif sys.argv[1] == '-e': + sys.argv.pop(1) + erase = True + break + elif sys.argv[1] == '-u': + sys.argv.pop(1) + unlock = True + break + elif sys.argv[1] == '-s': + sys.argv.pop(1) + status_only = True + skip_blank_check=False + break + elif sys.argv[1] == '-b': + skip_blank_check=False + elif sys.argv[1] == '-n': + no_protect = True + elif sys.argv[1] == '-r': + reset_after_successful_write = False + else: + filename = sys.argv[1] + f = open(filename) + data = f.read() + f.close() + sys.argv.pop(1) + + colorama_init() + + try: + r = main(show_help, erase, no_protect, reset_after_successful_write, + skip_blank_check, status_only, unlock, data) + if r == 0: + print Fore.WHITE + Back.BLUE + Style.BRIGHT + "SUCCESS" + Style.RESET_ALL + exit(r) + except Exception as e: + print Back.RED + Style.BRIGHT + repr(e) + Style.RESET_ALL