def check_fw(path): """Check that firmware is valid and return dict with binary data.""" try: intel_hex = IntelHex() with open(path, 'r') as file_handle: intel_hex.fromfile(file_handle, format='hex') bin_string = intel_hex.tobinstr() except (IntelHexError, TypeError, ValueError) as exception: _LOGGER.error(exception) return pads = len(bin_string) % 128 # 128 bytes per page for atmega328 for _ in range(128 - pads): # pad up to even 128 bytes bin_string += b'\xff' fware = { 'path': path, 'blocks': int(len(bin_string) / FIRMWARE_BLOCK_SIZE), 'crc': compute_crc(bin_string), 'data': bin_string, } return fware
def main(): args = parser.parse_args() base_hex = IntelHex() # Merge in hex files for file_name in args.hex: file_name = os.path.expanduser(file_name) new_hex_data = IntelHex() print "opening file %s" % file_name new_hex_data.fromfile(file_name, format='hex') print_hex_info(file_name, new_hex_data) base_hex = merge_hex(base_hex, new_hex_data) # Merge in binary files for file_name, addr_str in args.bin: file_name = os.path.expanduser(file_name) offset = int(addr_str, 0) new_hex_data = IntelHex() new_hex_data.loadbin(file_name, offset=offset) print_hex_info(file_name, new_hex_data) base_hex = merge_hex(base_hex, new_hex_data) # Write out data print_hex_info(os.path.expanduser(args.output_file), base_hex) with open(os.path.expanduser(args.output_file), 'wb') as output_file: base_hex.tofile(output_file, 'hex') if args.output_bin_file is not None: with open(os.path.expanduser(args.output_bin_file), 'wb') as output_file: base_hex.tofile(output_file, 'bin')
class FirmwareTool: def __init__(self, firmware, version, hexfile=None): self.ffi = FFI() try: self.schema = PRESET_SCHEMATA[firmware][version](self.ffi) except KeyError: raise NotImplementedError( "don't know how to read version {}".format(version)) else: self.ffi.cdef(self.schema.cdef()) if hexfile is not None: self.ih = IntelHex() self.ih.fromfile(hexfile, format='hex') # without this, the program will just silently exit if it # segfaults trying to read values from the CFFI object faulthandler.enable() self.nvram_data = self.ffi.new( '{} *'.format(self.schema.root_type())) nvram_buffer = self.ffi.buffer(self.nvram_data) # address from the ansible.sym symbol table nvram_dump = self.ih.tobinarray( self.schema.address(), self.schema.address() + len(nvram_buffer) - 1 ) nvram_buffer[:] = nvram_dump
def _compute_crc(hex_file_path): # Read in hex file new_hex_file = IntelHex() new_hex_file.padding = 0xFF new_hex_file.fromfile(hex_file_path, format='hex') # Get the starting and ending address addresses = new_hex_file.addresses() addresses.sort() start_end_pairs = list(_ranges(addresses)) regions = len(start_end_pairs) assert regions == 1, ("Error - only 1 region allowed in " "hex file %i found." % regions) start, end = start_end_pairs[0] # Compute checksum over the range (don't include data at location of crc) size = end - start + 1 crc_size = size - 4 data = new_hex_file.tobinarray(start=start, size=crc_size) data_crc32 = binascii.crc32(data) & 0xFFFFFFFF # Grab the crc from the image embedded_crc32 = (((new_hex_file[end - 3] & 0xFF) << 0) | ((new_hex_file[end - 2] & 0xFF) << 8) | ((new_hex_file[end - 1] & 0xFF) << 16) | ((new_hex_file[end - 0] & 0xFF) << 24)) return data_crc32, embedded_crc32
def check_only(self, name): # FIXME refactor # copy from program_file if name.lower().endswith(".json"): data = json.loads(open(name, "r").read()) fw = base64.b64decode(helpers.from_websafe(data["firmware"]).encode()) sig = base64.b64decode(helpers.from_websafe(data["signature"]).encode()) ih = IntelHex() tmp = tempfile.NamedTemporaryFile(delete=False) tmp.write(fw) tmp.seek(0) tmp.close() ih.fromfile(tmp.name, format="hex") else: if not name.lower().endswith(".hex"): print('Warning, assuming "%s" is an Intel Hex file.' % name) sig = None ih = IntelHex() ih.fromfile(name, format="hex") if sig is None: sig = b"A" * 64 if self.do_reboot: self.verify_flash(sig)
def test_write_atmega4809_eeprom_uses_hexfile_address(self): filename = "{}eeprom.hex".format(TESTFILE_FOLDER) offset = 16 numbytes = 8 info = Backend.get_device_info('atmega4809') device_memory_info = deviceinfo.DeviceMemoryInfo(info) eeprom_info = device_memory_info.memory_info_by_name( MemoryNames.EEPROM) mem_tuple = self._generate_memorytuple(numbytes, eeprom_info) write_memory_to_hex(filename, mem_tuple, offset) hexfile = IntelHex() hexfile.fromfile(filename, format='hex') segments = hexfile.segments() segment = segments[0] start = segment[0] stop = segment[1] hexadr = eeprom_info[DeviceMemoryInfoKeys.HEXFILE_ADDRESS] self.assertEqual(start, hexadr + offset, msg="Unexpected start hex address") self.assertEqual(stop, hexadr + offset + numbytes, msg="Unexpected stop hex address")
def write_flash_hex(self, flash_file): flash_hex = IntelHex() flash_hex.fromfile(flash_file, "hex") if flash_hex.maxaddr() >= self.application_size: raise KpBoot32u4Error( "Hex file doesn't fit in flash. Maximum flash address is {}, but" " the given file writes to address {}.".format( self.application_size, flash_hex.maxaddr(), )) segments = flash_hex.segments() # checks if a given page is a part of any of the segments in the hex # file def is_page_used(p_start, p_end): for (seg_start, seg_end) in segments: if seg_start <= p_start < seg_end: return True if seg_start <= p_end < seg_end: return True return False # flash is only page accessible, so look at each page in the hex file # and see if it needs to be written for start in range(0, self.application_size, self.page_size): end = start + self.page_size if not is_page_used(start, end): continue # Get the data for the current page and write it data = bytearray(flash_hex.tobinstr(start, end - 1)) self.write_flash_page(start, data)
def read_memories_from_hex(filename, device_memory_info): """ Read the content of a hexfile :param filename: Name/path of hex file to read from :param device_memory_info: DeviceMemoryInfo instance for the device the hex file is intended for :returns: list of namedtuples with three fields: data, offset and memory_info. data contains a byte array of raw data bytes, offset is the start address within the memory the data starts at and memory_info is a dictionary with the memory info as defined in pymcuprog.deviceinfo.deviceinfo """ hexfile = IntelHex() hexfile.fromfile(filename, format='hex') memory_segments = [] for segment in hexfile.segments(): start = segment[0] stop = segment[1] subsegment_start = start subsegment_stop = start while subsegment_stop < stop: current_memory_info = device_memory_info.memory_info_by_address( subsegment_start, DeviceMemoryInfoKeys.HEXFILE_ADDRESS, DeviceMemoryInfoKeys.HEXFILE_SIZE) if current_memory_info is None: raise IndexError( "Hexfile contains data at hex address 0x{:X} which is outside any memory" .format(subsegment_start)) current_hexfile_address = current_memory_info[ DeviceMemoryInfoKeys.HEXFILE_ADDRESS] current_hexfile_size = current_memory_info[ DeviceMemoryInfoKeys.HEXFILE_SIZE] subsegment_stop = current_hexfile_address + current_hexfile_size if stop < subsegment_stop: # Reached end of segment subsegment_stop = stop memory_tuple = namedtuple('MemorySegment', 'data offset memory_info') data = hexfile.tobinarray(start=subsegment_start, end=subsegment_stop - 1) current_size = current_memory_info[DeviceMemoryInfoKeys.SIZE] if current_hexfile_size == current_size * 2: # There are phantom bytes in the hexfile (PIC16 EEPROM), so every 2nd byte should be removed data = remove_phantom_bytes(data) memory_tuple.data = data memory_tuple.memory_info = current_memory_info memory_tuple.offset = subsegment_start - current_hexfile_address memory_segments.append(copy.deepcopy(memory_tuple)) subsegment_start = subsegment_stop return memory_segments
def _loadhex(self, fw: Union[str, IO]) -> None: ih = IntelHex() ih.fromfile(fw, format='hex') self.fw = bytearray(ih.tobinstr()) if self.base is None: self.base = ih.minaddr() else: if self.base != ih.minaddr(): raise ValueError('inconsistent base address')
def main(): try: os.remove(RESULT) except OSError: pass ihx = IntelHex() ihx.fromfile(TARGET, format='hex') addr_min, addr_max = ihx.minaddr(), ihx.maxaddr() print hex(addr_min), hex(addr_max) ihx.tofile(TEST, format='hex') d = Disassembler() function = ihx.tobinarray()[FUNC_START:] blocks = d.parse(function, 0, FUNC_START) for b in blocks: print '-' * 40 print repr(b) print '-' * 40 blocks = sum(blocks) data = blocks.assemble(FUNC_START, externalize_labels=True) print 'Stream:', ' '.join('%02x' % b for b in bytearray(data)) data_length = len(data) print 'Writing %d bytes.' % data_length ihx.puts(FUNC_START, data) appendix = Block() label_nops = Label('look_mah_no_ops') appendix += Block(label_nops, nop, nop, nop, nop) appendix += Block(Data('\xef\xbe')) appendix += Block(Data(0xbeef)) appendix += Block(Data(label_nops)) end = ihx.maxaddr() + 1 data = appendix.assemble(end, externalize_labels=True) data_length = len(data) print 'Writing %d bytes.' % data_length ihx.puts(end, data) ihx.tofile(RESULT, format='hex') patched = IntelHex() patched.fromfile(RESULT, format='hex') check = ihx.tobinarray()[FUNC_START:FUNC_START + data_length] print 'Stream:', ' '.join('%02x' % b for b in bytearray(data)) print hex(patched.minaddr()), hex(patched.maxaddr())
def write_eeprom_hex(self, eep_file): eep_hex = IntelHex() eep_hex.fromfile(eep_file, "hex") segments = eep_hex.segments() # eeprom is byte addressable, so write all the bytes in each segment for (start, end) in segments: data = bytearray(eep_hex.tobinstr(start, end - 1)) self.write_eeprom(start, data)
def from_hex(self, filename, offset): ih = IntelHex() ih.fromfile(filename, format='hex') self.__cycles_number = ih[offset] * 256 + ih[offset + 1] cmd_number = ih[offset + 2] offset += 3 self.__commands = [] for i in range(0, cmd_number): (cmd, offset) = self.__hex_to_cmd(ih, offset) self.__commands.append(cmd)
def test_write_and_read_eeprom_pic16f18446(self): """ This test exercises the write_memory_to_hex function (single segment) """ filename = "{}eeprom.hex".format(TESTFILE_FOLDER) offset = 0 info = Backend.get_device_info('pic16f18446') device_memory_info = deviceinfo.DeviceMemoryInfo(info) eeprom_info = device_memory_info.memory_info_by_name( MemoryNames.EEPROM) numbytes_eeprom = eeprom_info[DeviceMemoryInfoKeys.SIZE] mem_tuple_eeprom = self._generate_memorytuple(numbytes_eeprom, eeprom_info) write_memory_to_hex(filename, mem_tuple_eeprom, offset) segments_read = read_memories_from_hex(filename, device_memory_info) for segment_read in segments_read: memory_name = segment_read.memory_info[DeviceMemoryInfoKeys.NAME] # When writing multiple segments all will start from relative offset 0 self.assertEqual(segment_read.offset, offset, msg="Incorrect offset for {}".format(memory_name)) if memory_name == MemoryNames.EEPROM: self.assertEqual(segment_read.data, mem_tuple_eeprom.data, msg="Incorrect EEPROM data") else: self.fail("Unexpected memory: {}".format(memory_name)) # Sanity check to see that the phantom bytes actually were added by the write to hex hexfile = IntelHex() hexfile.fromfile(filename, format='hex') hexadr = eeprom_info[DeviceMemoryInfoKeys.HEXFILE_ADDRESS] data_read = hexfile.tobinarray(start=hexadr, end=hexadr + numbytes_eeprom * 2 - 1) self.assertEqual( len(data_read), numbytes_eeprom * 2, msg= "EEPROM should include twice as many bytes as was written due to the phantom bytes" ) index = 0 for index in range(numbytes_eeprom): self.assertEqual( data_read[index * 2], mem_tuple_eeprom.data[index], msg="Incorrect EEROM data in written hex at index {}".format( index * 2)) self.assertEqual( data_read[index * 2 + 1], 0x00, msg="Incorrect phantom byte in written hex at index {}".format( index * 2 + 1))
def to_eep_file(self, eep_file_name): """Save the configuration to an EEPROM-file.""" hex_file = IntelHex() # Change any existing files instead of overwriting them. if os.path.isfile(eep_file_name): hex_file.fromfile(eep_file_name, format='hex') data = self.to_bytes(crc=True) hex_file.puts(Config.START_ADDRESS, data) hex_file.write_hex_file(eep_file_name, byte_count=0x20)
def sign_firmware_for_version(sk_name, hex_file, APPLICATION_END_PAGE, PAGES=128): # Maybe this is not the optimal module... import base64 import binascii from hashlib import sha256 from ecdsa import SigningKey from intelhex import IntelHex sk = SigningKey.from_pem(open(sk_name).read()) fw = open(hex_file, "r").read() fw = base64.b64encode(fw.encode()) fw = helpers.to_websafe(fw.decode()) ih = IntelHex() ih.fromfile(hex_file, format="hex") # start of firmware and the size of the flash region allocated for it. # TODO put this somewhere else. START = ih.segments()[0][0] # keep in sync with targets/stm32l432/src/memory_layout.h PAGE_SIZE = 2048 END = (0x08000000 + ((PAGES - APPLICATION_END_PAGE) * PAGE_SIZE)) - 8 ih = IntelHex(hex_file) # segs = ih.segments() arr = ih.tobinarray(start=START, size=END - START) im_size = END - START print("im_size: ", im_size) print("firmware_size: ", len(arr)) byts = (arr).tobytes() if hasattr(arr, "tobytes") else (arr).tostring() h = sha256() h.update(byts) sig = binascii.unhexlify(h.hexdigest()) print("hash", binascii.hexlify(sig)) sig = sk.sign_digest(sig) print("sig", binascii.hexlify(sig)) sig = base64.b64encode(sig) sig = helpers.to_websafe(sig.decode()) # msg = {'data': read()} msg = {"firmware": fw, "signature": sig} return msg
def from_eep_file(cls, eep_file_name): """Create an ErrorLog instance with the content from the EEPROM-file.""" hex_file = IntelHex() hex_file.fromfile(eep_file_name, format='hex') log = cls() for addr in range(ErrorLog._START_ADDRESS, ErrorLog._END_ADDRESS, ErrorMessage.size()): data = hex_file.gets(addr, ErrorMessage.size()) error_message = ErrorMessage.from_bytes(data) if error_message: log.append(error_message) return log
def program_file(self, name): if name.lower().endswith(".json"): data = json.loads(open(name, "r").read()) fw = base64.b64decode( helpers.from_websafe(data["firmware"]).encode()) sig = base64.b64decode( helpers.from_websafe(data["signature"]).encode()) ih = IntelHex() tmp = tempfile.NamedTemporaryFile(delete=False) tmp.write(fw) tmp.seek(0) tmp.close() ih.fromfile(tmp.name, format="hex") else: if not name.lower().endswith(".hex"): print('Warning, assuming "%s" is an Intel Hex file.' % name) sig = None ih = IntelHex() ih.fromfile(name, format="hex") if self.exchange == self.exchange_hid: chunk = 2048 else: chunk = 240 seg = ih.segments()[0] size = seg[1] - seg[0] total = 0 t1 = time.time() * 1000 print("erasing firmware...") for i in range(seg[0], seg[1], chunk): s = i e = min(i + chunk, seg[1]) data = ih.tobinarray(start=i, size=e - s) self.write_flash(i, data) total += chunk progress = total / float(size) * 100 sys.stdout.write("updating firmware %.2f%%...\r" % progress) sys.stdout.write("updated firmware 100% \r\n") t2 = time.time() * 1000 print("time: %.2f s" % ((t2 - t1) / 1000.0)) if sig is None: sig = b"A" * 64 if self.do_reboot: self.verify_flash(sig) return sig
def LoadHex(file): try: # Load the hex file ih=IntelHex() ih.fromfile(file,format='hex') bf = ih.tobinarray() #convert to bin array except ValueError: print(f'Error {ValueError} in LoadHex function with argument : {file}') CleanExit() return bf
class IHexFile: def __init__(self): self.ihex = IntelHex() self.fileName = "None Loaded" self.fileLoaded = False self.faultList = {} def loadFromFile(self, infilename): self.ihex.fromfile(infilename, format='hex') self.fileName = infilename self.fileLoaded = True self.minAddress = self.ihex.minaddr() self.maxAddress = self.ihex.maxaddr() return "OK" def writeToFile(self, outfilename): if not self.fileLoaded: return "No File Loaded" else: self.ihex.write_hex_file(outfilename) return "OK" def writeHexDump(self, fname): if not self.fileLoaded: return "No File Loaded" else: f = open(fname, 'w') self.ihex.dump(f) f.close() return "Wrote " + fname def faultInjection(self, address, value): if not self.fileLoaded: return "No Hex File Loaded" elif address > self.maxAddress or address < self.minAddress: return "Address out of Range" else: self.ihex[address] = value self.ihex[address + 1] = value self.faultList[address] = value #How to handle Low and High Byte!!! return "OK" def viewFaults(self): if not self.fileLoaded: return "No Hex File Loaded" else: return self.faultList
def program_file(self, name): if name.lower().endswith('.json'): data = json.loads(open(name, 'r').read()) fw = base64.b64decode(from_websafe(data['firmware']).encode()) sig = base64.b64decode(from_websafe(data['signature']).encode()) ih = IntelHex() tmp = tempfile.NamedTemporaryFile(delete=False) tmp.write(fw) tmp.seek(0) tmp.close() ih.fromfile(tmp.name, format='hex') else: if not name.lower().endswith('.hex'): print('Warning, assuming "%s" is an Intel Hex file.' % name) sig = None ih = IntelHex() ih.fromfile(name, format='hex') if self.exchange == self.exchange_hid: chunk = 2048 else: chunk = 240 seg = ih.segments()[0] size = seg[1] - seg[0] total = 0 t1 = time.time() * 1000 print('erasing...') for i in range(seg[0], seg[1], chunk): s = i e = min(i + chunk, seg[1]) data = ih.tobinarray(start=i, size=e - s) self.write_flash(i, data) total += chunk progress = total / float(size) * 100 sys.stdout.write('downloading %.2f%%...\r' % progress) sys.stdout.write('downloaded 100% \r\n') t2 = time.time() * 1000 print('time: %.2f s' % ((t2 - t1) / 1000.0)) print('Verifying...') if self.do_reboot: if sig is not None: self.verify_flash(sig) else: self.verify_flash(b'A' * 64)
def load_fw(path): """Open firmware file and return a binary string.""" fname = os.path.realpath(path) exists = os.path.isfile(fname) if not exists or not os.access(fname, os.R_OK): _LOGGER.error('Firmware path %s does not exist or is not readable', path) return None try: intel_hex = IntelHex() with open(path, 'r') as file_handle: intel_hex.fromfile(file_handle, format='hex') return intel_hex.tobinstr() except (IntelHexError, TypeError, ValueError) as exc: _LOGGER.error('Firmware not valid, check the hex file at %s: %s', path, exc) return None
def combine(bootloader_fn, app_fn, app_addr, hdr_addr, bootloader_addr, output_fn, version, no_bootloader): # read bootloader bootloader_format = bootloader_fn.split('.')[-1] bootloader = IntelHex() if not no_bootloader: if bootloader_format == 'hex': bootloader.fromfile(bootloader_fn, bootloader_format) elif bootloader_format == 'bin': bootloader.loadbin(bootloader_fn, bootloader_addr) else: print('Bootloader format can only be .bin or .hex') exit(-1) # read application app_format = app_fn.split('.')[-1] app = IntelHex() if app_format == 'hex': app.fromfile(app_fn, app_format) elif app_format == 'bin': app.loadbin(app_fn, app_addr) else: print('Application format can only be .bin or .hex') exit(-1) # create firmware header header = IntelHex() fw_header = create_header(app.tobinstr(), version) header.puts(hdr_addr, fw_header) # combine output_format = output_fn.split('.')[-1] output = IntelHex() if not no_bootloader: print("Writing bootloader to address 0x%08x-0x%08x." % (bootloader.addresses()[0], bootloader.addresses()[-1])) output.merge(bootloader, overlap='error') print("Writing header to address 0x%08x-0x%08x." % (header.addresses()[0], header.addresses()[-1])) output.merge(header, overlap='error') print("Writing application to address 0x%08x-0x%08x." % (app.addresses()[0], app.addresses()[-1])) output.merge(app, overlap='error') # write output file output.tofile(output_fn, format=output_format)
def dump_sections(args): ''' Find all sections in the image file and dump their name and offset ''' try: hexfile = IntelHex() hexfile.fromfile(args.image_file[0], format='hex') content = hexfile.tobinarray() except HexRecordError: # Not a valid HEX file, so assume we are dealing with a binary image args.image_file[0].seek(0) content = args.image_file[0].read(MAX_FILE_SIZE + 1) if len(content) > MAX_FILE_SIZE: print('ERROR: Binary image file larger than 16 kBytes') sys.exit(1) available_sections = dict() for section_name in SECTIONS.values(): available_sections[section_name] = 0 error_found = False section_name, version, offset = find_section(content, 0) while section_name is not None: try: available_sections[section_name] += 1 if args.verbose: print('Found "{:s}", version {:d} at offset 0x{:x}'.format( section_name, version, offset)) except KeyError: print('ERROR: Unknown section {}'.format(section_name)) error_found = True section_name, version, offset = find_section(content, offset + 1) for section_name in available_sections: if available_sections[section_name] == 0: error_found = True print('ERROR: Section "{}" is missing'.format(section_name)) elif available_sections[section_name] > 1: error_found = True print('ERROR: Multiple "{}" sections found'.format(section_name)) if error_found: sys.exit(1)
def slurp(self, filename): if filename.endswith('.bit') or filename.endswith('.bin'): with open(filename, 'rb') as f: return f.read() elif filename.endswith('.hex'): with open(filename, 'rb') as f: return bytes("".join(chr(int(i, 16)) for i in f.read().split())) elif filename.endswith('.mcs'): ih = IntelHex() ih.fromfile(filename, format='hex') bitstream = ih.tobinstr(start=0, end=ih.maxaddr()) bitstream = _mirror_each_byte(bitstream) return bitstream else: raise ValueError('Unknown bitstream extension')
def from_eep_file(cls, eep_file_name): """Create an Config instance with data from an EEPROM-file.""" hex_file = IntelHex() hex_file.fromfile(eep_file_name, format='hex') data = hex_file.gets(Config.START_ADDRESS, Config.size()) parameters = struct.unpack(Config._FMT_CRC, data) stored_crc = parameters[-1] # Remove the two last bytes to exclude the stored CRC value from the # CRC calculation. calculated_crc = Config.calculate_crc(data[:-2]) if stored_crc != calculated_crc: raise ConfigCrcException('CRC mismatch') # Remove last element with the stored CRC since it's only used for # validation. return cls(*parameters[:-1])
def read_image_file(image_file): ''' Read the given image file. First we try to read the file as Intel-hex, if that fails we assume it is a binary image. The file handle is closed before returning the IntelHex object containing the image data. ''' hexfile = IntelHex() try: hexfile.fromfile(image_file, format='hex') except HexRecordError: # Not a valid HEX file, so assume we are dealing with a binary image image_file.seek(0) hexfile.fromfile(image_file, format='bin') image_file.close() return hexfile
def GetHexCrc(file): # convert hex to bin ih = IntelHex() ih.fromfile(file, format='hex') bf = ih.tobinarray() #pad the array (flash size) for CRC calculation 220kb while len(bf) < (220 * 1024): bf.append(255) # calculate checksum for APP_HEX crc32_func = crcmod.mkCrcFun(int(0x104c11db7), initCrc=int(0xffffffff), rev=False, xorOut=0) checksum_val = crc32_func(bytearray(bf)) checksum_val = f'0x{checksum_val:X}' return checksum_val
class RomMemory: """docstring for RomMemory""" pagesize = 256 numpages = 128 size = pagesize * numpages def __init__(self): self.rom = IntelHex() self.size = 0 def OpenHex(self, filename): self.rom = IntelHex() try: self.rom.fromfile(filename, format='hex') except: return None self.size = len(self.rom.tobinarray()) return True def OpenBin(self, filename): self.rom = IntelHex() try: self.rom = fromfile(filename, format='bin') except: return None self.size = len(self.rom.tobinarray()) return True def Print(self): self.rom.dump() def ReadPage(self, numpage): return self.rom.tobinarray(start=numpage * self.pagesize, size=self.pagesize) def ReadBytes(self, address, count): return self.rom.tobinarray(start=address, size=count)
def combine(bootloader_fn, app_fn, app_addr, hdr_addr, bootloader_addr, output_fn, version, no_bootloader): ih = IntelHex() bootloader_format = bootloader_fn.split('.')[-1] # write the bootloader if not no_bootloader: print("Using bootloader %s" % bootloader_fn) if bootloader_format == 'hex': print("Loading bootloader from hex file.") ih.fromfile(bootloader_fn, format=bootloader_format) elif bootloader_format == 'bin': print("Loading bootloader to address 0x%08x." % bootloader_addr) ih.loadbin(bootloader_fn, offset=bootloader_addr) else: print('Bootloader format can only be .bin or .hex') exit(-1) # write firmware header app_format = app_fn.split('.')[-1] if app_format == 'bin': with open(app_fn, 'rb') as fd: app_blob = fd.read() elif app_format == 'hex': application = IntelHex(app_fn) app_blob = application.tobinstr() FirmwareHeader = create_header(app_blob, version) print("Writing header to address 0x%08x." % hdr_addr) ih.puts(hdr_addr, FirmwareHeader) # write the application if app_format == 'bin': print("Loading application to address 0x%08x." % app_addr) ih.loadbin(app_fn, offset=app_addr) elif app_format == 'hex': print("Loading application from hex file") ih.fromfile(app_fn, format=app_format) # output to file ih.tofile(output_fn, format=output_fn.split('.')[-1])
def main(): args = parser.parse_args() base_hex = IntelHex() # Merge in hex files for file_name in args.hex: new_hex_data = IntelHex() print "opening file %s" % file_name new_hex_data.fromfile(file_name, format='hex') print_hex_info(file_name, new_hex_data) base_hex = merge_hex(base_hex, new_hex_data) # Merge in binary files for file_name, addr_str in args.bin: offset = int(addr_str, 0) new_hex_data = IntelHex() new_hex_data.loadbin(file_name, offset=offset) print_hex_info(file_name, new_hex_data) base_hex = merge_hex(base_hex, new_hex_data) # Write out data print_hex_info(args.output_file, base_hex) with open(args.output_file, 'wb') as output_file: base_hex.tofile(output_file, 'hex')
def _download(self, addr, filename): """Downloads a binary file to the target system Args: addr: Start address where the binary file is stored filename: File name of the binary file """ import platform if platform.architecture()[0] == '64bit': filenamebuf = c_char_p(filename.encode('UTF-8')) c_addr = c_uint32(addr) self.jl.JLINK_DownloadFile(filenamebuf, c_addr) else: from intelhex import IntelHex ih = IntelHex() extension = os.path.splitext(filename)[1][1:] ih.fromfile(filename,format=extension) for (a, d) in zip(ih.addresses(), ih.tobinarray()): self.wr_mem(8, addr+a, d)
def get_firmware_object(sk_name, hex_file): from ecdsa import SigningKey, NIST256p sk = SigningKey.from_pem(open(sk_name).read()) fw = open(hex_file, "r").read() fw = base64.b64encode(fw.encode()) fw = to_websafe(fw.decode()) ih = IntelHex() ih.fromfile(hex_file, format="hex") # start of firmware and the size of the flash region allocated for it. # TODO put this somewhere else. START = ih.segments()[0][0] END = (0x08000000 + ((128 - 19) * 2048)) - 8 ih = IntelHex(hex_file) segs = ih.segments() arr = ih.tobinarray(start=START, size=END - START) im_size = END - START print("im_size: ", im_size) print("firmware_size: ", len(arr)) byts = (arr).tobytes() if hasattr(arr, "tobytes") else (arr).tostring() h = sha256() h.update(byts) sig = binascii.unhexlify(h.hexdigest()) print("hash", binascii.hexlify(sig)) sig = sk.sign_digest(sig) print("sig", binascii.hexlify(sig)) sig = base64.b64encode(sig) sig = to_websafe(sig.decode()) # msg = {'data': read()} msg = {"firmware": fw, "signature": sig} return msg
def main(): parser = argparse.ArgumentParser() parser.add_argument("--scan", help="Scans for Bluetooth low energy devices", action="store_true") parser.add_argument( "--device", help="Connects to given bluetooth device and give OTA information") parser.add_argument( "--program", help= "Writes firmware image onto device. Due to erase procedure, you might get" + "an error on a non-empty device and have to try the same command a second time." ) args = parser.parse_args() ota_service = None if args.scan: scanner = Scanner() devices = scanner.scan(5.0) for dev in devices: print("Device %s (%s), RSSI=%d dB, connectable=%r" % (dev.addr, dev.addrType, dev.rssi, dev.connectable)) for (adtype, desc, value) in dev.getScanData(): print(" %s = %s" % (desc, value)) if args.device: peripheral = Peripheral(args.device, ADDR_TYPE_RANDOM) ota_service = Ota(peripheral) if args.device and args.program: ih = IntelHex() ih.fromfile(args.program, format='hex') ota_service.program(ih)
s += "WIDTH = %d;\n" % data_width s += "ADDRESS_RADIX = %s;\n" % addr_radix s += "DATA_RADIX = %s;\n" % data_radix return s def mif_data(data={}, minaddr=MIN_ADDR, maxaddr=MAX_ADDR, gap_fill=GAP_FILL): s = "CONTENT\n" s += "BEGIN\n" s += "[%x..%x] : %x;\n" % (minaddr, maxaddr - 1, gap_fill) for k in data.keys(): if isinstance(k, Number): s += "%x : %x;\n" % (k, data[k]) s += "END;\n" return s if __name__ == "__main__": ih = IntelHex() ih.fromfile(sys.stdin, format="hex") data = ih.todict() for a in range(0, 4096, 4): if data.has_key(a): d = data[a] + (data[a + 1] << 8) + (data[a + 2] << 16) + (data[a + 3] << 24) del data[a], data[a + 1], data[a + 2], data[a + 3] data[a] = d print mif_header(32, 0, 4096) print mif_data(data, 0, 4096, 0x00000013)
filename = name + ".hex" if not exists(filename): print "Error: You must specify a filename.\n" showUsage() # Set up the device interface mb = Microboot() info = mb.getDeviceInfo(device) if info is None: print "Unsupported device type '%s'." % device exit(1) # Set up logging if requested if g_logFile is not None: mb.logger = logFunction # Load the HEX file hexfile = IntelHex() hexfile.fromfile(filename, format='hex') if device == "attiny85": # Adjust the code to move the RESET vector hexfile = adjustStartup(info, hexfile) # Set up for the write start = hexfile.minaddr() length = (hexfile.maxaddr() - start) + 1 data = list() for index in range(length): data.append(hexfile[start + index]) print "Writing %d bytes (%04X:%04X) from file '%s'." % (length, start, start + length - 1, filename) print "Target is a '%s' on port '%s'." % (device, port) # Write the data try: mb.connect(device, port) except Exception, ex:
def sendblock(command,payload): if len(payload)!=16: raise Exception('Payload length incorrect') magicnumber=0x59 checksum=(magicnumber-(sum(payload)+command))&0xff ser.write(payload) ser.write([checksum]) ser.write([command]) ser=serial.Serial('com6',57600,timeout=0.1) ih=IntelHex() ih.fromfile('Blinky104.hex',format='hex') while True: try: print("Connecting...") """ send dummy packet to sync RX/TX """ sendblock(0x00,[1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8]) ser.timeout=0.05 ackdat=ser.read(1) if len(ackdat)==1: print("\t",ackdat) else: print("timeout") continue