1. 解析Srec文件
"""
Parse the SRecord file and return all contiguous data blocks and header record
argument:
- srec_file_path: path of srecord file to parse
return:
- title_infor: contains any title information
- data_blocks: list,Each element is a dictionary,contains 'address' and 'data'
"""
def parse_srec_fragments(srec_file_path):
with open(srec_file_path, 'r') as f:
lines = f.readlines()
f.close()
title_infor = None
data_blocks = [] # storage all data blocks [{address: int, data: bytes}, ...]
current_address = 0x00000000
next_address = None
for line in lines:
line = line.strip()
if not line.startswith('S'):
continue
if len(line) & 1 == 1:
raise ValueError(f"Invalid line, length error: {line}")
# Extract fields
record_type = int(line[1:2], 16)
byte_count = int(line[2:4], 16)
checksum = int(line[-2:], 16)
address = None
data_bytes = None
# Verify length
if len(line) != 4 + byte_count*2:
raise ValueError(f"Invalid line, length error: {line}")
# Verify checksum
computed_sum = sum(bytes.fromhex(line[2:-2])) & 0xFF
computed_checksum = 0xff - computed_sum
if checksum != computed_checksum:
raise ValueError(f"checksum error: {line}")
# Process record type
if record_type == 0x00: # S0: Header Record
if len(line) < 10:
raise ValueError(f"Invalid line, length error: {line}")
title_infor = line[8:-2]
elif (record_type == 0x01 or # S1: Data Record, 16-bit address
record_type == 0x02 or # S2: Data Record, 24-bit address
record_type == 0x03): # S3: Data Record, 32-bit address
address = int(line[4:6+record_type*2], 16)
data_bytes = bytes.fromhex(line[6+record_type*2:-2])
current_address = address
if current_address == next_address:
# Merge continuous address data together
temp = bytearray(data_blocks[-1]['data'])
temp.extend(data_bytes)
data_blocks[-1]['data'] = bytes(temp)
else:
# Start a new block
data_blocks.append({
'address': current_address,
'data': data_bytes
})
next_address = current_address + byte_count - record_type - 1 - 1
elif (record_type == 0x04): # S4: Resverd
break
elif (record_type == 0x05): # S5: Count Record, 16-bit counter
if record_type + byte_count != 8:
raise ValueError(f"Invalid line, length error: {line}")
elif (record_type == 0x06): # S6: Count Record, 24-bit counter
if record_type + byte_count != 10:
raise ValueError(f"Invalid line, length error: {line}")
elif (record_type == 0x07 or # S7: Termination Record, 16-bit address
record_type == 0x08 or # S8: Termination Record, 24-bit address
record_type == 0x09): # S9: Termination Record, 32-bit address
if record_type + byte_count != 12:
raise ValueError(f"Invalid line, length error: {line}")
else:
raise TypeError(f"Invalid record type!!!")
if len(data_blocks) != 0:
print(f"Header Record: 0x{title_infor}")
for idx, block in enumerate(data_blocks):
print(f"Block {idx + 1}:")
print(f" Starts at: 0x{block['address']:08X}")
print(f" Length : 0x{len(block['data']):0X}")
# print(f" Data : {block['data'].hex().upper()}")
else:
print("No valid data records found in SRecord files!")
return title_infor, data_blocks
2. 解析Hex文件
"""
Parse the HEX file and return all contiguous data blocks
argument:
- hex_file_path: path of hex file to parse
return:
- data_blocks: list,Each element is a dictionary,contains 'address' and 'data'
"""
def parse_hex_fragments(hex_file_path):
with open(hex_file_path, 'r') as f:
lines = f.readlines()
f.close()
data_blocks = [] # storage all data blocks [{address: int, data: bytes}, ...]
upper_address = 0x0000 # Extended linear address (Type 04)
current_segment = 0x0000 # Extended segment address (Type 02)
next_address = None
for line in lines:
line = line.strip()
if not line.startswith(':'):
continue
if len(line) < 11 or len(line) & 1 == 0:
raise ValueError(f"Invalid line, length error: {line}")
# Extract fields
byte_count = int(line[1:3], 16)
address = int(line[3:7], 16)
record_type = int(line[7:9], 16)
data_bytes = bytes.fromhex(line[9:-2])
checksum = int(line[-2:], 16)
if len(line) != 11 + byte_count*2:
raise ValueError(f"Invalid line, length error: {line}")
# Verify checksum
computed_sum = sum(bytes.fromhex(line[1:-2])) & 0xFF
computed_checksum = (0x100 - computed_sum) & 0xFF
if checksum != computed_checksum:
raise ValueError(f"checksum error: {line}")
# Process record type
if record_type == 0x00: # Data record
# Calculate full addresses (support segment addresses and linear addresses)
if upper_address != 0x0000:
full_address = (upper_address << 16) + address
else:
full_address = (current_segment << 4) + address
if full_address == next_address:
# Merge continuous address data together
temp = bytearray(data_blocks[-1]['data'])
temp.extend(data_bytes)
data_blocks[-1]['data'] = bytes(temp)
else:
# Start a new block
data_blocks.append({
'address': full_address,
'data': data_bytes
})
next_address = full_address + byte_count
elif record_type == 0x02: # Extended segment address record
current_segment = int.from_bytes(data_bytes, byteorder='big')
elif record_type == 0x04: # Extended linear address record
upper_address = int.from_bytes(data_bytes, byteorder='big')
elif record_type == 0x01: # File end record
break
if len(data_blocks) != 0:
for idx, block in enumerate(data_blocks):
print(f"Block {idx + 1}:")
print(f" Starts at: 0x{block['address']:08X}")
print(f" Length : 0x{len(block['data']):0X}")
# print(f" Data : {block['data'].hex().upper()}")
else:
print("No valid data records found in HEX files!")
return data_blocks