Mercurial > lcfOS
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) |