comparison python/hexfile.py @ 244:58155c7c4a8e

Add hexutil
author Windel Bouwman
date Wed, 24 Jul 2013 19:47:13 +0200
parents 6259856841a0
children 66912720d712
comparison
equal deleted inserted replaced
243:ef683881c64e 244:58155c7c4a8e
1 import os 1 import os
2 import struct
2 3
3 class HexFileException(Exception): 4 class HexFileException(Exception):
4 pass 5 pass
5 6
6 def parseHexLine(line): 7 def parseHexLine(line):
11 if len(nums) != bytecount + 5: 12 if len(nums) != bytecount + 5:
12 raise HexFileException('byte count field incorrect') 13 raise HexFileException('byte count field incorrect')
13 crc = sum(nums) 14 crc = sum(nums)
14 if (crc & 0xFF) != 0: 15 if (crc & 0xFF) != 0:
15 raise HexFileException('crc incorrect') 16 raise HexFileException('crc incorrect')
16 address = nums[1] * 256 + nums[2] 17 address = struct.unpack('>H', nums[1:3])[0]
17 typ = nums[3] 18 typ = nums[3]
18 data = nums[4:-1] 19 data = nums[4:-1]
19 return (address, typ, data) 20 return (address, typ, data)
20 21
22 def makeHexLine(address, typ, data=bytes()):
23 bytecount = len(data)
24 nums = bytearray()
25 nums.append(bytecount)
26 nums.extend(struct.pack('>H', address))
27 nums.append(typ)
28 nums.extend(data)
29 crc = sum(nums)
30 crc = ((~crc) + 1) & 0xFF
31 nums.append(crc)
32 line = ':' + ''.join(['{:02X}'.format(b) for b in nums])
33 return line
34
35 def chunks(data, csize=16):
36 idx = 0
37 while idx < len(data):
38 s = min(len(data) - idx, csize)
39 yield data[idx:idx+s]
40 idx += s
21 41
22 class HexFile: 42 class HexFile:
23 """ Represents an intel hexfile """ 43 """ Represents an intel hexfile """
24 def __init__(self): 44 def __init__(self):
25 self.regions = [] 45 self.regions = []
63 # After all lines: 83 # After all lines:
64 if curData: 84 if curData:
65 self.regions.append(HexFileRegion(startAddress, bytes(curData))) 85 self.regions.append(HexFileRegion(startAddress, bytes(curData)))
66 86
67 def __repr__(self): 87 def __repr__(self):
68 i = [] 88 return 'Hexfile with {} regions'.format(len(self.regions))
69 i.append(super().__repr__()) 89
70 i.append('Start address {0}'.format(hex(self.startAddress))) 90 def dump(self):
91 print(self)
71 for r in self.regions: 92 for r in self.regions:
72 i.append(str(r)) 93 print(r)
73 return os.linesep.join(i) 94
95 def __eq__(self, other):
96 regions = self.regions
97 oregions = other.regions
98 if len(regions) != len(oregions):
99 return False
100 return all(rs == ro for rs, ro in zip(regions, oregions))
101
102 def addRegion(self, address, data):
103 r = HexFileRegion(address, data)
104 # TODO: check touches
105 self.regions.append(r)
106 self.regions.sort(key=lambda r: r.address)
74 107
75 def save(self, f): 108 def save(self, f):
76 for r in self.regions: 109 for r in self.regions:
77 offset = 0 110 offset = 0
78 while offset < len(r.data): 111 for chunk in chunks(r.data):
79 f.write('a') 112 print(makeHexLine(r.address + offset, 0x0, bytes(r.data[offset:offset+16])), file=f)
80 offset += 16 113 offset += len(chunk)
81 114 print(makeHexLine(0, 0x1, bytes()), file=f)
82 115
83 class HexFileRegion: 116 class HexFileRegion:
84 def __init__(self, address, data = bytes()): 117 def __init__(self, address, data = bytes()):
85 self.address = address 118 self.address = address
86 self.data = data 119 self.data = data
87 def __repr__(self): 120
88 return 'Region at 0x{0:X} of {1} bytes'.format(self.address, len(self.data)) 121 def __repr__(self):
122 return 'Region at 0x{0:X} of {1} bytes'.format(self.address, len(self.data))
123
124 def __eq__(self, other):
125 return (self.address, self.data) == (other.address, other.data)
126
127 @property
128 def EndAddress(self):
129 return self.address + len(self.data)
89 130
90 131
91 if __name__ == '__main__': 132 if __name__ == '__main__':
92 h = HexFile() 133 h = HexFile()
93 print(h) 134 print(h)