From aecd328255aeeb4b32ca591e153c8683561c96e2 Mon Sep 17 00:00:00 2001 From: Sergey Shchelkanov Date: Thu, 11 May 2023 02:56:07 +0300 Subject: [PATCH] WIP parse hex line --- .gitignore | 3 +- mik32_parsers.py | 88 ++++++++++++++++++++++++++++++++++++----- mik32_upload.py | 92 ++++++++++++++----------------------------- parsers/parser_hex.py | 3 -- parsers/parsers.py | 16 -------- 5 files changed, 109 insertions(+), 93 deletions(-) delete mode 100644 parsers/parser_hex.py delete mode 100644 parsers/parsers.py diff --git a/.gitignore b/.gitignore index 4f5c3d3..1d9eed2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__ .vscode -openocd \ No newline at end of file +openocd +*.hex \ No newline at end of file diff --git a/mik32_parsers.py b/mik32_parsers.py index a583003..6874484 100644 --- a/mik32_parsers.py +++ b/mik32_parsers.py @@ -1,4 +1,80 @@ from typing import List, Dict +from dataclasses import dataclass + +from enum import Enum +from typing import List, Tuple + + +class RecordType(Enum): + UNKNOWN = -1 + DATA = 0 + EOF = 1 + SEGADDR = 2 + STARTADDR = 3 + EXTADDR = 4 + LINEARSTARTADDR = 5 + + +@dataclass +class Record: + type: RecordType + address: int + data: List[int] + + +def parse_line(line: str, file_extension: str) -> Record: + if file_extension != ".hex": + raise Exception("Unsupported file format: %s" % (file_extension)) + + return parse_hex_line(line) + + +def parse_hex_line(line: str) -> Record: + if line[0] != ':': + print("Error: unexpected record mark on line %s, expect \':\', get \'%c\'" % ( + line, line[0])) + return () + + reclen = int(line[1:3], base=16) # Record length + addr = int(line[3:7], base=16) # Initial address of data byte + rectype = int(line[7:9], base=16) # Record type + data_bytes: List[str] = [] + + data_bytes_line = line[9:reclen*2 + 9] + for i in range(reclen): + data_bytes.append(data_bytes_line[i*2:i*2+2]) + + record = Record(RecordType.UNKNOWN, 0, []) + + if rectype == 0: # Data Record + record.type = RecordType.DATA + record.address = addr + record.data = list(map(lambda x: int(x, base=16), data_bytes)) + elif rectype == 1: # End of File Record + record.type = RecordType.EOF + elif rectype == 2: # Extended Segment Address Record + record.type = RecordType.SEGADDR + record.address = addr + record.data = list(map(lambda x: int(x, base=16), data_bytes)) + elif rectype == 3: # Start Segment Address Record + print("Start Segment Address Record") + print("ERROR: unimplemented record type 3 on line %i" % (i+1)) + is_error = True + elif rectype == 4: # Extended Linear Address Record + record.type = RecordType.EXTADDR + record.address = addr + record.data = list(map(lambda x: int(x, base=16), data_bytes)) + elif rectype == 5: # Start Linear Address Record + record.type = RecordType.LINEARSTARTADDR + record.address = addr + record.data = list(map(lambda x: int(x, base=16), data_bytes)) + print("Start Linear Address is 0x%s (line %s)" % + (data_bytes_line, line)) + else: + record_type = RecordType.UNKNOWN + + return record + def parse_hex(file: str) -> Dict: """ @@ -77,11 +153,11 @@ def parse_hex(file: str) -> Dict: # is_error = True elif rectype == 5: # Start Linear Address Record print("Start Linear Address is 0x%s (line %i)" % - (data_bytes_line, (i+1))) + (data_bytes_line, (i+1))) print("MIK32 MCU does not support arbitrary start address") else: print("ERROR: unexpected record type %i on line %i" % - (rectype, i+1)) + (rectype, i+1)) is_error = True break # print("line %i data_bytes=%i line_addr=%i" % (i+1, data_bytes, line_addr)) @@ -96,14 +172,6 @@ def parse_hex(file: str) -> Dict: return memory_blocks -def parse_bin(filename: str) -> List[int]: - arr: List[int] = [] - with open(filename, "rb") as f: - while byte := f.read(1): - arr.append(byte[0]) - return arr - - def bytes2words(arr: List[int]) -> List[int]: word = [] words = [] diff --git a/mik32_upload.py b/mik32_upload.py index 8880f2d..33e9979 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -5,12 +5,11 @@ import subprocess import os from enum import Enum from typing import List, Tuple -from .drivers.tclrpc import OpenOcdTclRpc -from .drivers.mik32_eeprom import * -from .drivers.mik32_spifi import * -from .drivers.mik32_ram import * -from .mik32_parsers import * -from .parsers.parser_hex import * +from drivers.tclrpc import OpenOcdTclRpc +from drivers.mik32_eeprom import * +from drivers.mik32_spifi import * +from drivers.mik32_ram import * +from mik32_parsers import * # class bcolors(Enum): @@ -38,8 +37,8 @@ def test_connection(): raise Exception("ERROR: no regs found, check MCU connection") -def read_file(filename: str) -> List[Tuple[int, List[int]]] : - segments: List[Tuple[int, List[int]]] = [] +def read_file(filename: str) -> List[Record]: + segments: List[Record] = [] lines: List[str] = [] file_name, file_extension = os.path.splitext(filename) @@ -54,28 +53,14 @@ def read_file(filename: str) -> List[Tuple[int, List[int]]] : raise Exception("Unsupported file format: %s" % (file_extension)) for line in lines: - record: Tuple[RecordType, List[int]] - if file_extension == ".hex": - record = + record: Record = parse_line(line, file_extension) + print(record) + - return segments -def get_content(filename: str) -> List[int]: - content: List[int] = [] - - if filename.endswith(".bin"): - content = parse_bin(filename) - elif filename.endswith(".hex"): - content = parse_hex(filename)[0] - else: - - - return content - - -def upload_file(filename: str, boot_source: str = "undefined", is_resume=True) -> int: +def upload_file(filename: str, is_resume=True) -> int: """ Write ihex or binary file into MIK32 EEPROM or external flash memory @@ -87,16 +72,16 @@ def upload_file(filename: str, boot_source: str = "undefined", is_resume=True) - TODO: Implement error handling """ - print("Boot mode %s" % boot_source) + # print("Running OpenOCD...") - print("Running OpenOCD...") - - print(DEFAULT_OPENOCD_EXEC_FILE_PATH) - print(DEFAULT_OPENOCD_SCRIPTS_PATH) + # print(DEFAULT_OPENOCD_EXEC_FILE_PATH) + # print(DEFAULT_OPENOCD_SCRIPTS_PATH) if not os.path.exists(filename): print("ERROR: File %s does not exist" % filename) exit(1) + + print(read_file(filename)) # 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: @@ -113,40 +98,24 @@ def upload_file(filename: str, boot_source: str = "undefined", is_resume=True) - # result = 1 # proc.kill() - if boot_source == "eeprom": - result = write_words(bytes2words(get_content(filename)), is_resume) - elif boot_source == "spifi": - result = spifi_write_file(get_content(filename), is_resume) - elif boot_source == "ram": - write_file(filename, is_resume) - result = 0 # TODO - else: - raise Exception("Unsupported boot source, use eeprom or spifi") - result = 1 + # if boot_source == "eeprom": + # result = write_words(bytes2words(get_content(filename)), is_resume) + # elif boot_source == "spifi": + # result = spifi_write_file(get_content(filename), is_resume) + # elif boot_source == "ram": + # write_file(filename, is_resume) + # result = 0 # TODO + # else: + # raise Exception("Unsupported boot source, use eeprom or spifi") + # result = 1 - return result - - -def show_file(filename: str, boot_source: str = "eeprom"): - if filename.endswith(".bin"): - content = parse_bin(filename) - elif filename.endswith(".hex"): - content = parse_hex(filename) - else: - raise Exception("Unsupported file format") - - if type(content) is list: - print(content) - elif type(content) is dict: - print(content[0]) + return 1 def createParser(): parser = argparse.ArgumentParser() parser.add_argument('filepath', nargs='?') - parser.add_argument('--show-file', action="store_const", const=True) - parser.add_argument('--no-upload', action="store_const", const=True) - parser.add_argument('-b', '--boot-mode', default='undefined') + # parser.add_argument('-b', '--boot-mode', default='undefined') return parser @@ -155,10 +124,7 @@ if __name__ == '__main__': parser = createParser() namespace = parser.parse_args() - if namespace.show_file: - show_file(namespace.filepath) if namespace.filepath: - if namespace.no_upload == None: - upload_file(namespace.filepath, namespace.boot_mode) + upload_file(namespace.filepath) else: print("Nothing to upload") diff --git a/parsers/parser_hex.py b/parsers/parser_hex.py deleted file mode 100644 index 5bab9dd..0000000 --- a/parsers/parser_hex.py +++ /dev/null @@ -1,3 +0,0 @@ -from parsers import RecordType - -def parse(str) -> \ No newline at end of file diff --git a/parsers/parsers.py b/parsers/parsers.py deleted file mode 100644 index 14e2c44..0000000 --- a/parsers/parsers.py +++ /dev/null @@ -1,16 +0,0 @@ -from enum import Enum -from typing import List, Tuple -import parser_hex - - -class RecordType(Enum): - DATA = 1 - - -def parse_line(line: str, file_extension: str) -> Tuple[RecordType, List[int]]: - record: Tuple[RecordType, List[int]] - - if file_extension == ".hex": - - - return record \ No newline at end of file