WIP parse hex line

This commit is contained in:
Sergey Shchelkanov 2023-05-11 02:56:07 +03:00
parent 9e1c817cf2
commit aecd328255
5 changed files with 109 additions and 93 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
__pycache__ __pycache__
.vscode .vscode
openocd openocd
*.hex

View File

@ -1,4 +1,80 @@
from typing import List, Dict 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: def parse_hex(file: str) -> Dict:
""" """
@ -96,14 +172,6 @@ def parse_hex(file: str) -> Dict:
return memory_blocks 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]: def bytes2words(arr: List[int]) -> List[int]:
word = [] word = []
words = [] words = []

View File

@ -5,12 +5,11 @@ import subprocess
import os import os
from enum import Enum from enum import Enum
from typing import List, Tuple from typing import List, Tuple
from .drivers.tclrpc import OpenOcdTclRpc from drivers.tclrpc import OpenOcdTclRpc
from .drivers.mik32_eeprom import * from drivers.mik32_eeprom import *
from .drivers.mik32_spifi import * from drivers.mik32_spifi import *
from .drivers.mik32_ram import * from drivers.mik32_ram import *
from .mik32_parsers import * from mik32_parsers import *
from .parsers.parser_hex import *
# class bcolors(Enum): # class bcolors(Enum):
@ -38,8 +37,8 @@ def test_connection():
raise Exception("ERROR: no regs found, check MCU connection") raise Exception("ERROR: no regs found, check MCU connection")
def read_file(filename: str) -> List[Tuple[int, List[int]]] : def read_file(filename: str) -> List[Record]:
segments: List[Tuple[int, List[int]]] = [] segments: List[Record] = []
lines: List[str] = [] lines: List[str] = []
file_name, file_extension = os.path.splitext(filename) 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)) raise Exception("Unsupported file format: %s" % (file_extension))
for line in lines: for line in lines:
record: Tuple[RecordType, List[int]] record: Record = parse_line(line, file_extension)
if file_extension == ".hex": print(record)
record =
return segments return segments
def get_content(filename: str) -> List[int]: def upload_file(filename: str, is_resume=True) -> 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:
""" """
Write ihex or binary file into MIK32 EEPROM or external flash memory Write ihex or binary file into MIK32 EEPROM or external flash memory
@ -87,17 +72,17 @@ def upload_file(filename: str, boot_source: str = "undefined", is_resume=True) -
TODO: Implement error handling 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): if not os.path.exists(filename):
print("ERROR: File %s does not exist" % filename) print("ERROR: File %s does not exist" % filename)
exit(1) 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) # 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: # with subprocess.Popen(cmd, shell=True, stdout=subprocess.DEVNULL) as proc:
# if boot_source == "eeprom": # if boot_source == "eeprom":
@ -113,40 +98,24 @@ def upload_file(filename: str, boot_source: str = "undefined", is_resume=True) -
# result = 1 # result = 1
# proc.kill() # proc.kill()
if boot_source == "eeprom": # if boot_source == "eeprom":
result = write_words(bytes2words(get_content(filename)), is_resume) # result = write_words(bytes2words(get_content(filename)), is_resume)
elif boot_source == "spifi": # elif boot_source == "spifi":
result = spifi_write_file(get_content(filename), is_resume) # result = spifi_write_file(get_content(filename), is_resume)
elif boot_source == "ram": # elif boot_source == "ram":
write_file(filename, is_resume) # write_file(filename, is_resume)
result = 0 # TODO # result = 0 # TODO
else: # else:
raise Exception("Unsupported boot source, use eeprom or spifi") # raise Exception("Unsupported boot source, use eeprom or spifi")
result = 1 # result = 1
return result return 1
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])
def createParser(): def createParser():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('filepath', nargs='?') parser.add_argument('filepath', nargs='?')
parser.add_argument('--show-file', action="store_const", const=True) # parser.add_argument('-b', '--boot-mode', default='undefined')
parser.add_argument('--no-upload', action="store_const", const=True)
parser.add_argument('-b', '--boot-mode', default='undefined')
return parser return parser
@ -155,10 +124,7 @@ if __name__ == '__main__':
parser = createParser() parser = createParser()
namespace = parser.parse_args() namespace = parser.parse_args()
if namespace.show_file:
show_file(namespace.filepath)
if namespace.filepath: if namespace.filepath:
if namespace.no_upload == None: upload_file(namespace.filepath)
upload_file(namespace.filepath, namespace.boot_mode)
else: else:
print("Nothing to upload") print("Nothing to upload")

View File

@ -1,3 +0,0 @@
from parsers import RecordType
def parse(str) ->

View File

@ -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