Mercurial > lcfOS
view python/hexfile.py @ 222:c3f1ce8b638f
Fixup of parser
author | Windel Bouwman |
---|---|
date | Tue, 09 Jul 2013 17:36:31 +0200 |
parents | ed230e947dc6 |
children | d3dccf12ca88 |
line wrap: on
line source
import os class HexFileException(Exception): pass def parseHexLine(line): """ Parses a hexfile line into three parts """ line = line[1:] # Remove ':' nums = bytes.fromhex(line) bytecount = nums[0] if len(nums) != bytecount + 5: raise HexFileException('byte count field incorrect') crc = sum(nums) if (crc & 0xFF) != 0: raise HexFileException('crc incorrect') address = nums[1] * 256 + nums[2] typ = nums[3] data = nums[4:-1] return (address, typ, data) class HexFile: """ Represents an intel hexfile """ def __init__(self, filename=None): self.regions = [] self.startAddress = 0 self.filename = None if filename: self.load(filename) def load(self, filename): with open(filename, 'r') as f: endOfFile = False offset = 0 startAddress = 0 curAddress = 0 curData = bytearray() for line in f: line = line.strip() # Strip spaces and newlines if not line: continue # Skip empty lines if line[0] != ':': continue # Skip lines that do not start with a ':' if endOfFile: raise HexFileException('hexfile line after end of file record') address, typ, data = parseHexLine(line) if typ == 0x0: # Data record address += offset # Fix address with offset # Append data if address == curAddress: curData += data curAddress += len(data) else: if curData: self.regions.append(HexFileRegion(startAddress, bytes(curData))) startAddress = address curAddress = address + len(data) curData = bytearray(data) elif typ == 0x4: # Extended linear address record offset = ((data[0] << 8) + data[1]) << 16 elif typ == 0x1: # End of file record if len(data) != 0: raise HexFileException('end of file record must contain no data') endOfFile = True elif typ == 0x5: # Start address record (where IP goes after loading) self.startAddress = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3] else: raise HexFileException('record type {0} not implemented'.format(typ)) print(hex(address), typ, data) # After all lines: if curData: self.regions.append(HexFileRegion(startAddress, bytes(curData))) # Store the filename: self.filename = filename def __repr__(self): i = [] i.append(super().__repr__()) i.append('Start address {0}'.format(hex(self.startAddress))) i.append('Filename: {0}'.format(self.filename)) for r in self.regions: i.append(str(r)) return os.linesep.join(i) def save(self, filename): with open(filename, 'w') as f: for line in f: pass class HexFileRegion: def __init__(self, address, data = bytes()): self.address = address self.data = data def __repr__(self): return 'Region at 0x{0:X} of {1} bytes'.format(self.address, len(self.data)) if __name__ == '__main__': h = HexFile() print(h) """ Test hexfile implementation with some hexfile """ h1 = HexFile('audio.hex') print(h1)