def save_image(self, path): if self.data_buffer: if path.lower().endswith(".bin"): with open(path, "wb") as f: f.write(self.data_buffer) f.close() elif path.lower().endswith(".hex"): ihex = IntelHex() ihex.frombytes(self.data_buffer, 0) ihex.start_addr = self.FlashStartAddress try: ihex.tofile(path, format="hex") except Exception as e: wx.MessageBox( "Could not write into file: %s\n\n%s" % (path, str(e)), "ERROR", wx.OK | wx.ICON_ERROR ) elif path.lower().endswith((".s19", ".srec")): srec = SRecFile() srec.header = "KBOOT" srec.start_addr = self.FlashStartAddress srec.data = self.data_buffer try: srec.save(path) except Exception as e: wx.MessageBox( "Could not write into file: %s\n\n%s" % (path, str(e)), "ERROR", wx.OK | wx.ICON_ERROR ) else: wx.MessageBox("Not supported file Type !", "ERROR", wx.OK | wx.ICON_ERROR) else: wx.MessageBox("No data to save", "INFO", wx.OK | wx.ICON_INFORMATION)
def append_validation_data(signature, input_file, public_key, offset, output_hex, output_bin, magic_value): ih = IntelHex(input_file) ih.start_addr = None # OBJCOPY incorrectly inserts x86 specific records, remove the start_addr as it is wrong. minimum_offset = ((ih.maxaddr() // 4) + 1) * 4 if offset != 0 and offset < minimum_offset: raise RuntimeError( f'Incorrect offset, must be bigger than {hex(minimum_offset)}') # Parse comma-separated string of uint32s into hex string. Each is encoded in little-endian byte order parsed_magic_value = b''.join( [struct.pack('<I', int(m, 0)) for m in magic_value.split(',')]) validation_data = get_validation_data(signature_bytes=signature, input_hex=ih, public_key=public_key, magic_value=parsed_magic_value) validation_data_hex = IntelHex() # If no offset is given, append metadata right after input hex file (word aligned). if offset == 0: offset = minimum_offset validation_data_hex.frombytes(validation_data, offset) ih.merge(validation_data_hex) ih.write_hex_file(output_hex) if output_bin: ih.tofile(output_bin.name, format='bin')
def sign_and_append_validation_data(pem_file, input_file, offset, output_file, magic_value, pk_hash_len): ih = IntelHex(input_file) ih.start_addr = None # OBJCOPY incorrectly inserts x86 specific records, remove the start_addr as it is wrong. minimum_offset = ((ih.maxaddr() // 4) + 1) * 4 if offset != 0 and offset < minimum_offset: raise RuntimeError("Incorrect offset, must be bigger than %x" % minimum_offset) # Parse comma-separated string of uint32s into hex string. Each in is encoded # in little-endian byte order parsed_magic_value = b''.join( [struct.pack("<I", int(m, 0)) for m in magic_value.split(",")]) validation_data = get_validation_data(pem_file=pem_file, input_hex=ih, magic_value=parsed_magic_value, pk_hash_len=pk_hash_len) validation_data_hex = IntelHex() # If no offset is given, append metadata right after input hex file (word aligned). if offset == 0: offset = minimum_offset validation_data_hex.frombytes(validation_data, offset) ih.merge(validation_data_hex) ih.write_hex_file(output_file)
def generate_provision_hex_file(s0_address, s1_address, hashes, provision_address, output, max_size, num_counter_slots_version): # Add addresses provision_data = struct.pack('III', s0_address, s1_address, len(hashes)) for mhash in hashes: provision_data += struct.pack('I', 0xFFFFFFFF) # Invalidation token provision_data += mhash num_counters = 1 if num_counter_slots_version > 0 else 0 provision_data += struct.pack('H', 1) # Type "counter collection" provision_data += struct.pack('H', num_counters) if num_counters == 1: if num_counter_slots_version % 2 == 1: num_counter_slots_version += 1 print( f'Monotonic counter slots rounded up to {num_counter_slots_version}' ) provision_data += struct.pack('H', 1) # counter description provision_data += struct.pack('H', num_counter_slots_version) assert (len(provision_data) + (2 * num_counter_slots_version) ) <= max_size, """Provisioning data doesn't fit. Reduce the number of public keys or counter slots and try again.""" ih = IntelHex() ih.frombytes(provision_data, offset=provision_address) ih.write_hex_file(output)
def save(self, path, hex_addr=None): """Save an image from a given file""" ext = os.path.splitext(path)[1][1:].lower() if ext == INTEL_HEX_EXT: # input was in binary format, but HEX needs to know the base addr if self.base_addr is None and hex_addr is None: raise click.UsageError("No address exists in input file " "neither was it provided by user") h = IntelHex() if hex_addr is not None: self.base_addr = hex_addr h.frombytes(bytes=self.payload, offset=self.base_addr) if self.pad: trailer_size = self._trailer_size(self.align, self.max_sectors, self.overwrite_only, self.enckey, self.save_enctlv, self.enctlv_len) trailer_addr = (self.base_addr + self.slot_size) - trailer_size padding = bytes([self.erased_val] * (trailer_size - len(boot_magic))) + boot_magic h.puts(trailer_addr, padding) h.tofile(path, 'hex') else: if self.pad: self.pad_to(self.slot_size) with open(path, 'wb') as f: f.write(self.payload)
def save_image(self, path): if self.data_buffer: if path.lower().endswith('.bin'): with open(path, "wb") as f: f.write(self.data_buffer) f.close() elif path.lower().endswith('.hex'): ihex = IntelHex() ihex.frombytes(self.data_buffer, 0) ihex.start_addr = self.FlashStartAddress try: ihex.tofile(path, format='hex') except Exception as e: wx.MessageBox( "Could not write into file: %s\n\n%s" % (path, str(e)), 'ERROR', wx.OK | wx.ICON_ERROR) elif path.lower().endswith(('.s19', '.srec')): srec = SRecFile() srec.header = "KBOOT" srec.start_addr = self.FlashStartAddress srec.data = self.data_buffer try: srec.save(path) except Exception as e: wx.MessageBox( "Could not write into file: %s\n\n%s" % (path, str(e)), 'ERROR', wx.OK | wx.ICON_ERROR) else: wx.MessageBox('Not supported file Type !', 'ERROR', wx.OK | wx.ICON_ERROR) else: wx.MessageBox('No data to save', 'INFO', wx.OK | wx.ICON_INFORMATION)
def generate_provision_hex_file(s0_address, s1_address, hashes, provision_address, output): # Add addresses provision_data = struct.pack('III', s0_address, s1_address, len(hashes)) provision_data += b''.join(hashes) ih = IntelHex() ih.frombytes(provision_data, offset=provision_address) ih.write_hex_file(output)
def save(self, path): """Save an image from a given file""" ext = os.path.splitext(path)[1][1:].lower() if ext != INTEL_HEX_EXT: raise Exception("Only hex input file supported") h = IntelHex() h.frombytes(bytes=self.payload, offset=self.load_address) h.tofile(path, 'hex')
def generate_provision_hex_file(s0_address, s1_address, hashes, provision_address, output): # Add addresses provision_data = struct.pack('III', s0_address, s1_address, len(hashes)) for mhash in hashes: provision_data += struct.pack('I', 0xFFFFFFFF) # Invalidation token provision_data += mhash ih = IntelHex() ih.frombytes(provision_data, offset=provision_address) ih.write_hex_file(output)
def test_read_micropython(mock_read_flash): """Test read_micropython() with default arguments.""" data_bytes = bytes([x for x in range(256)] * 4) intel_hex = IntelHex() intel_hex.frombytes(data_bytes) ihex_str = ihex_to_str(intel_hex) mock_read_flash.return_value = (0, data_bytes) result = cmds.read_micropython() assert result == ihex_str
def setUp(cls): random.seed(420) cls._bin_data = bytes([random.randint(0, 0xFF) for i in range(10000)]) ihex = IntelHex() ihex.frombytes(cls._bin_data) hex_data = io.StringIO() ihex.write_hex_file(hex_data, write_start_addr=False) cls._hex_data = codecs.encode(hex_data.getvalue(), encoding='ascii') cls._args = [ 'python3', 'qpsk/encoder.py', '-s', '48000', '-y', '6000', '-b', '1K', '-f', '1K:40', '-a', '0', '-w', '10', '-p', '256' ]
def patch(message_func, ihex, hexf, align=256): update_checksum = False update_metadata = False # calculate checksum of the program section, detect metadata checksum = 0 for start, end in ihex.segments(): if start == CY_CHECKSUM_ADDR: # checksum section found in the original hex update_checksum = True if start == CY_META_ADDR: # metadata section found in the original hex update_metadata = True if start >= CY_PROGRAM_SIZE: continue segment = ihex.tobinarray(start, end) checksum += sum(segment) # only update checksum if it was found in the original hex if update_checksum: lowchecksum = checksum & 0x0FFFF message_func("Calculated checksum for %s is 0x%04x" % (hexf, lowchecksum)) checksum_str = pack('>H', lowchecksum) ihex.frombytes(array('B', checksum_str), offset=CY_CHECKSUM_ADDR) # only update metadata if it was found in the original hex if update_metadata: signature = unpack( '>L', ihex.tobinstr(start=CY_META_SILICON_ID_ADDR, size=4))[0] sigcheck = pack('>L', (checksum + signature) & 0x0FFFF) ihex.frombytes(array('B', sigcheck), offset=CY_META_CHECKSUM_ADDR) # align flash segments align_mask = align - 1 alignments = IntelHex() for start, end in ihex.segments(): if start >= CY_PROGRAM_SIZE: continue aligned_start = start & ~align_mask if start != aligned_start: message_func("Aligning start from 0x%x to 0x%x" % (start, aligned_start)) alignments.frombytes(ihex.tobinarray(aligned_start, start - 1), aligned_start) aligned_end = end & ~align_mask if end != aligned_end: aligned_end += align message_func("Aligning end from 0x%x to 0x%x" % (end, aligned_end)) alignments.frombytes(ihex.tobinarray(end, aligned_end - 1), end) ihex.merge(alignments, 'ignore')
def save(self, path): """Save an image from a given file""" ext = os.path.splitext(path)[1][1:].lower() if ext == INTEL_HEX_EXT: # input was in binary format, but HEX needs to know the base addr if self.slot_address is None: raise Exception("Input file does not provide a slot address") h = IntelHex() h.frombytes(bytes=self.payload, offset=self.slot_address) h.tofile(path, 'hex') else: with open(path, 'wb') as f: f.write(self.payload)
def patch_file(in_file, out_file, hex_file): with open(in_file, 'rb') as i: data = i.read() padding = bytes([0xFF]) data = data.ljust(BL_SIZE, padding) data = patch_data(data) with open(out_file, 'wb') as df: df.write(data) if len(hex_file) > 0: from intelhex import IntelHex out = IntelHex() out.frombytes(data, offset=BL_START) out.write_hex_file(hex_file)
def generate(self, workspace, outBin=None, outHex=None, skip=False): self.generated = False self.generatedBinary = None if self.valid: try: p = workspace.getParameters(self.parameters) if p is not None: if p.generateBinary(workspace, self): if outBin is not None: path = os.path.join(outBin, self.parameters) if not os.path.isdir(path): os.makedirs(path) self.destinationBin = os.path.join( path, self.name + ".bin") sink = open(self.destinationBin, 'wb') sink.write(p.generatedBinary) else: self.destinationBin = None if outHex is not None: path = os.path.join(outHex, self.parameters) if not os.path.isdir(path): os.makedirs(path) self.destinationHex = os.path.join( path, self.name + ".hex") ih = IntelHex() ih.frombytes(p.generatedBinary) ih.tofile(self.destinationHex, "hex") else: self.destinationHex = None self.generated = True else: self.reason = p.reason else: self.reason = "Cannot find a valid parameters file for '" + self.parameters + "'" return self.generated except IOError as e: self.reason = CoreConsole.error( str(e.strerror) + " [" + CoreConsole.highlightFilename(e.filename) + "]") CoreConsole.fail("ParametersTarget::generate: " + self.reason) return False
def generate(self, workspace, outBin=None, outHex=None,skip=False): self.generated = False self.generatedBinary = None if self.valid: try: p = workspace.getParameters(self.parameters) if p is not None: if p.generateBinary(workspace, self): if outBin is not None: path = os.path.join(outBin, self.parameters) if not os.path.isdir(path): os.makedirs(path) self.destinationBin = os.path.join(path, self.name + ".bin") sink = open(self.destinationBin, 'wb') sink.write(p.generatedBinary) else: self.destinationBin = None if outHex is not None: path = os.path.join(outHex, self.parameters) if not os.path.isdir(path): os.makedirs(path) self.destinationHex = os.path.join(path, self.name + ".hex") ih = IntelHex() ih.frombytes(p.generatedBinary) ih.tofile(self.destinationHex, "hex") else: self.destinationHex = None self.generated = True else: self.reason = p.reason else: self.reason = "Cannot find a valid parameters file for '" + self.parameters + "'" return self.generated except IOError as e: self.reason = CoreConsole.error(str(e.strerror) + " [" + CoreConsole.highlightFilename(e.filename) + "]") CoreConsole.fail("ParametersTarget::generate: " + self.reason) return False
def readToFile(self, file, fileformat="bin"): result = False readData = self.read() ih = IntelHex() ih.frombytes(readData) if fileformat in ("bin", "hex"): ih.tofile(file, format=fileformat) result = True else: raise DriverCapabilityError( "Invalid Format. readToFile() does not support format={}". format(format)) return result
def split_bin_to_ihex(file_name, base_addr, max_block_size): """Split a binary file to the blocks and load the blocks to IntelHex objects. Return the list of IntelHex objects. """ # Block size must be aligned to 2 byte boundary (workaround for rf#2088) assert max_block_size % 2 == 0 ihex_list = [] with open(file_name, 'rb') as f: while True: block = bytearray(f.read(max_block_size)) if not block: break # Align the last block to 2 byte boundary (workaround for rf#2088) if len(block) % 2 != 0: block.append(0xFF) ihex = IntelHex() ihex.frombytes(block, base_addr) ihex_list.append(ihex) return ihex_list
def _bytes_to_pretty_hex(data, offset=0x0000): """Convert a list of bytes to a nicely formatted ASCII decoded hex string. :param data: List of integers, each representing a single byte. :param offset: Start address offset. :return: A string with the formatted hex data. """ i_hex = IntelHex() i_hex.frombytes(data, offset) fake_file = StringIO() try: i_hex.dump(tofile=fake_file, width=16, withpadding=False) except IOError as e: sys.stderr.write("ERROR: File write: {}\n{}".format(fake_file, str(e))) return pretty_hex_str = fake_file.getvalue() fake_file.close() return pretty_hex_str
def _bytes_to_intel_hex(data, offset=0x0000): """Take a list of bytes and return a string in the Intel Hex format. :param data: List of integers, each representing a single byte. :param offset: Start address offset. :return: A string with the Intel Hex encoded data. """ i_hex = IntelHex() i_hex.frombytes(data, offset) fake_file = StringIO() try: i_hex.tofile(fake_file, format="hex") except IOError as e: sys.stderr.write("ERROR: File write: {}\n{}".format(fake_file, str(e))) return intel_hex_str = fake_file.getvalue() fake_file.close() return intel_hex_str
def patch(message_func, ihex, hexf, align=256): #calculate checksum checksum = 0 for start, end in ihex.segments(): if start >= 0x090000000: continue segment = ihex.tobinarray(start, end) checksum += sum(segment) lowchecksum = checksum & 0x0FFFF message_func("Calculated checksum for %s is 0x%04x" % (hexf, lowchecksum)) # update checksum checksum_str = pack('>H', lowchecksum) ihex.frombytes(array('B', checksum_str), offset=0x90300000) # update metadata signature = unpack('>L', ihex.tobinstr(start=0x90500002, size=4))[0] sigcheck = pack('>L', (checksum + signature) & 0x0FFFF) ihex.frombytes(array('B', sigcheck), offset=0x90500008) # align flash segments align_mask = align - 1 alignments = IntelHex() for start, end in ihex.segments(): if start >= 0x090000000: continue aligned_start = start & ~align_mask if start != aligned_start: message_func("Aligning start from 0x%x to 0x%x" % (start, aligned_start)) alignments.frombytes(ihex.tobinarray(aligned_start, start - 1), aligned_start) aligned_end = end & ~align_mask if end != aligned_end: aligned_end += align message_func("Aligning end from 0x%x to 0x%x" % (end, aligned_end)) alignments.frombytes(ihex.tobinarray(end, aligned_end - 1), end) ihex.merge(alignments)
def read(addr, length, compress, file): click.echo("\n Reading from MCU memory, please wait !\n") # Call KBoot flash erase all function data = KBOOT.read_memory(addr, length) # Disconnect KBoot Device KBOOT.disconnect() if file is None: click.echo(hexdump(data, addr, compress)) else: if file.lower().endswith('.bin'): with open(file, "wb") as f: f.write(data) f.close() elif file.lower().endswith('.hex'): ihex = IntelHex() ihex.frombytes(data, 0) ihex.start_addr = addr try: ihex.tofile(file, format='hex') except Exception as e: raise Exception('Could not write to file: %s \n [%s]' % (file, str(e))) else: srec = kboot.SRecFile() srec.header = "pyKBoot" srec.start_addr = addr srec.data = data try: srec.save(file) except Exception as e: raise Exception('Could not write to file: %s \n [%s]' % (file, str(e))) click.secho(" Successfully saved into: %s. \n" % file)
class Hex_File(object): """ This class handles patching the hex file with new device key and unicast address. """ def __init__(self, options): """ Initializer function. Keyword arguments: options -- Object created by parser.parse_args() that holds all the parameter values. """ try: self.hf_db = MeshDB(options.db_input_file) self.hf_hex_file = IntelHex(options.hex_input_file) self.hf_number_of_nodes = len(self.hf_db.nodes) self.hf_start_node = options.start_node self.hf_mesh_sdk_version = options.mesh_sdk_version self.hf_clone_copies = options.clone_copies if (self.hf_mesh_sdk_version == 400): self.START_OF_FLASH_MANAGER_OFFSET = 0x50 self.UNICAST_ADDRESS_OFFSET_1 = 0x1C self.UNICAST_ADDRESS_OFFSET_2 = 0x4C else: #Else assuming v3.2.0 of Nordic Mesh SDK self.START_OF_FLASH_MANAGER_OFFSET = 0x40 self.UNICAST_ADDRESS_OFFSET_1 = 0x1C self.UNICAST_ADDRESS_OFFSET_2 = 0x3C logging.debug('Start node is {0}'.format(self.hf_start_node)) if self.hf_start_node is not None: self.hf_working_node = self.hf_db.nodes[self.hf_start_node] else: self.hf_working_node = self.hf_db.nodes[( self.hf_number_of_nodes - 1)] self.hf_output_hex_fw_name = options.hex_output_file self.hf_new_device_key = options.device_key self.hf_new_unicast_addr = options.unicast_address self.hf_new_node_name = options.node_name self._hf_iteration = 0 except Exception as ex: logging.exception("Initialization error") def _generate_new_device_key(self): return uuid.uuid4().int.to_bytes(16, byteorder="big", signed=False) def patch_hex_file(self): """ This function patches the hex file with the new device key and the new unicast address. """ try: logging.debug('Patching for Mesh SDK version {0}'.format( self.hf_mesh_sdk_version)) #Get the device key from the database file self.hf_device_key = self.hf_working_node.device_key #Convert hex data to byte string so we can easily find the device key self.hf_input_hex_fw_bytestr = self.hf_hex_file.tobinstr() #Convert hex data to byte array that will represent the output patched hex file self.hf_output_hex_fw_bytearray = self.hf_hex_file.tobinarray() #Find the index where the device key starts logging.debug('Looking for device key {0}'.format( self.hf_device_key.hex())) self.hf_device_key_index = self.hf_input_hex_fw_bytestr.find( self.hf_device_key) if (self.hf_device_key_index == -1): logging.info( 'Device key not found! Are you sure the correct node is specified (--start-node)? ' ) raise ValueError( 'Device key not found in hex file! Aborting!') logging.info("Device key found at location {0}".format( hex(self.hf_device_key_index))) #Sanity check: for the infinitesimally small chance that the device key occurs elsewhere in the hex file naturally! #Check for Flash Manager Area signature: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.meshsdk.v4.0.0%2Fmd_doc_libraries_flash_manager.html self.hf_expected_start_of_flash_manager_index = ( self.hf_device_key_index - self.START_OF_FLASH_MANAGER_OFFSET) #This is where signature should be self.hf_flash_manager_sign_found = self.hf_input_hex_fw_bytestr.startswith( bytearray.fromhex('08041010'), (self.hf_expected_start_of_flash_manager_index), (self.hf_expected_start_of_flash_manager_index + 16)) if (self.hf_flash_manager_sign_found == False): logging.info( 'Flash Area Manager signature not found at expected location {0}' .format(hex( self.hf_expected_start_of_flash_manager_index))) raise ValueError( 'Flash Area Manager signature not found at expected location {0}' .format(hex( self.hf_expected_start_of_flash_manager_index))) else: logging.info( 'Flash Area Manager signature found at expected location {0}' .format(hex( self.hf_expected_start_of_flash_manager_index))) #Get offset for both occurences of device handle which also need to be updated per device self.hf_expected_device_uc_addr_index = ( self.hf_expected_start_of_flash_manager_index + self.UNICAST_ADDRESS_OFFSET_1) self.hf_expected_device_uc_addr_index_second = ( self.hf_expected_start_of_flash_manager_index + self.UNICAST_ADDRESS_OFFSET_2) #Create new unicast address by reading all existing unicast addresses in the db file, finding the max, and incrementing the largest one by one. if self.hf_new_unicast_addr is None: #Create a list of unicast addresses from the db file self.unicast_address_list = [] for i in self.hf_db.nodes: self.unicast_address_list.append(i.unicast_address) #Find highest unicast address and increment by 1 to create new unicast address self.next_unicast_address = max(self.unicast_address_list) + 1 logging.debug('Next available unicast address is {0}'.format( hex(self.next_unicast_address))) self.hf_new_unicast_addr = self.next_unicast_address for x in range(self.hf_clone_copies): ####Patch and write the cloned fw #Update device unicast address in output bytearray self.hf_output_hex_fw_bytearray[ self. hf_expected_device_uc_addr_index] = self.hf_new_unicast_addr self.hf_output_hex_fw_bytearray[ self. hf_expected_device_uc_addr_index_second] = self.hf_new_unicast_addr #Generate new device key only if not specified on command line if (self.hf_new_device_key is None): self.hf_new_device_key = self._generate_new_device_key() #Replace key in bytearray with new key for i in range(0, 16): self.hf_output_hex_fw_bytearray[ self.hf_device_key_index + i] = self.hf_new_device_key[i] #Create output IntelHex object... self.hf_output_hex_fw = IntelHex() #...and load it up with patched data self.hf_output_hex_fw.frombytes( self.hf_output_hex_fw_bytearray) #Write out new patched fw file #New file name for each clone, except first one if (self._hf_iteration == 0): logging.debug('Creating {0}'.format( self.hf_output_hex_fw_name)) self.hf_output_hex_fw.write_hex_file( self.hf_output_hex_fw_name) else: self._hf_output_hex_fw_name_list = re.split( '(\W)', self.hf_output_hex_fw_name) self._hf_output_hex_fw_name = self._hf_output_hex_fw_name_list[ 0] + "_" + str(self._hf_iteration) + "".join( self._hf_output_hex_fw_name_list[1:]) logging.debug('Creating {0}'.format( self._hf_output_hex_fw_name)) self.hf_output_hex_fw.write_hex_file( self._hf_output_hex_fw_name) self._hf_iteration += 1 ####Done patching and write the cloned fw ####Update JSON file with new node information #Create a new node for the new firmware in the JSON file by shallow copying from the original node in the JSON file self.hf_new_node = copy.copy(self.hf_working_node) #Update device address and unicast address self.hf_new_node.device_key = self.hf_new_device_key.hex() self.hf_new_node.unicast_address = self.hf_new_unicast_addr self.hf_db.nodes.append(self.hf_new_node) #Update node name if (self.hf_new_node_name is None): self.hf_new_node.name += "_" + str( self.hf_new_unicast_addr) else: self.hf_new_node.name = self.hf_new_node_name #Store to file self.hf_db.store() ####Done updating JSON file with new node information ####Reinitialize variables for next iteration, if any #Reset the device key so new one is generated in next iteration in case multiple clones are requested. #This also means if device key is specified on command-line and multiple clones requested then only first #fw clone will have that specified key & the rest of clones will have auto-generated keys. self.hf_new_device_key = None #Increment unicast address for next node, if there are more iterations. #This also means if unicast address is specified on command-line and multiple clones requested then only first #fw clone will have that specified unicast address & the rest of clones will have unique unicast addresses generated by #incrementing command-line specified node by 1. self.hf_new_unicast_addr = self.hf_new_unicast_addr + 1 #Reset node name to none for next iteration, if there are more iterations #This also means if node name is specified on command-line and multiple clones requested then only first #fw clone will have that node name & the rest of clones will have auto-generated node names. self.hf_new_node_name = None ####Done reinitializing variables for next iteration, if any except Exception as ex: logging.exception("Hex file patching error")
def generateNewHex(): tmp=open(bin_dir+program_name+"_modified.hex","w+"); ih=IntelHex(bin_dir+program_name+".hex"); binary=ih.tobinarray(); for p in pointers: if 'rjmp' in p: offset=int(p.split(":")[1],16); destination=p.split(":")[3]; binary.pop(offset); binary.pop(offset); insertOpcodeJMP(destination,offset,binary); elif 'jmp' in p: offset=int(p.split(":")[1],16); destination=p.split(":")[3]; binary.pop(offset); binary.pop(offset); binary.pop(offset); binary.pop(offset); insertOpcodeJMP(destination,offset,binary); elif 'rcall' in p: offset=int(p.split(":")[1],16); destination=p.split(":")[3]; binary.pop(offset); binary.pop(offset); insertOpcodeCALL(destination,offset,binary); elif 'call' in p: offset=int(p.split(":")[1],16); destination=p.split(":")[3]; binary.pop(offset); binary.pop(offset); binary.pop(offset); binary.pop(offset); insertOpcodeCALL(destination,offset,binary); elif 'br' in p: offset=int(p.split(":")[1],16); destination=p.split(":")[3]; opcode=p.split(":")[4]; binary.pop(offset); binary.pop(offset); insertOpcodeBR(destination,offset,binary,opcode); elif 'nop' in p: offset=int(p.split(":")[1],16); binary.insert(offset,0x00); binary.insert(offset+1,0x00); elif 'jump_link' in p: offset=int(p.split(":")[1],16); destination=p.split(":")[3]; insertOpcodeJMP(destination,offset,binary); elif 'global_ctors' in p: offset=int(p.split(":")[1],16); destination=p.split(":")[3]; binary.pop(offset); binary.pop(offset); insertOpcodeGLOBAL_CTORS(destination,offset,binary); elif 'vpointer' in p: offset=int(p.split(":")[1],16)-0x800000-0x100+offsetDataInSRAM; destination=p.split(":")[3]; binary.pop(offset); binary.pop(offset); insertOpcodeVPointers(destination,offset,binary); elif 'ldi_data_offset' in p: offset=int(p.split(":")[1],16); destination=p.split(":")[3]; binary.pop(offset); binary.pop(offset); binary.pop(offset); binary.pop(offset); insertOpcodeLDI_destination(destination,offset,binary); elif 'prologues' in p: offset=int(p.split(":")[1],16); destination=p.split(":")[3]; ad=destination.split("0x")[1]; while (len(ad)<4): ad='0'+ad; pc=address2pc(int(ad[0:2],16),int(ad[2:4],16)); destination="0x"+h(pc)+l(pc); binary.pop(offset); binary.pop(offset); binary.pop(offset); binary.pop(offset); insertOpcodeLDI_destination(destination,offset,binary); ih.frombytes(binary); ih.write_hex_file(tmp);
# However the key features of the programmer are for erase, read, write, # and verify functionality # Here's how easy it is to erase the memory, and then verify that it's blank print("Erasing the EEPROM...this may take 10s of seconds") programmer.erase() print("Erase Completed!") print("Now performing a blank check...") isBlank = programmer.blankCheck() print("isBlank = {}".format(isBlank)) print("Reading the entire EEPROM") data = programmer.read() print("Creating a .bin and .hex file with the data read from the EEPROM") ih.frombytes(data) print("Min Addr: {}, Max Addr: {}".format(str(ih.minaddr()), str(ih.maxaddr()))) print("Now saving the file to disk just to demo how easy it is") ih.tofile("testFileErased-00.hex", format="hex") ih.tofile("testFileErased-00.bin", format="bin") # Reading / Writing / Verifying EEPROMs from bin or hex files is also very # easy: print("Manually modifying the data file") dataFile = "testFile.bin" ih[0] = 0xDE ih[1] = 0xAD ih[2] = 0xBE ih[3] = 0xEF
def save(self, path): h = IntelHex() h.frombytes(bytes=self.payload, offset=self.base_addr) h.tofile(path, 'hex')