Clean up Intel HEX utilities

No functional change intended.
This commit is contained in:
Grigori Goronzy 2017-09-24 14:29:19 +02:00
parent ebcfeb467c
commit 8b0fdcb42a

View File

@ -5,15 +5,20 @@
import struct
import codecs
class IHex(object):
class IHex:
"""Intel HEX parser and writer"""
@classmethod
def read(cls, lines):
"""Read Intel HEX data from string or lines"""
ihex = cls()
segbase = 0
for line in lines:
line = line.strip()
if not line: continue
if not line:
continue
t, a, d = ihex.parse_line(line)
if t == 0x00:
@ -47,6 +52,7 @@ class IHex(object):
@classmethod
def read_file(cls, fname):
"""Read Intel HEX data from file"""
f = open(fname, "rb")
ihex = cls.read(f)
f.close()
@ -65,6 +71,7 @@ class IHex(object):
self.row_bytes = row_bytes
def extract_data(self, start=None, end=None):
"""Extract binary data"""
if start is None:
start = 0
@ -74,8 +81,9 @@ class IHex(object):
for addr, data in self.areas.items():
if addr >= start:
if len(result) < (addr - start):
result[len(result):addr-start] = bytes(addr-start-len(result))
result[addr-start:addr-start+len(data)] = data
result[len(result):addr - start] = bytes(
addr - start - len(result))
result[addr - start:addr - start + len(data)] = data
return bytes(result)
@ -84,10 +92,11 @@ class IHex(object):
for addr, data in self.areas.items():
if addr >= start and addr < end:
data = data[:end-addr]
data = data[:end - addr]
if len(result) < (addr - start):
result[len(result):addr-start] = bytes(addr-start-len(result))
result[addr-start:addr-start+len(data)] = data
result[len(result):addr - start] = bytes(
addr - start - len(result))
result[addr - start:addr - start + len(data)] = data
return bytes(result)
@ -115,10 +124,11 @@ class IHex(object):
else:
data = self.areas[area]
# istart - iend + len(idata) + len(data)
self.areas[area] = data[:istart-area] + idata + data[iend-area:]
self.areas[area] = data[
:istart - area] + idata + data[iend - area:]
def calc_checksum(self, bytes):
total = sum(bytes)
def calc_checksum(self, data):
total = sum(data)
return (-total) & 0xFF
def parse_line(self, rawline):
@ -126,33 +136,31 @@ class IHex(object):
raise ValueError("Invalid line start character (%r)" % rawline[0])
try:
#line = rawline[1:].decode("hex")
line = codecs.decode(rawline[1:], "hex_codec")
except:
raise ValueError("Invalid hex data")
length, addr, type = struct.unpack(">BHB", line[:4])
length, addr, line_type = struct.unpack(">BHB", line[:4])
dataend = length + 4
data = line[4:dataend]
#~ print line[dataend:dataend + 2], repr(line)
cs1 = line[dataend]
cs2 = self.calc_checksum(line[:dataend])
if cs1 != cs2:
raise ValueError("Checksums do not match")
return (type, addr, data)
return (line_type, addr, data)
def make_line(self, type, addr, data):
line = struct.pack(">BHB", len(data), addr, type)
def make_line(self, line_type, addr, data):
line = struct.pack(">BHB", len(data), addr, line_type)
line += data
line += chr(self.calc_checksum(line))
#~ return ":" + line.encode("hex")
return ":" + line.encode("hex").upper() + "\r\n"
def write(self):
"""Write Intel HEX data to string"""
output = ""
for start, data in sorted(self.areas.items()):
@ -174,7 +182,8 @@ class IHex(object):
addr = t
if newsegbase != segbase:
output += self.make_line(0x02, 0, struct.pack(">H", newsegbase))
output += self.make_line(
0x02, 0, struct.pack(">H", newsegbase))
segbase = newsegbase
elif self.mode == 32:
@ -182,7 +191,8 @@ class IHex(object):
addr = addr & 0xFFFF
if newsegbase != segbase:
output += self.make_line(0x04, 0, struct.pack(">H", newsegbase))
output += self.make_line(
0x04, 0, struct.pack(">H", newsegbase))
segbase = newsegbase
output += self.make_line(0x00, addr, chunk)
@ -192,14 +202,17 @@ class IHex(object):
if self.start is not None:
if self.mode == 16:
output += self.make_line(0x03, 0, struct.pack(">2H", self.start[0], self.start[1]))
output += self.make_line(
0x03, 0, struct.pack(">2H", self.start[0], self.start[1]))
elif self.mode == 32:
output += self.make_line(0x05, 0, struct.pack(">I", self.start))
output += self.make_line(
0x05, 0, struct.pack(">I", self.start))
output += self.make_line(0x01, 0, "")
return output
def write_file(self, fname):
"""Write Intel HEX data to file"""
f = open(fname, "w")
f.write(self.write())
f.close()