gnuk/tool/intel_hex.py

95 lines
3.0 KiB
Python
Raw Normal View History

2010-11-02 03:05:18 +00:00
"""
intel_hex.py - Intel Hex file reader.
Copyright (C) 2010 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org>
You can use/distribute/modify/etc. this for any purpose.
"""
2010-11-01 09:14:10 +00:00
import binascii
2012-06-19 01:19:26 +00:00
class intel_hex(object):
2010-11-01 09:14:10 +00:00
def __init__(self, filename):
self.start_address = 0
self.address = 0
self.memory = {}
self.lineno = 0
file = open(filename, 'r')
for line in file:
self.lineno += 1
if self.parse_line(line):
break
file.close()
self.pack()
def pack(self):
memory = {}
prev_addr = 0
prev_data_len = 0
for addr in sorted(self.memory.keys()):
data = self.memory[addr]
if addr == prev_addr + prev_data_len:
memory[prev_addr] += data
prev_data_len += len(data)
else:
memory[addr] = data
prev_addr = addr
prev_data_len = len(data)
2015-08-03 10:22:02 +00:00
self.memory = memory
2010-11-01 09:14:10 +00:00
def calc_checksum(self, byte_count, offset, type_code, data):
s = byte_count
s += (offset >> 8)
s += offset & 0xff
s += type_code
for d in data:
s += (ord(d) & 0xff)
s &= 0xff
if s != 0:
s = 256 - s
return s
def add_data(self, count, offset, data):
address = self.address + offset
try:
self.memory[address]
except:
pass
else:
2015-08-03 10:22:02 +00:00
raise ValueError("data overwritten (%d)" % self.lineno)
2010-11-01 09:14:10 +00:00
self.memory[address] = data
def parse_line(self, line):
if line[0] != ':':
2015-08-03 10:22:02 +00:00
raise ValueError("invalid line (%d)" % self.lineno)
2010-11-01 09:14:10 +00:00
count = int(line[1:3], 16)
offset = int(line[3:7], 16)
type_code = int(line[7:9], 16)
data = binascii.unhexlify(line[9:(9+count*2)])
check_sum = int(line[(9+count*2):], 16)
if check_sum != self.calc_checksum(count, offset, type_code, data):
2015-08-03 10:22:02 +00:00
raise ValueError("invalid checksum (%d)" % self.lineno)
2010-11-01 09:14:10 +00:00
if type_code == 0x00:
self.add_data(count, offset, data)
return 0
elif type_code == 0x01:
return 1
elif type_code == 0x04:
if count != 2:
2015-08-03 10:22:02 +00:00
raise ValueError("invalid count (%d): (%d) Expected 2" \
% (self.lineno, count))
2010-11-01 09:14:10 +00:00
self.address = ((ord(data[0])&0xff)<<24) + ((ord(data[1])&0xff)<<16)
return 0
elif type_code == 0x05:
if count != 4:
2015-08-03 10:22:02 +00:00
raise ValueError("invalid count (%d): (%d) Expected 4" \
% (self.lineno, count))
2010-11-01 09:14:10 +00:00
self.start_address \
= ((ord(data[0])&0xff)<<24) + ((ord(data[1])&0xff)<<16) \
+ ((ord(data[2])&0xff)<<8) + ((ord(data[3])&0xff))
return 0
else:
2015-08-03 10:22:02 +00:00
raise ValueError("invalid type code (%d): (%d)" \
% (self.lineno, type_code))