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