From 1f90a39a482adc14b3053e0882c0c0fd97da63fb Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Thu, 11 May 2023 13:32:57 +0300 Subject: [PATCH] WIP matching segments to section and error checking --- mik32_parsers.py | 5 +++-- mik32_upload.py | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/mik32_parsers.py b/mik32_parsers.py index 7bed34e..6230a32 100644 --- a/mik32_parsers.py +++ b/mik32_parsers.py @@ -31,9 +31,8 @@ def parse_line(line: str, file_extension: str) -> Record: def parse_hex_line(line: str) -> Record: if line[0] != ':': - print("Error: unexpected record mark on line %s, expect \':\', get \'%c\'" % ( + raise Exception("Error: unexpected record mark on line %s, expect \':\', get \'%c\'" % ( line, line[0])) - return () datalen = int(line[1:3], base=16) # Data field length addr = int(line[3:7], base=16) # Load offset field @@ -186,4 +185,6 @@ def bytes2words(arr: List[int]) -> List[int]: if bytes.__len__() == 4: words.append(bytes[0]+2**8*bytes[1]+2**16*bytes[2]+2**24*bytes[3]) bytes = [] + if bytes.__len__() != 0: + print("WARNING: skipping not-word-aligned byte") return words diff --git a/mik32_upload.py b/mik32_upload.py index 560a65c..5d8b276 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -42,15 +42,17 @@ class Segment: offset: int data: List[int] + class MemoryType(Enum): EEPROM = 1 RAM = 2 SPIFI = 80 + class MemorySection(NamedTuple): type: MemoryType offset: int - length: int # Memory section length in bytes + length: int # Memory section length in bytes mik32v0_sections: List[MemorySection] = [ @@ -60,6 +62,15 @@ mik32v0_sections: List[MemorySection] = [ ] +def belongs_memory_section(memory_section: MemorySection, offset: int) -> bool: + if offset < memory_section.offset: + return False + if offset >= (memory_section.offset + memory_section.length): + return False + + return True + + def read_file(filename: str) -> List[Segment]: segments: List[Segment] = [] lines: List[str] = [] @@ -71,7 +82,7 @@ def read_file(filename: str) -> List[Segment]: elif file_extension == ".bin": with open(filename, "rb") as f: contents = list(f.read()) - segments[0] = (0, contents) + segments.append(Segment(offset=0, data=contents)) else: raise Exception("Unsupported file format: %s" % (file_extension)) @@ -96,6 +107,8 @@ def read_file(filename: str) -> List[Segment]: lba = record.address elif record.type == RecordType.LINEARSTARTADDR: print("Start Linear Address:", record.address) + elif record.type == RecordType.EOF: + break return segments @@ -105,11 +118,8 @@ def upload_file(filename: str, is_resume=True) -> int: Write ihex or binary file into MIK32 EEPROM or external flash memory @filename: full path to the file with hex or bin file format - @boot_source: boot source, eeprom, ram or spifi, define memory block mapped to boot memory area (0x0 offset) @return: return 0 if successful, 1 if failed - - TODO: Implement error handling """ # print("Running OpenOCD...") @@ -121,7 +131,24 @@ def upload_file(filename: str, is_resume=True) -> int: print("ERROR: File %s does not exist" % filename) exit(1) - print(read_file(filename)) + segments: List[Segment] = read_file(filename) + # print(segments) + + for segment in segments: + segment_section: None | MemorySection = None + for section in mik32v0_sections: + if belongs_memory_section(section, segment.offset): + segment_section = section + + if segment_section is None: + raise Exception( + "ERROR: segment with offset %s doesn't belong to any section" % hex(segment.offset)) + if (segment.offset + segment.data.__len__()) > (segment_section.offset + segment_section.length): + raise Exception("ERROR: segment with offset %s and length %s overflows section %s" % ( + hex(segment.offset), segment.data.__len__(), segment_section.type.name)) + + if segment_section.type == MemoryType.EEPROM: + result = write_words(bytes2words(segment.data), is_resume) # cmd = shlex.split("%s -s %s -f interface/ftdi/m-link.cfg -f target/mcu32.cfg" % (DEFAULT_OPENOCD_EXEC_FILE_PATH, DEFAULT_OPENOCD_SCRIPTS_PATH), posix=False) # with subprocess.Popen(cmd, shell=True, stdout=subprocess.DEVNULL) as proc: