def merge_region_list(region_list, destination, padding=b'\xFF'): """Merege the region_list into a single image Positional Arguments: region_list - list of regions, which should contain filenames destination - file name to write all regions to padding - bytes to fill gapps with """ merged = IntelHex() print("Merging Regions:") for region in region_list: if region.active and not region.filename: raise ToolException("Active region has no contents: No file found.") if region.filename: print(" Filling region %s with %s" % (region.name, region.filename)) part = intelhex_offset(region.filename, offset=region.start) part_size = (part.maxaddr() - part.minaddr()) + 1 if part_size > region.size: raise ToolException("Contents of region %s does not fit" % region.name) merged.merge(part) pad_size = region.size - part_size if pad_size > 0 and region != region_list[-1]: print(" Padding region %s with 0x%x bytes" % (region.name, pad_size)) merged.puts(merged.maxaddr() + 1, padding * pad_size) if not exists(dirname(destination)): makedirs(dirname(destination)) print("Space used after regions merged: 0x%x" % (merged.maxaddr() - merged.minaddr() + 1)) with open(destination, "wb+") as output: merged.tofile(output, format='bin')
def main(args): if len(args) == 1: img = Image.open(sys.stdin) else: img = Image.open(args[1]) if img.mode not in ('1', 'P'): sys.exit("Expected a 1-bit image, got %s" % img.mode) if img.size != (8, 8): sys.exit("Expected an 8x8 pixel image") if 'duration' not in img.info: sys.exit("Expected an animation") out = IntelHex() out.puts(0x00, struct.pack("BBB", 1, img.info['duration'] / 10, 0)) for idx, frame in enumerate(ImageSequence.Iterator(img)): framedata = [0] * 8 for i, bit in enumerate(frame.getdata()): framedata[i % 8] = (framedata[i % 8] << 1) | bit out.puts(data_offset + idx * 8, struct.pack('8B', *framedata)) # Write out the frame count out[0x02] = idx + 1 if len(args) == 2: out.tofile(sys.stdout, format='hex') else: out.tofile(open(args[2], 'w'), format='hex')
def dump_state(filename, regs, content_chunks): from intelhex import IntelHex ih = IntelHex() for base_addr, contents in content_chunks.items(): # print("Adding chunk of size 0x{:x}".format(len(contents))) # f.write("0x{:08x} {}\n".format(base_addr, hexlify(contents.rstrip(b'\0')).decode())) ih.puts(base_addr, contents) with open(filename, "w") as f: f.write("""r0=0x{:x} r1=0x{:x} r2=0x{:x} r3=0x{:x} r4=0x{:x} r5=0x{:x} r6=0x{:x} r7=0x{:x} r8=0x{:x} r9=0x{:x} r10=0x{:x} r11=0x{:x} r12=0x{:x} lr=0x{:x} pc=0x{:x} sp=0x{:x} xpsr=0x{:x} """.format(*[regs[const] for const in uc_reg_consts])) print("Writing ihex dump now...") ih.write_hex_file(f)
def __init__(self, fw, channel=16, serial_port=None, snr=None): ''' Ininitialises the OTA Flasher class which handles flashing the devboard with the needed OTA Server firmware and the update file for the OTA Client. The said devboard shall become the OTA Server which shall propagate the image on the Zigbee network. Keyword arguments: fw -- path to the update file for the OTA Client channel -- a 802.15.4 channel number, on which the OTA Server shall operate (default 16) serial_port -- a serial port of the connected devboard which shall be flashed with OTA Server snr -- a JLink serial number of the connected devboard which shall be flashed with OTA Server Note: only one parameter out of (serial_port, snr) must be provided, since the superclass constructor shall handle resolving the rest. ''' # Call the superclass constructor super().__init__(serial_port, snr) # Create a Intel Hex out of the Zigbee Update file ih = IntelHex() update = open(fw, 'rb').read() ih.puts(OTAFlasher.OTA_UPDATE_OFFSET, update) self.update_firmware_hex = fw + '.hex' ih.write_hex_file(self.update_firmware_hex) # Open the serial channel to the devboard and save the 802.15.4 channel self.ser = Serial(self.serial_port, 115200) self.channel = channel
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 read(start, lenght, fname): stop=start+lenght f=fname print "Dumping from %04x to %04x as %s." % (start,stop,f) #h = IntelHex16bit(None) # FIXME: get mcu state and return it to that state try: h = IntelHex(None) i=start while i<=stop: #data=client.ARMreadMem(i, 48) data=client.ARMreadChunk(i, 48, verbose=0) print "Dumped %06x."%i for dword in data: if i<=stop and dword != 0xdeadbeef: h.puts( i, struct.pack("<I", dword) ) i+=4 # FIXME: get mcu state and return it to that state except: print "Unknown error during read. Writing results to output file." print "Rename file with last address dumped %06x."%i pass h.write_hex_file(f)
def dumpV2(self, all): start_address = 0x3ff2 if all else 0x37f8 cmd_verif = [0xa6, 0, 0, 0, 0, 0, 0, 0] cmd_verif[1] = 5 + 8 # find block of 8 0xFF at the end of the device memory block = [0xff] * 8 found = False data = [d ^ self.scrambleCodeV2[i % 8] for i, d in enumerate(block)] for address in range(start_address, -1, -1): print('Looking for 0xFF block at address 0x{:04X}'.format( address), end='\n') cmd_verif[3:5] = address & 0xFF, (address >> 8) & 0xFF r, _ = self.cmd_verify_v2(bin_str_of_list(cmd_verif + data)) if r == 0: print('\nFound 0xFF block at address 0x{:04X}'.format(address)) found = True break if not found: print('\nUnable to find 0xFF block') return memdump = IntelHex() memdump.puts(address, bin_str_of_list(block)) print('Starting flash dumping') for i in reversed(block): print('{:02X} '.format(i), end='') sys.stdout.flush() nTry = 0 nBytes = 0 for address in range(address - 1, -1, -1): block[1:] = block[:-1] # shift cmd_verif[3:5] = address & 0xFF, (address >> 8) & 0xFF found = False for i in range(256): val = stats[i] block[0] = val nTry += 1 data = [d ^ self.scrambleCodeV2[i % 8] for i, d in enumerate(block)] r, _ = self.cmd_verify_v2(bin_str_of_list(cmd_verif + data),9) if r == 0: # verification ok, we found the correct byte print('{:02X} '.format(val), end='') sys.stdout.flush() found = True nBytes += 1 memdump[address] = val break if not found: raise ValueError('Unable to find correct ' 'byte for address 0x{:04X}'.format(address)) output_bin = 'out.bin' output_hex = 'out.hex' print('\nDone, writing output files {} and {}'.format(output_bin, output_hex)) print('Ntry = {} {:.2f}try/bytes'.format(nTry, float(nTry) / nBytes)) memdump.tobinfile(output_bin) memdump.tofile(output_hex, format='hex')
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 tofile(self, outfile: Union[str, IO]) -> None: ih = IntelHex() ih.puts(self.base or 0, bytes(self.fw)) if Firmware._ishex(outfile): if not isinstance(outfile, str): outfile = io.TextIOWrapper(outfile) ih.write_hex_file(outfile) else: ih.tobinfile(outfile)
def post_process(self): logging.info("Processing binaries") # save original dir cwd = os.getcwd() # change to target dir os.chdir(self.target_dir) ih = IntelHex('main.hex') fwid = uuid.UUID('{' + self.settings["FWID"] + '}') size = ih.maxaddr() - ih.minaddr() + 1 # get os info os_project = get_project_builder(self.settings["OS_PROJECT"]) # create firmware info structure fw_info = struct.pack('<I16s128s16s128s16s', size, fwid.bytes, os_project.proj_name, os_project.version, self.proj_name, self.version) # insert fw info into hex ih.puts(0x120, fw_info) # compute crc crc_func = crcmod.predefined.mkCrcFun('crc-aug-ccitt') crc = crc_func(ih.tobinstr()) logging.info("size: %d" % (size)) logging.info("fwid: %s" % (fwid)) logging.info("crc: 0x%x" % (crc)) logging.info("os name: %s" % (os_project.proj_name)) logging.info("os version: %s" % (os_project.version)) logging.info("app name: %s" % (self.proj_name)) logging.info("app version: %s" % (self.version)) ih.puts(ih.maxaddr() + 1, struct.pack('>H', crc)) ih.write_hex_file('main.hex') ih.tobinfile('firmware.bin') # get loader info loader_project = get_project_builder(self.settings["LOADER_PROJECT"]) # create loader image loader_hex = os.path.join(loader_project.target_dir, "main.hex") self.merge_hex('main.hex', loader_hex, 'loader_image.hex') # change back to original dir os.chdir(cwd)
def create_hex(filename, addr, auto_rst, pad_size): file_format = 'hex' intel_hex = IntelHex() intel_hex.puts(addr, struct.pack(FORMAT, CFG_KEY, FORMAT_LENGTH, auto_rst)) pad_addr = addr + FORMAT_LENGTH pad_byte_count = pad_size - (FORMAT_LENGTH % pad_size) pad_data = '\xFF' * pad_byte_count intel_hex.puts(pad_addr, pad_data) with open(filename, 'wb') as f: intel_hex.tofile(f, file_format)
def create_hex(filename, addr, auto_rst, automation_allowed, overflow_detect, detect_incompatible_target, pad_size): intel_hex = IntelHex() intel_hex.puts(addr, struct.pack(FORMAT, CFG_KEY, FORMAT_LENGTH, auto_rst, automation_allowed, overflow_detect, detect_incompatible_target)) pad_addr = addr + FORMAT_LENGTH pad_byte_count = pad_size - (FORMAT_LENGTH % pad_size) pad_data = '\xFF' * pad_byte_count intel_hex.puts(pad_addr, pad_data) intel_hex.write_hex_file(filename)
def dump(self): end_address = 0x3ff0 # send the key b = '\xa6\x04' + struct.pack('BBBB', *scrambleCode) self.xcmd(b, 0) # find block of 16 0xFF at the end of the device memory block = [0xff] * 16 found = False for address in range(end_address, -1, -1): print('\rLooking for address 0x{:04X}'.format(address), end='') r = self.cmd('\xa7\16' + struct.pack('<H', address) + bin_str_of_list(scramble(block))) if r == 0: print('\nFound 0xFF block at address 0x{:04X}'.format(address)) found = True break if not found: print('\nUnable to find 0xFF block') return memdump = IntelHex() memdump.puts(address, bin_str_of_list(block)) print('Starting flash dumping') base = [0xa7, 16, 0, 0] nTry = 0 nBytes = 0 for address in range(address - 1, - 1, -1): block[1:] = block[:-1] # shift base[2:4] = address & 0xFF, address >> 8 found = False for i in range(256): i = stats[i] block[0] = i nTry += 1 r = self.cmd(bin_str_of_list(base + scramble(block)), 4) if r == 0: # verification ok, we found the correct byte print('{:02X} '.format(i), end='') sys.stdout.flush() found = True nBytes += 1 memdump[address] = i break if not found: raise ValueError('Unable to find correct ' 'byte for address 0x{:04X}'.format(address)) output_bin = 'out.bin' output_hex = 'out.hex' print('\nDone, writing output files {} and {}'.format(output_bin, output_hex)) print('Ntry = {} {:.2f}try/bytes'.format(nTry, float(nTry) / nBytes)) memdump.tobinfile(output_bin) memdump.tofile(output_hex, format='hex')
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 tofile(self, outfile: Union[str, BinaryIO], fmt: Optional[str] = None) -> None: if fmt is None and isinstance( outfile, str) and outfile.lower().endswith('.hex'): fmt = 'hex' else: fmt = 'bin' ih = IntelHex() ih.puts(self.base or 0, bytes(self.fw)) ih.tofile(outfile, fmt)
def create_hex(filename, addr, auto_rst, automation_allowed, pad_size): file_format = 'hex' intel_hex = IntelHex() intel_hex.puts(addr, struct.pack(FORMAT, CFG_KEY, FORMAT_LENGTH, auto_rst, automation_allowed)) pad_addr = addr + FORMAT_LENGTH pad_byte_count = pad_size - (FORMAT_LENGTH % pad_size) pad_data = '\xFF' * pad_byte_count intel_hex.puts(pad_addr, pad_data) with open(filename, 'wb') as f: intel_hex.tofile(f, file_format)
def _main(): """Append credentials to a prebuilt hex file, download it via a J-Link debug probe, allow the hex file to run, verify the result code, and then erase the hex file. """ args = _add_and_parse_args() nrfjprog_api = None nrfjprog_probe = None try: hex_path = HEX_PATH if args.in_file: hex_path = args.in_file intel_hex = IntelHex(hex_path) if intel_hex.maxaddr() >= CRED_PAGE_ADDR: if hex_path == HEX_PATH: print("error: Prebuilt hex file is too large.") _close_and_exit(nrfjprog_api, -3) elif (intel_hex.maxaddr() < FW_RESULT_CODE_ADDR or intel_hex.gets(CRED_PAGE_ADDR, 4) != MAGIC_NUMBER_BYTES): print("error: Magic number not found in hex file.") _close_and_exit(nrfjprog_api, -2) else: intel_hex.puts(CRED_PAGE_ADDR, MAGIC_NUMBER_BYTES) intel_hex.puts(CRED_COUNT_ADDR, struct.pack('B', 0x00)) if not args.out_file or args.program_app: nrfjprog_api, nrfjprog_probe = _connect_to_jlink(args) _append_creds(intel_hex, args) if args.out_file: intel_hex.tofile(args.out_file, "hex") else: # Create a temporary file to pass to pynrfjprog and then delete it when finished. tmp_file = os.path.sep.join((tempfile.mkdtemp(), TMP_FILE_NAME)) intel_hex.tofile(tmp_file, "hex") _write_firmware(nrfjprog_probe, tmp_file) time.sleep(args.fw_delay) result_code = nrfjprog_probe.read(FW_RESULT_CODE_ADDR) if result_code: print("error: Firmware result is 0x{:X}".format(result_code)) _close_and_exit(nrfjprog_api, -4) imei_bytes = nrfjprog_probe.read(IMEI_ADDR, IMEI_LEN + 1) if (IMEI_LEN != imei_bytes.find(BLANK_FLASH_VALUE) or not imei_bytes[:IMEI_LEN].isdigit()): print("error: IMEI does not look valid.") _close_and_exit(nrfjprog_api, -5) print(imei_bytes[:-1].decode()) nrfjprog_probe.erase(HighLevel.EraseAction.ERASE_ALL) os.remove(tmp_file) os.removedirs(os.path.dirname(tmp_file)) if args.program_app: _write_firmware(nrfjprog_probe, args.program_app) _close_and_exit(nrfjprog_api, 0) except Exception as ex: print("error: " + str(ex)) _close_and_exit(nrfjprog_api, -2)
def read(self, address, length, hex_file_path): if ((int(length, 16) % 4) != 0): print("ERROR: number of bytes must be a multiple of 4") return NrfDfuErr.INVALID_PARAMETER if (not self._quiet): print("Reading %s bytes from address %s" % (length, address)) open(hex_file_path, 'w+') ih = IntelHex(hex_file_path) ih.__init__() self.api.write_u32(0x2000000C, 0x00000004, True) self.api.write_u32(0x20000010, int(address, 16), False) self.api.write_u32(0x20000014, int(length, 16), False) self.api.write_u32(0x4002A004, 0x00000001, False) start_time = time.time() event_received = False while (event_received == False): if ((time.time() - start_time) > 10): print ("ERROR: Time out, no event received after 10 sec.") return NrfDfuErr.TIME_OUT return_value, event_received = self.get_event_status() if return_value < 0: return return_value self.acknowlage_events() return_value, modem_response = self.read_be(0x2000000C) if (modem_response == "5a000001"): print("\n\n ERROR: UNKNOWN COMMAND") return NrfDfuErr.DFU_ERROR elif (modem_response == "5a000002"): print("\n\n ERROR: COMMAND ERROR") error_result = self.api.read_u32(0x20000010) print("ERROR: Read failed at {}".format(hex(error_result))) return NrfDfuErr.DFU_ERROR word_count = int(length, 16)//4 for i in range(0, word_count): return_value, lelevel = self.hex_read(0x20000010+(i*4)) ih.puts(int(address,16)+(i*4), codecs.decode(lelevel, "hex")) ih.write_hex_file(hex_file_path) if (not self._quiet): print ("Reading completed") return NrfDfuErr.SUCCESS
def to_hex(self, f): ''' Convert the assembled machine code to Intel HEX file format. :param f: The HEX data will be written to this destination. :type f: filename or file-like object ''' from intelhex import IntelHex ih = IntelHex() for addr, val in self.accumulator.iteritems(): addr = int(addr, 16) ih.puts(addr, val) ih.write_hex_file(f)
def main(args: argparse.Namespace): brtype = args.branch_type hexfile = args.hexfile # Pad a numeric string with zeros brtype = brtype.zfill(BRANCH_TYPE_BYTES * 2) # Split string data into bytes (e.g. "AABBCCDD" -> b'\xaa\xbb\xcc\xdd' bytes_brtype = bytes.fromhex(brtype) ''' # for debug print("bytes_brtype=", end='') print(bytes_brtype) ''' ih = IntelHex() # Write out user defined data global csvFilePath csvFilePath = args.user_data if csvFilePath is not None: # if csvFilePath is given if os.path.exists(csvFilePath): with open(csvFilePath, 'r') as fp: csvList = list(csv.reader(fp)) if len(csvList) > 0: print("csvList has some contents") flatList = [item for subList in csvList for item in subList] print(flatList) bytes_data = strlist_to_bytes(flatList) if len(bytes_data) > 0: ih.puts(USER_DATA_ADDR, bytes_data) else: print(csvFilePath + " is empty") ErrorMsg() else: print(csvFilePath + " not found. Skip user defined EEPROM data flash.") print() else: print("Skip user defined EEPROM data flash.") print() # Write out branchType ih.puts(SYSTEM_RESERVED_ADDR, bytes_brtype) hex_file_name = os.path.join(os.path.dirname(os.path.abspath(__file__)), hexfile) ih.dump() ih.write_hex_file(hex_file_name)
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 merge_region_list(region_list, destination, notify, padding=b'\xFF'): """Merge the region_list into a single image Positional Arguments: region_list - list of regions, which should contain filenames destination - file name to write all regions to padding - bytes to fill gapps with """ merged = IntelHex() _, format = splitext(destination) notify.info("Merging Regions") for region in region_list: if region.active and not region.filename: raise ToolException("Active region has no contents: No file found.") if isinstance(region.filename, list): header_basename, _ = splitext(destination) header_filename = header_basename + "_header.hex" _fill_header(region_list, region).tofile(header_filename, format='hex') region = region._replace(filename=header_filename) if region.filename: notify.info(" Filling region %s with %s" % (region.name, region.filename)) part = intelhex_offset(region.filename, offset=region.start) part.start_addr = None part_size = (part.maxaddr() - part.minaddr()) + 1 if part_size > region.size: raise ToolException("Contents of region %s does not fit" % region.name) merged.merge(part) pad_size = region.size - part_size if pad_size > 0 and region != region_list[-1]: notify.info(" Padding region %s with 0x%x bytes" % (region.name, pad_size)) if format is ".hex": """The offset will be in the hex file generated when we're done, so we can skip padding here""" else: merged.puts(merged.maxaddr() + 1, padding * pad_size) if not exists(dirname(destination)): makedirs(dirname(destination)) notify.info("Space used after regions merged: 0x%x" % (merged.maxaddr() - merged.minaddr() + 1)) merged.tofile(destination, format=format.strip("."))
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 dump(self,fn,start=0,stop=0xffffffff): """Dump an intel hex file from code memory.""" print "Dumping from %04x to %04x as %s." % (start,stop,f); # FIXME: get mcu state and return it to that state self.halt() h = IntelHex(None); i=start; while i<=stop: data=self.ARMreadChunk(i, 48, verbose=0); print "Dumped %06x."%i; for dword in data: if i<=stop and dword != 0xdeadbeef: h.puts( i, struct.pack("<I", dword) ) i+=4; # FIXME: get mcu state and return it to that state self.resume() h.write_hex_file(fn); print "Dump not implemented.";
def dump(self, fn, start=0, stop=0xFFFFFFFF): """Dump an intel hex file from code memory.""" print "Dumping from %04x to %04x as %s." % (start, stop, f) # FIXME: get mcu state and return it to that state self.halt() h = IntelHex(None) i = start while i <= stop: data = self.ARMreadChunk(i, 48, verbose=0) print "Dumped %06x." % i for dword in data: if i <= stop and dword != 0xDEADBEEF: h.puts(i, struct.pack("<I", dword)) i += 4 # FIXME: get mcu state and return it to that state self.resume() h.write_hex_file(fn) print "Dump not implemented."
def dump(self,fn,start=0,stop=0xffffffff): """Dump an intel hex file from code memory.""" print "Dumping from %04x to %04x as %s." % (start,stop,f); # FIXME: get mcu state and return it to that state self.halt() print "halted, starting the dump" h = IntelHex(None); i=start; while i<=stop: data=self.ARMreadChunk(i, 48, verbose=0); print "Dumped %06x."%i; for dword in data: if i<=stop and dword != 0xdeadbeef: h.puts( i, struct.pack("<I", dword) ) i+=4; # FIXME: get mcu state and return it to that state self.resume() h.write_hex_file(fn); print "Dump not implemented.";
def provisionDevice( model ): # create New Device Account , create backupHex file, Flash the device FactoryDevHex = IntelHex("BootAppConfig.hex") keySectionApp = IntelHex() # contain key section of hex file #update key section #keys A4T4 is stored for "AT" in eeprom if (not fbLoginSucess()): printE("Login to provision") return #register new device and load SN maxSn = fbReadDb("FirmwareMeta/" + model + "/MaxSn") fbWriteDb("FirmwareMeta/" + model + "/MaxSn", maxSn + 1) DevSn = base36encode(maxSn, 6) userid = model + DevSn # 8 bytes passkey = get_random_password_string(8) #pass key 8 bytes #get model key From Server, makeure for any new device modle key is generated manually ModelKey = fbReadDb("FirmwareMeta/" + model + "/ModelKey") # "MODEL"+model+"0" #8 bytes fbWriteDb("FirmwareMeta/" + model + "/DevSnKeys/" + userid, passkey) #mearge hex file with keys and generate device hex file keysection = userid + passkey + ModelKey + passkey # last passkey is just filler eepKeySection = insertByteAfterOne( bytes(passkey + ModelKey, 'utf-8'), 0 ) # this keys are also loaded into EEP so that user need not have to to FDR keysectionFlash = insertByteAfterOne(bytes( keysection, 'utf-8'), 0x34) # 34 in msb signify flash constant keySectionApp.puts(KEY_START_ADD * FLASH_WORD_SIZE, keysectionFlash) keySectionApp.puts(EEP_KEY_START_ADD * FLASH_WORD_SIZE, eepKeySection) FactoryDevHex.merge(keySectionApp) FactoryDevHex.write_hex_file("Factory" + model + DevSn + ".hex", False) # don't write start address currentDevPath = "Factory" + model + DevSn + ".hex" return currentDevPath
def install_app(self, app_manifest: AppManifest): hex_file = IntelHex(app_manifest.get_binary()) code_length = hex_file.maxaddr() - hex_file.minaddr() + 1 data_length = app_manifest.data_size code_length -= data_length assert code_length % 64 == 0 # code length must be aligned flags = app_manifest.get_application_flags() # not handled yet params = app_manifest.serialize_parameters() main_address = hex_file.start_addr["EIP"] - hex_file.minaddr() data = struct.pack(">IIIII", code_length, data_length, len(params), flags, main_address) self.apdu_secure_exchange(LedgerSecureIns.CREATE_APP, data) hex_file.puts(hex_file.maxaddr() + 1, params) for segment in hex_file.segments(): self._load_segment(hex_file, segment) self.apdu_secure_exchange(LedgerSecureIns.COMMIT)
if modf(chan)[0] != 0.0: print "Illegal freq/spacing combo" sys.exit(2) chan = int(chan) # First create the data without the checksum, note that we specify # little-endianness for multi-byte values. t = pack('<BBBHB8x', band, demphasis, spacing, chan, volume) # Calculate and append a crc-16 checksum crc16 = Crc('crc-16') crc16.update(t) t = t + pack('<H', crc16.crcValue) # # Simply create a hex file with the concatenation of two tuning structures (t) # and optionally one manufacturing structure, then write the result. # eeprom = t + t if manuf: eeprom = eeprom + manuf_record(sn, ts, campaign) hexfile = IntelHex() hexfile.puts(0, eeprom) hexfile.write_hex_file(outfile)
flash_base = 0x18000000 cap_delay = 2 spi_clk = 0 cfg_info = 0xffffffbf image_crypt = 0xffffffff sbl_code_start = flash_base+0x1000 sbl_code_length = len(sbl_data) crc_rslt = zlib.crc32(sbl_data) crc_bytes = struct.pack("I",crc_rslt) sbl_data = sbl_data + crc_bytes info_head = struct.pack('LLHHLLLLLL',test_word0,test_word1,cap_delay,spi_clk,cfg_info,image_crypt,0xffffffff,0xffffffff,sbl_code_start,sbl_code_length) else: flash_base = 0x00800000 code_offset = 0x1000 sbl_code_length = len(sbl_data) sbl_code_start = flash_base+code_offset sbl_code_exec_addr = 0x400100 feature_mask = 0xffffffff info_head = struct.pack('LLLLLL',test_word0,test_word1,code_offset,sbl_code_length,sbl_code_exec_addr,feature_mask) mac_addr_base = flash_base + 0x30 mac_addr = bytes([0xff,0xff,0xff,0xff,0xff,0xff]) # ff:ff:ff:ff:ff:ff is not a valid address ih = IntelHex() ih.puts(flash_base,info_head) ih.puts(mac_addr_base,mac_addr) ih.puts(sbl_code_start,sbl_data) ih.write_hex_file(sys.argv[3])
if vargs.range is not None: if vargs.range[0] is not None: startAddr = vargs.range[0] if vargs.range[1] is not None: endAddr = vargs.range[1] # Make sure the last address is divisible by 16 remainder = endAddr % OAD_BLOCK_SIZE if remainder: print( "Last address was 0x%0X. Expanded to 0x%0X to be divisible by OAD block size" % (endAddr, endAddr + (OAD_BLOCK_SIZE - remainder))) endAddr += OAD_BLOCK_SIZE - remainder #if specified, the script will pad the image with the pad value fillHex = IntelHex() fillHex.puts(startAddr, struct.pack('B', vargs.fill) * (endAddr)) mergedHex.merge(fillHex, 'ignore') mergedHex = mergedHex[ startAddr:endAddr] # +1 since the last address is not inclusive mergedHex.padding = vargs.fill #if we are calculating metadata #Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these #All onchip OAD images need metdata placement if not (vargs.oadtype == 'offchip' and (vargs.imgtype == 'production' or vargs.imgtype == 'np')): # Place metadata, onchip production image expects header at 0x600 if vargs.oadtype == 'onchip' and vargs.imgtype == 'production': residentHdr = OadHdr._make( struct.unpack( OAD_HDR_FMT,
def _fill_header(region_list, current_region): """Fill an application header region This is done it three steps: * Fill the whole region with zeros * Fill const, timestamp and size entries with their data * Fill the digests using this header as the header region """ region_dict = {r.name: r for r in region_list} header = IntelHex() header.puts(current_region.start, b'\x00' * current_region.size) start = current_region.start for member in current_region.filename: _, type, subtype, data = member if type == "const": fmt = { "8le": ">B", "16le": "<H", "32le": "<L", "64le": "<Q", "8be": "<B", "16be": ">H", "32be": ">L", "64be": ">Q" }[subtype] header.puts(start, struct.pack(fmt, integer(data, 0))) elif type == "timestamp": fmt = { "32le": "<L", "64le": "<Q", "32be": ">L", "64be": ">Q" }[subtype] header.puts(start, struct.pack(fmt, int(time()))) elif type == "size": fmt = { "32le": "<L", "64le": "<Q", "32be": ">L", "64be": ">Q" }[subtype] size = sum(_real_region_size(region_dict[r]) for r in data) header.puts(start, struct.pack(fmt, size)) elif type == "digest": if data == "header": ih = header[:start] else: ih = intelhex_offset(region_dict[data].filename, offset=region_dict[data].start) if subtype.startswith("CRCITT32"): fmt = {"CRCITT32be": ">L", "CRCITT32le": "<L"}[subtype] crc_val = zlib.crc32(ih.tobinarray()) & 0xffffffff header.puts(start, struct.pack(fmt, crc_val)) elif subtype.startswith("SHA"): if subtype == "SHA256": hash = hashlib.sha256() elif subtype == "SHA512": hash = hashlib.sha512() hash.update(ih.tobinarray()) header.puts(start, hash.digest()) start += Config.header_member_size(member) return header
def get_hex(f, b, d, cs): # # All the following to be able to be set with getopt. # These defaults will do for testing purposes. # outfile = sys.stdout # manufacturing data # manuf = False sn = "" ts = "" campaign = "" eyecatcher = 'The Public Radio' # tuning info defaults # freq = 0.0 band = 0 # US 87.5 - 108 demphasis = 0 # US 75uS spacing = 0 # US 200KHz volume = 0x0f # max (0 dBFS) # # Create a manufacturing record. # def manuf_record(sn, ts, campaign): ww = int(date.today().strftime('%V')) yy = int(date.today().strftime('%g')) return pack('17sBB2s13s17s', sn[:16], ww, yy, ts[:2], campaign[:12], eyecatcher) # # calculate channel # based on freq, band & channel spacing. # Note that we force the floating point arithmetic to round # to a reasonable number of digits in order to avoid daft problems. freq = float(f) band = int(b) demphasis = int(d) spacing = int(cs) base = {0: 87.5, 1: 76, 2: 76} step = {0: 5, 1: 10, 2: 20} try: chan = round((freq - base[band]) * step[spacing], 4) except: chan = round((freq - base[0]) * step[0], 4) if modf(chan)[0] != 0.0: chan = 0 chan = int(chan) # First create the data without the checksum, note that we specify # little-endianness for multi-byte values. t = pack('<BBBHB8x', band, demphasis, spacing, chan, volume) # Calculate and append a crc-16 checksum crc16 = crcmod.predefined.Crc('crc-16') crc16.update(t) t = t + pack('<H', crc16.crcValue) # # Simply create a hex file with the concatenation of two tuning structures (t) # and optionally one manufacturing structure, then write the result. # eeprom = t + t if manuf: eeprom = eeprom + manuf_record(sn, ts, campaign) outfile = tempfile.NamedTemporaryFile(prefix='eeprom.', suffix='.hex', delete=False) hexfile = IntelHex() hexfile.puts(0, eeprom) hexfile.write_hex_file(outfile) outfile.close() return outfile
elif sel == "B": # take B_!RST low i2c2.write_byte(0x70, 0x4) # steer mux iob = i2c0.read_byte_data(0x22, 0x14) i2c0.write_byte_data(0x22, 0x14, iob&~0x10) print(icsp_cmd(ser, b'L')) # take MCLR low (icsp) print(icsp_cmd(ser, b'#', 9)) # reset checksum # print(icsp_cmd(ser, b'%', 5)) # reset stats print(icsp_cmd(ser, b'^')) # enter LVP print("dumping program memory ...") data = icsp_read_data(ser, 0x4000) for a in range(0x0000, 0x4000): val = data[a] ih.puts(a*2, struct.pack("<h", val)) icsp_cmd(ser, b'[X0=]', 0) # switch to config mem print("dumping config memory ...") data = icsp_read_data(ser, 0x11) for a in range(0x8000, 0x8011): val = data[a - 0x8000] ih.puts(a*2, struct.pack("<h", val)) print(icsp_cmd(ser, b'#', 9)) # retrieve checksum print(icsp_cmd(ser, b'Z')) # tristate MCLK (icsp) if sel == "A": # bring A_!RST high again i2c0.write_byte_data(0x23, 0x14, ioa|0x10)
endAddr = ((endAddr + INT_FL_PG_SIZE) & ~(INT_FL_PG_SIZE-1)) print ('endAddr round', hex(endAddr)) if vargs.range is not None: if vargs.range[0] is not None: startAddr = vargs.range[0] if vargs.range[1] is not None: endAddr = vargs.range[1] # Make sure the last address is divisible by 16 remainder = endAddr % OAD_BLOCK_SIZE if remainder: print("Last address was 0x%0X. Expanded to 0x%0X to be divisible by OAD block size" % (endAddr, endAddr+(OAD_BLOCK_SIZE-remainder)) ) endAddr += OAD_BLOCK_SIZE - remainder #if specified, the script will pad the image with the pad value fillHex = IntelHex() fillHex.puts(startAddr, struct.pack('B', vargs.fill) * (endAddr)) mergedHex.merge(fillHex, 'ignore') mergedHex = mergedHex[startAddr:endAddr] # +1 since the last address is not inclusive mergedHex.padding = vargs.fill #if we are calculating metadata #Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these #All onchip OAD images need metdata placement if not(vargs.oadtype == 'offchip' and (vargs.imgtype == 'production' or vargs.imgtype == 'np')): # Place metadata, onchip production image expects header at 0x600 if vargs.oadtype == 'onchip' and vargs.imgtype == 'production': residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN, INT_FL_OAD_IMG_A_META_BEGIN+15))) else: residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(startAddr, startAddr+15))) metaAddr = vargs.meta
def arm9_cli_handler(client, argv): if(argv[1]=="info"): client.halt() print >>sys.stderr, client.ARMidentstr() print >>sys.stderr,"Debug Status:\t%s" % client.statusstr() print >>sys.stderr,"CPSR: (%s) %s\n"%(client.ARMget_regCPSRstr()) client.resume() if(argv[1]=="dump"): f = sys.argv[2] start=0x00000000 stop=0xFFFFFFFF if(len(sys.argv)>3): start=int(sys.argv[3],16) if(len(sys.argv)>4): stop=int(sys.argv[4],16) print "Dumping from %04x to %04x as %s." % (start,stop,f) #h = IntelHex16bit(None) # FIXME: get mcu state and return it to that state client.halt() try: h = IntelHex(None) i=start while i<=stop: #data=client.ARMreadMem(i, 48) data=client.ARMreadChunk(i, 48, verbose=0) print "Dumped %06x."%i for dword in data: if i<=stop and dword != 0xdeadbeef: h.puts( i, struct.pack("<I", dword) ) i+=4 # FIXME: get mcu state and return it to that state except: print "Unknown error during read. Writing results to output file." print "Rename file with last address dumped %06x."%i pass client.resume() h.write_hex_file(f) ''' if(sys.argv[1]=="erase"): print "Erasing main flash memory." client.ARMmasserase() if(sys.argv[1]=="eraseinfo"): print "Erasing info memory." client.ARMinfoerase() ''' if(sys.argv[1]=="ivt"): client.halt() client.ARMprintChunk(0x0,0x20) client.resume() if(sys.argv[1]=="regs"): client.halt() for i in range(0,16): print "r%i=%04x" % (i,client.ARMget_register(i)) client.resume() if(sys.argv[1]=="flash"): f=sys.argv[2] start=0 stop=0x10000 if(len(sys.argv)>3): start=int(sys.argv[3],16) if(len(sys.argv)>4): stop=int(sys.argv[4],16) client.halt() h = IntelHex16bit(f) #Should this be default? #Makes flashing multiple images inconvenient. #client.ARMmasserase() count=0; #Bytes in commit. first=0 vals=[] last=0; #Last address committed. for i in h._buf.keys(): if((count>0x40 or last+2!=i) and count>0 and i&1==0): #print "%i, %x, %x" % (len(vals), last, i) client.ARMpokeflashblock(first,vals) count=0 first=0 last=0 vals=[] if(i>=start and i<stop and i&1==0): val=h[i>>1] if(count==0): first=i last=i count+=2 vals+=[val&0xff,(val&0xff00)>>8] if(i%0x100==0): print "%04x" % i if count>0: #last commit, ivt client.ARMpokeflashblock(first,vals) client.resume() if(sys.argv[1]=="verify"): f=sys.argv[2] start=0 stop=0xFFFF if(len(sys.argv)>3): start=int(sys.argv[3],16) if(len(sys.argv)>4): stop=int(sys.argv[4],16) client.halt() h = IntelHex16bit(f) for i in h._buf.keys(): if(i>=start and i<stop and i&1==0): peek=client.peek(i) if(h[i>>1]!=peek): print "ERROR at %04x, found %04x not %04x"%(i,peek,h[i>>1]) if(i%0x100==0): print "%04x" % i client.resume() if(sys.argv[1]=="peek"): start = 0x0000 if(len(sys.argv)>2): start=int(sys.argv[2],16) stop = start+4 if(len(sys.argv)>3): stop=int(sys.argv[3],16) print "Peeking from %04x to %04x." % (start,stop) client.halt() for dword in client.ARMreadChunk(start, (stop-start)/4, verbose=0): print "%.4x: %.8x" % (start, dword) start += 4 client.resume() if(sys.argv[1]=="poke"): start=0x0000 val=0x00 if(len(sys.argv)>2): start=int(sys.argv[2],16) if(len(sys.argv)>3): val=int(sys.argv[3],16) print "Poking %06x to become %04x." % (start,val) client.halt() #???while client.ARMreadMem(start)[0]&(~val)>0: client.ARMwriteChunk(start, [val]) print "Poked to %.8x" % client.ARMreadMem(start)[0] client.resume() if(sys.argv[1]=="reset"): #Set PC to RESET vector's value. #client.ARMsetPC(0x00000000) #client.ARMset_regCPSR(0) #client.ARMreleasecpu() client.ARMresettarget(1000)
import sys from intelhex import IntelHex WRITEBACK = True if len(sys.argv) > 1: WRITEBACK = False ser = int(sys.argv[1]) else: try: ser = int(file(".serial", "rb").read(), 16) + 1 except IOError: ser = 0 print >>sys.stderr, ("[--- new serial number: %.4x ---]" % ser) if WRITEBACK: file(".serial", "wb").write("%.13x" % ser) sertxt = "" sertmp = "%.13x" % ser for c in sertmp: sertxt += "%s\x00" % c ihc = IntelHex("CCBootloader/CCBootloader-rfcat-chronosdongle.hex") ihd = IntelHex("CCBootloader/CCBootloader-rfcat-donsdongle.hex") ihc.puts(0x13E0, "@las\x1c\x03" + sertxt) ihd.puts(0x13E0, "@las\x1c\x03" + sertxt) ihc.write_hex_file("CCBootloader/CCBootloader-rfcat-chronosdongle-serial.hex") ihd.write_hex_file("CCBootloader/CCBootloader-rfcat-donsdongle-serial.hex")
class Flash(): def __init__(self, link, flash_type, sbp_version): """ Object representing either of the two flashes (STM/M25) on the Piksi, including methods to erase, program, and read. Parameters ---------- link : sbp.client.handler.Handler Handler to send messages to Piksi over and register callbacks with. flash_type : string Which Piksi flash to interact with ("M25" or "STM"). sbp_version : (int, int) SBP protocol version, used to select messages to send. Returns ------- out : Flash instance """ self._n_queued_ops = 0 self.nqo_lock = Lock() self.stopped = False self.status = '' self.link = link self.flash_type = flash_type self.sbp_version = sbp_version # IntelHex object to store read flash data in that was read from device. self._read_callback_ihx = IntelHex() self.link.add_callback(self._done_callback, SBP_MSG_FLASH_DONE) self.link.add_callback(self._read_callback, SBP_MSG_FLASH_READ_DEVICE) self.ihx_elapsed_ops = 0 # N operations finished in self.write_ihx if self.flash_type == "STM": self.flash_type_byte = 0 self.addr_sector_map = stm_addr_sector_map # Add STM-specific functions. self.__dict__['lock_sector'] = \ new.instancemethod(_stm_lock_sector, self, Flash) self.__dict__['unlock_sector'] = \ new.instancemethod(_stm_unlock_sector, self, Flash) self.n_sectors = STM_N_SECTORS self.restricted_sectors = STM_RESTRICTED_SECTORS elif self.flash_type == "M25": self.flash_type_byte = 1 self.addr_sector_map = m25_addr_sector_map # Add M25-specific functions. self.__dict__['write_status'] = \ new.instancemethod(_m25_write_status, self, Flash) self.n_sectors = M25_N_SECTORS self.restricted_sectors = M25_RESTRICTED_SECTORS else: raise ValueError("flash_type must be \"STM\" or \"M25\", got \"%s\"" \ % flash_type) def __enter__(self): return self def __exit__(self, type, value, traceback): """ Calls self.stop() before instance is deleted. """ if not self.stopped: self.stop() def ihx_n_ops(self, ihx, erase=True): """ Find the number of sent SBP messages (erase, program, read) self.write_ihx will require to write a particular intelhex.IntelHex for this instance's flash type. Parameters ---------- ihx : intelhex.Intelhex intelhex.IntelHex to be written. erase : bool Include number of erase operations required in total. Returns ------- out : int Number of sent SBP messages (erase, program, read) self.write_ihx will require to write ihx. """ return ihx_n_ops(ihx, self.addr_sector_map, erase) def inc_n_queued_ops(self): """ Increment the count of queued flash operation SBP messages in the STM's flash in a thread safe way. """ self.nqo_lock.acquire() self._n_queued_ops += 1 self.nqo_lock.release() def dec_n_queued_ops(self): """ Decrement the count of queued flash operation SBP messages in the STM's flash in a thread safe way. """ self.nqo_lock.acquire() self._n_queued_ops -= 1 self.nqo_lock.release() def get_n_queued_ops(self): """ Get the current count of queued flash operation SBP messages. Returns ------- out : int Get the current count of queued flash operation SBP messages. """ return self._n_queued_ops def stop(self): """ Remove instance callbacks from sbp.client.handler.Handler. """ self.stopped = True self.link.remove_callback(self._done_callback, SBP_MSG_FLASH_DONE) self.link.remove_callback(self._read_callback, SBP_MSG_FLASH_READ_DEVICE) def __str__(self): """ Return flashing status. """ return self.status def erase_sector(self, sector, warn=True): """ Erase a sector of the flash. Parameters ---------- sector : int Sector to be erased. warn : bool Warn if sector is restricted and should most likely not be erased. """ if warn and sector in self.restricted_sectors: text = 'Attempting to erase %s flash restricted sector %d' % \ (self.flash_type, sector) raise Warning(text) msg_buf = struct.pack("BB", self.flash_type_byte, sector) self.inc_n_queued_ops() self.link.send(SBP_MSG_FLASH_ERASE, msg_buf) while self.get_n_queued_ops() > 0: time.sleep(0.001) def program(self, address, data): """ Program a set of addresses of the flash. Parameters ---------- address : int Starting address of set of addresses to program with data. data : string String of bytes to program to flash starting at address. """ msg_buf = struct.pack("B", self.flash_type_byte) msg_buf += struct.pack("<I", address) msg_buf += struct.pack("B", len(data)) self.inc_n_queued_ops() # < 0.45 of SBP protocol, reuse single flash message. if self.sbp_version < (0, 45): self.link.send(SBP_MSG_FLASH_DONE, msg_buf + data) else: self.link.send(SBP_MSG_FLASH_PROGRAM, msg_buf + data) def read(self, address, length): """ Read a set of addresses of the flash. Parameters ---------- address : int Starting address of length addresses to read. length : int Number of addresses to read. """ msg_buf = struct.pack("B", self.flash_type_byte) msg_buf += struct.pack("<I", address) msg_buf += struct.pack("B", length) self.inc_n_queued_ops() # < 0.45 of SBP protocol, reuse single read message. if self.sbp_version < (0, 45): self.link.send(SBP_MSG_FLASH_READ_DEVICE, msg_buf) else: self.link.send(SBP_MSG_FLASH_READ_HOST, msg_buf) def _done_callback(self, sbp_msg): """ Handles flash done message sent from device. Parameters ---------- data : string Binary data sent from device. """ ret = ord(sbp_msg.payload) if (ret != 0): print "Flash operation returned error (%d)" % ret self.dec_n_queued_ops() assert self.get_n_queued_ops() >= 0, \ "Number of queued flash operations is negative" def _read_callback(self, sbp_msg): """ Handles flash read message sent from device. Parameters ---------- data : string Binary data sent from device. """ # 4 bytes addr, 1 byte length, length bytes data address = struct.unpack('<I', sbp_msg.payload[0:4])[0] length = struct.unpack('B', sbp_msg.payload[4])[0] self._read_callback_ihx.puts(address, sbp_msg.payload[5:]) self.dec_n_queued_ops() assert self.get_n_queued_ops() >= 0, \ "Number of queued flash operations is negative" def write_ihx(self, ihx, stream=None, mod_print=0, elapsed_ops_cb=None, erase=True): """ Perform all operations to write an intelhex.IntelHex to the flash and verify. Parameters ---------- ihx : intelhex.IntelHex intelhex.IntelHex to write to the flash. stream : stream Object implementing write and flush methods to write status updates to. mod_print : int How many loops to run through before writing to stream. elapsed_ops_cb : function Callback to execute every mod_print loops. erase : bool Erase sectors before writing. """ self.ihx_elapsed_ops = 0 self.print_count = 0 start_time = time.time() ihx_addrs = ihx_ranges(ihx) # Erase sectors if erase: for sector in sectors_used(ihx_addrs, self.addr_sector_map): self.status = self.flash_type + " Flash: Erasing sector %d" % sector if stream: stream.write('\r' + self.status) stream.flush() self.erase_sector(sector) self.ihx_elapsed_ops += 1 if elapsed_ops_cb != None: elapsed_ops_cb(self.ihx_elapsed_ops) if stream: stream.write('\n') # Write data to flash and read back to later validate. STM's lowest address # is used by bootloader to check that the application is valid, so program # from high to low to ensure this address is programmed last. for start, end in reversed(ihx_addrs): for addr in reversed(range(start, end, ADDRS_PER_OP)): self.status = self.flash_type + " Flash: Programming address" + \ " 0x%08X" % addr if mod_print == 0 or mod_print != 0 and self.print_count % mod_print == 0: if stream: stream.write('\r' + self.status) stream.flush() self.print_count = 1 if elapsed_ops_cb != None: elapsed_ops_cb(self.ihx_elapsed_ops) else: self.print_count += 1 binary = ihx.tobinstr(start=addr, size=ADDRS_PER_OP) # Program ADDRS_PER_OP addresses while self.get_n_queued_ops() >= MAX_QUEUED_OPS: time.sleep(0.001) self.program(addr, binary) self.ihx_elapsed_ops += 1 # Read ADDRS_PER_OP addresses while self.get_n_queued_ops() >= MAX_QUEUED_OPS: time.sleep(0.001) self.read(addr, ADDRS_PER_OP) self.ihx_elapsed_ops += 1 # Verify that data written to flash matches data read from flash. while self.get_n_queued_ops() > 0: time.sleep(0.001) for start, end in reversed(ihx_addrs): if self._read_callback_ihx.gets(start, end-start+1) != \ ihx.gets(start, end-start+1): for i in range(start, end): r = self._read_callback_ihx.gets(i,1) p = ihx.gets(i,1) if r != p: raise Exception('Data read from flash != Data programmed to flash' ('Addr: %x, Programmed: %x, Read: %x' % (i,r,p)).upper()) self.status = self.flash_type + " Flash: Successfully programmed and " + \ "verified, total time = %d seconds" % \ int(time.time()-start_time) if stream: stream.write('\n\r' + self.status + '\n')
memory_map = board.target.getMemoryMap() ram_regions = [region for region in memory_map if region.type == 'ram'] ram_region = ram_regions[0] rom_region = memory_map.getBootMemory() target_type = board.getTargetType() print "[3/6] Board recognized as %s. Downloading ROM..." % target_type addr = rom_region.start size = rom_region.length data = board.target.readBlockMemoryUnaligned8(addr, size) data = bytearray(data) with open("crashdump/rom.bin", 'wb') as f: f.write(data) ih = IntelHex() ih.puts(addr, data) ih.tofile("crashdump/rom.hex", format='hex') print "[4/6] Dumped ROM. Downloading RAM..." addr = ram_region.start size = ram_region.length data = board.target.readBlockMemoryUnaligned8(addr, size) data = bytearray(data) with open("crashdump/ram.bin", 'wb') as f: f.write(data) ih = IntelHex() ih.puts(addr, data) ih.tofile("crashdump/ram.hex", format='hex') print "[5/6] Dumped RAM. Creating uVision project..."
class Flash(): def __init__(self, link, flash_type, sbp_version, max_queued_ops=1): """ Object representing either of the two flashes (STM/M25) on the Piksi, including methods to erase, program, and read. Parameters ---------- link : sbp.client.handler.Handler Handler to send messages to Piksi over and register callbacks with. flash_type : string Which Piksi flash to interact with ("M25" or "STM"). sbp_version : (int, int) SBP protocol version, used to select messages to send. max_queued_ops : int Maximum number of Flash read/program operations to queue in device flash. (0.5 * ADDRS_PER_OP + SBP packet overhead) * max_queued_ops is how much of the device UART RX buffer will be filled by the program/read callback messages. A higher value will significantly speed up flashing, but can result in RX buffer overflows in other UARTs if the device is receiving data on other UARTs. Returns ------- out : Flash instance """ self._n_queued_ops = 0 self.max_queued_ops = max_queued_ops self.nqo_lock = Lock() self.stopped = False self.status = '' self.link = link self.flash_type = flash_type self.sbp_version = sbp_version # IntelHex object to store read flash data in that was read from device. self._read_callback_ihx = IntelHex() self.link.add_callback(self._done_callback, SBP_MSG_FLASH_DONE) self.link.add_callback(self._read_callback, SBP_MSG_FLASH_READ_RESP) self.ihx_elapsed_ops = 0 # N operations finished in self.write_ihx if self.flash_type == "STM": self.flash_type_byte = 0 self.addr_sector_map = stm_addr_sector_map # Add STM-specific functions. self.__dict__['lock_sector'] = \ new.instancemethod(_stm_lock_sector, self, Flash) self.__dict__['unlock_sector'] = \ new.instancemethod(_stm_unlock_sector, self, Flash) self.n_sectors = STM_N_SECTORS self.restricted_sectors = STM_RESTRICTED_SECTORS elif self.flash_type == "M25": self.flash_type_byte = 1 self.addr_sector_map = m25_addr_sector_map # Add M25-specific functions. self.__dict__['write_status'] = \ new.instancemethod(_m25_write_status, self, Flash) self.n_sectors = M25_N_SECTORS self.restricted_sectors = M25_RESTRICTED_SECTORS else: raise ValueError("flash_type must be \"STM\" or \"M25\", got \"%s\"" \ % flash_type) def __enter__(self): return self def __exit__(self, type, value, traceback): """ Calls self.stop() before instance is deleted. """ if not self.stopped: self.stop() def ihx_n_ops(self, ihx, erase=True): """ Find the number of sent SBP messages (erase, program, read) self.write_ihx will require to write a particular intelhex.IntelHex for this instance's flash type. Parameters ---------- ihx : intelhex.Intelhex intelhex.IntelHex to be written. erase : bool Include number of erase operations required in total. Returns ------- out : int Number of sent SBP messages (erase, program, read) self.write_ihx will require to write ihx. """ return ihx_n_ops(ihx, self.addr_sector_map, erase) def inc_n_queued_ops(self): """ Increment the count of queued flash operation SBP messages in the STM's flash in a thread safe way. """ self.nqo_lock.acquire() self._n_queued_ops += 1 self.nqo_lock.release() def dec_n_queued_ops(self): """ Decrement the count of queued flash operation SBP messages in the STM's flash in a thread safe way. """ self.nqo_lock.acquire() self._n_queued_ops -= 1 self.nqo_lock.release() def get_n_queued_ops(self): """ Get the current count of queued flash operation SBP messages. Returns ------- out : int Get the current count of queued flash operation SBP messages. """ return self._n_queued_ops def stop(self): """ Remove instance callbacks from sbp.client.handler.Handler. """ self.stopped = True self.link.remove_callback(self._done_callback, SBP_MSG_FLASH_DONE) self.link.remove_callback(self._read_callback, SBP_MSG_FLASH_READ_RESP) def __str__(self): """ Return flashing status. """ return self.status def erase_sector(self, sector, warn=True): """ Erase a sector of the flash. Parameters ---------- sector : int Sector to be erased. warn : bool Warn if sector is restricted and should most likely not be erased. """ if warn and sector in self.restricted_sectors: text = 'Attempting to erase %s flash restricted sector %d' % \ (self.flash_type, sector) raise Warning(text) msg_buf = struct.pack("BB", self.flash_type_byte, sector) self.inc_n_queued_ops() self.link(MsgFlashErase(target=self.flash_type_byte, sector_num=sector)) while self.get_n_queued_ops() > 0: time.sleep(0.001) def program(self, address, data): """ Program a set of addresses of the flash. Parameters ---------- address : int Starting address of set of addresses to program with data. data : string String of bytes to program to flash starting at address. """ msg_buf = struct.pack("B", self.flash_type_byte) msg_buf += struct.pack("<I", address) msg_buf += struct.pack("B", len(data)) self.inc_n_queued_ops() # < 0.45 of SBP protocol, reuse single flash message. if self.sbp_version < (0, 45): self.link(SBP(SBP_MSG_FLASH_DONE, payload=msg_buf + data)) else: self.link( MsgFlashProgram(target=self.flash_type_byte, addr_start=address, addr_len=len(data), data=data)) def read(self, address, length, block=False): """ Read a set of addresses of the flash. Parameters ---------- address : int Starting address of length addresses to read. length : int Number of addresses to read. block : bool Block until addresses are read and return them. Returns ======= out : str String of bytes (big endian) read from address. """ msg_buf = struct.pack("B", self.flash_type_byte) msg_buf += struct.pack("<I", address) msg_buf += struct.pack("B", length) self.inc_n_queued_ops() # < 0.45 of SBP protocol, reuse single read message. if self.sbp_version < (0, 45): self.link(SBP(SBP_MSG_FLASH_READ_RESP, payload=msg_buf)) else: self.link( MsgFlashReadReq(target=self.flash_type_byte, addr_start=address, addr_len=length)) if block: while self.get_n_queued_ops() > 0: time.sleep(0.001) return self._read_callback_ihx.gets(address, length) def _done_callback(self, sbp_msg, **metadata): """ Handles flash done message sent from device. Parameters ---------- data : string Binary data sent from device. """ ret = ord(sbp_msg.payload) if (ret != 0): print(("Flash operation returned error (%d)" % ret)) self.dec_n_queued_ops() assert self.get_n_queued_ops() >= 0, \ "Number of queued flash operations is negative" def _read_callback(self, sbp_msg, **metadata): """ Handles flash read message sent from device. Parameters ---------- data : string Binary data sent from device. """ # 4 bytes addr, 1 byte length, length bytes data address = struct.unpack('<I', sbp_msg.payload[0:4])[0] length = struct.unpack('B', sbp_msg.payload[4])[0] self._read_callback_ihx.puts(address, sbp_msg.payload[5:]) self.dec_n_queued_ops() assert self.get_n_queued_ops() >= 0, \ "Number of queued flash operations is negative" def write_ihx(self, ihx, stream=None, mod_print=0, elapsed_ops_cb=None, erase=True): """ Perform all operations to write an intelhex.IntelHex to the flash and verify. Parameters ---------- ihx : intelhex.IntelHex intelhex.IntelHex to write to the flash. stream : stream Object implementing write and flush methods to write status updates to. mod_print : int How many loops to run through before writing to stream. elapsed_ops_cb : function Callback to execute every mod_print loops. erase : bool Erase sectors before writing. """ self.ihx_elapsed_ops = 0 self.print_count = 0 start_time = time.time() ihx_addrs = ihx_ranges(ihx) # Erase sectors if erase: for sector in sectors_used(ihx_addrs, self.addr_sector_map): self.status = self.flash_type + " Flash: Erasing sector %d" % sector if stream: stream.write('\r' + self.status) stream.flush() self.erase_sector(sector) self.ihx_elapsed_ops += 1 if elapsed_ops_cb != None: elapsed_ops_cb(self.ihx_elapsed_ops) if stream: stream.write('\n') # Write data to flash and read back to later validate. STM's lowest address # is used by bootloader to check that the application is valid, so program # from high to low to ensure this address is programmed last. for start, end in reversed(ihx_addrs): for addr in reversed(list(range(start, end, ADDRS_PER_OP))): self.status = self.flash_type + " Flash: Programming address" + \ " 0x%08X" % addr if mod_print == 0 or mod_print != 0 and self.print_count % mod_print == 0: if stream: stream.write('\r' + self.status) stream.flush() self.print_count = 1 if elapsed_ops_cb != None: elapsed_ops_cb(self.ihx_elapsed_ops) else: self.print_count += 1 binary = ihx.tobinstr(start=addr, size=ADDRS_PER_OP) # Program ADDRS_PER_OP addresses while self.get_n_queued_ops() >= self.max_queued_ops: time.sleep(0.001) self.program(addr, binary) self.ihx_elapsed_ops += 1 # Read ADDRS_PER_OP addresses while self.get_n_queued_ops() >= self.max_queued_ops: time.sleep(0.001) self.read(addr, ADDRS_PER_OP) self.ihx_elapsed_ops += 1 # Verify that data written to flash matches data read from flash. while self.get_n_queued_ops() > 0: time.sleep(0.001) for start, end in reversed(ihx_addrs): if self._read_callback_ihx.gets(start, end-start+1) != \ ihx.gets(start, end-start+1): for i in range(start, end): r = self._read_callback_ihx.gets(i, 1) p = ihx.gets(i, 1) if r != p: raise Exception( 'Data read from flash != Data programmed to flash' ( 'Addr: %x, Programmed: %x, Read: %x' % (i, r, p)).upper()) self.status = self.flash_type + " Flash: Successfully programmed and " + \ "verified, total time = %d seconds" % \ int(time.time()-start_time) if stream: stream.write('\n\r' + self.status + '\n')
iob = i2c0.read_byte_data(0x22, 0x14) i2c0.write_byte_data(0x22, 0x14, iob&~0x10) # if ver == "0.36": # print("mux = 0x%02x" % i2c2.read_byte(0x30)) print(icsp_cmd(ser, b'L')) # take MCLR low (icsp) print(icsp_cmd(ser, b'#', 9)) # reset checksum print(icsp_enter_lvp(ser)) # enter LVP print("dumping program memory ...") data = icsp_read_data(ser, 0x4000) for a in range(0x0000, 0x4000): val = data[a] ih.puts(a*2, struct.pack("<h", val)) icsp_cmd(ser, b'[X0=]', 0) # switch to config mem print("dumping config memory ...") data = icsp_read_data(ser, 0x11) for a in range(0x8000, 0x8011): val = data[a - 0x8000] ih.puts(a*2, struct.pack("<h", val)) print(icsp_cmd(ser, b'#', 9)) # retrieve checksum print(icsp_cmd(ser, b'Z')) # tristate MCLK (icsp) if ver == "0.36": print("mux = 0x%02x" % i2c2.read_byte(0x30))
def get_hex(f, b, d, cs): # # All the following to be able to be set with getopt. # These defaults will do for testing purposes. # outfile=sys.stdout # manufacturing data # manuf=False sn="" ts="" campaign="" eyecatcher='The Public Radio' # tuning info defaults # freq=0.0 band=0 # US 87.5 - 108 demphasis=0 # US 75uS spacing=0 # US 200KHz volume=0x0f # max (0 dBFS) # # Create a manufacturing record. # def manuf_record(sn, ts, campaign): ww = int(date.today().strftime('%V')) yy = int(date.today().strftime('%g')) return pack('17sBB2s13s17s', sn[:16], ww, yy, ts[:2], campaign[:12], eyecatcher) # # calculate channel # based on freq, band & channel spacing. # Note that we force the floating point arithmetic to round # to a reasonable number of digits in order to avoid daft problems. freq = float(f) band = int(b) demphasis = int(d) spacing= int(cs) base = {0: 87.5, 1: 76, 2: 76} step = {0: 5, 1: 10, 2: 20} try: chan = round((freq - base[band]) * step[spacing], 4) except: chan = round((freq - base[0]) * step[0], 4) if modf(chan)[0] != 0.0: chan = 0 chan = int(chan) # First create the data without the checksum, note that we specify # little-endianness for multi-byte values. t = pack('<BBBHB8x', band, demphasis, spacing, chan, volume) # Calculate and append a crc-16 checksum crc16 = crcmod.predefined.Crc('crc-16') crc16.update(t) t = t + pack('<H', crc16.crcValue) # # Simply create a hex file with the concatenation of two tuning structures (t) # and optionally one manufacturing structure, then write the result. # eeprom = t + t if manuf: eeprom = eeprom + manuf_record(sn, ts, campaign) outfile = tempfile.NamedTemporaryFile(prefix='eeprom.', suffix='.hex', delete=False) hexfile = IntelHex() hexfile.puts(0, eeprom) hexfile.write_hex_file(outfile) outfile.close() return outfile
# Sanity checks, very important if ih.maxaddr() < 0x1004 or ih.maxaddr() > 32767: print "Insane hexfile: min=0x%x max=0x%x" % (ih.minaddr(), ih.maxaddr()) sys.exit(2) print "Length: %d / 28672" % (ih.maxaddr() - 4096 + 1) print "Free: %d" % (28672 - (ih.maxaddr() - 4096 + 1)) # Hack to force tobinstr() to write data from addres 0. IntelHex will # only write data from the first location with initialized data, skipping # over any uninitialized data beforehand. This initializes address 0, # forcing IntelHex to do what I want. ih[0]=ih[0] sumdata = (ih.tobinstr())[0x1004:] sumdata += '\xff' * (0x6ffc - len(sumdata)) cksum = binascii.crc32(sumdata) & 0xffffffff print "Checksum: 0x%08x" % cksum ih.puts(0x1000, struct.pack('<L', cksum)) # Rather than using IntelHex.tobinfile(), i'm writing to a file this way # to ensure that the file ends up at exactly 32768 bytes. binfw = ih.tobinstr() binfw += '\xff' * (0x8000 - len(binfw)) out.write(binfw) out.close() # Testing only. a=IntelHex() a.loadbin(sys.argv[2]) a.write_hex_file(sys.argv[2] + '.hex')
if not os.path.exists(sys.argv[2]): sys.exit("Unable open build %s" % sys.argv[2]) build_filename = sys.argv[1] prog_filename = sys.argv[2] # open the build and prog # note open build via StringIO so we can add to it build = IntelHex(StringIO.StringIO(open(build_filename, "r").read())) prog = IntelHex(prog_filename) # merge program into build prog_header_addr = prog.minaddr() prog.start_addr = build.start_addr # we need this to make the merge work smoothly build.merge(prog) # add pointer to program header to the bootstrap header_tbl_addr = 0x08000204 header_tbl_len = 2 #@todo get this from 0x0800200 as uint32_t header_tbl_format = "<LL" header_tbl = list(struct.unpack(header_tbl_format, build.gets(header_tbl_addr, header_tbl_len * 4))) k = 0 while header_tbl[k] != 0xffffffff: if k > header_tbl_len: sys.exit("bootstrap program table full [you have too many programs]!"); k += 1 header_tbl[k] = prog_header_addr build.puts(header_tbl_addr, struct.pack(header_tbl_format, *header_tbl)) # done build.write_hex_file(build_filename)
def merge_region_list(region_list, destination, notify, config, padding=b'\xFF'): """Merge the region_list into a single image Positional Arguments: region_list - list of regions, which should contain filenames destination - file name to write all regions to padding - bytes to fill gaps with """ merged = IntelHex() _, format = splitext(destination) notify.info("Merging Regions") # Merged file list: Keep track of binary/hex files that we have already # merged. e.g In some cases, bootloader may be split into multiple parts, # but all internally referring to the same bootloader file. merged_list = [] for region in region_list: if region.active and not region.filename: raise ToolException( "Active region has no contents: No file found.") if isinstance(region.filename, list): header_basename, _ = splitext(destination) header_filename = header_basename + "_header.hex" _fill_header(region_list, region).tofile(header_filename, format='hex') region = region._replace(filename=header_filename) if region.filename and (region.filename not in merged_list): notify.info(" Filling region %s with %s" % (region.name, region.filename)) part = intelhex_offset(region.filename, offset=region.start) part.start_addr = None # Normally, we assume that part.maxddr() can be beyond # end of rom. If the size is restricted with config, don't # allow this. if config.target.restrict_size is not None: part_size = (part.maxaddr() - part.minaddr()) + 1 if part_size > region.size: raise ToolException("Contents of region %s does not fit" % region.name) merged_list.append(region.filename) merged.merge(part) elif region.filename in merged_list: notify.info(" Skipping %s as it is merged previously" % (region.name)) # Hex file can have gaps, so no padding needed. While other formats may # need padding. Iterate through segments and pad the gaps. if format != ".hex": # begin patching from the end of the first segment _, begin = merged.segments()[0] for start, stop in merged.segments()[1:]: pad_size = start - begin merged.puts(begin, padding * pad_size) begin = stop + 1 if not exists(dirname(destination)): makedirs(dirname(destination)) notify.info("Space used after regions merged: 0x%x" % (merged.maxaddr() - merged.minaddr() + 1)) merged.tofile(destination, format=format.strip("."))
name = self._name_of_address_thunk(address) return name, address def _adjust(self, op, args, addr): return (ibv(args[0] - addr - 1),) if __name__ == '__main__': aa = AVRAssembly() aa.assemble_file('asm.py') ## print ; print ; print ## pprint.pprint(dict(aa.context)) ## print ; print ; print ## pprint.pprint(dict(aa.data)) ## print ; print ; print ## pprint.pprint(aa.pass2()) data = aa.pass2() print ; print ; print pprint.pprint(data) from intelhex import IntelHex ih = IntelHex() for addr, val in data.iteritems(): addr = int(addr, 16) if isinstance(val, str): ih.puts(addr, val) else: print 'non-str', addr, repr(val) ## ih.dump(tofile=open('pavr.hex', 'w')) ih.dump()
def arm9_cli_handler(client, argv): if (argv[1] == "info"): client.halt() print >> sys.stderr, client.ARMidentstr() print >> sys.stderr, "Debug Status:\t%s" % client.statusstr() print >> sys.stderr, "CPSR: (%s) %s\n" % (client.ARMget_regCPSRstr()) client.resume() if (argv[1] == "dump"): f = sys.argv[2] start = 0x00000000 stop = 0xFFFFFFFF if (len(sys.argv) > 3): start = int(sys.argv[3], 16) if (len(sys.argv) > 4): stop = int(sys.argv[4], 16) print "Dumping from %04x to %04x as %s." % (start, stop, f) #h = IntelHex16bit(None) # FIXME: get mcu state and return it to that state client.halt() try: h = IntelHex(None) i = start while i <= stop: #data=client.ARMreadMem(i, 48) data = client.ARMreadChunk(i, 48, verbose=0) print "Dumped %06x." % i for dword in data: if i <= stop and dword != 0xdeadbeef: h.puts(i, struct.pack("<I", dword)) i += 4 # FIXME: get mcu state and return it to that state except: print "Unknown error during read. Writing results to output file." print "Rename file with last address dumped %06x." % i pass client.resume() h.write_hex_file(f) ''' if(sys.argv[1]=="erase"): print "Erasing main flash memory." client.ARMmasserase() if(sys.argv[1]=="eraseinfo"): print "Erasing info memory." client.ARMinfoerase() ''' if (sys.argv[1] == "ivt"): client.halt() client.ARMprintChunk(0x0, 0x20) client.resume() if (sys.argv[1] == "regs"): client.halt() for i in range(0, 16): print "r%i=%04x" % (i, client.ARMget_register(i)) client.resume() if (sys.argv[1] == "flash"): f = sys.argv[2] start = 0 stop = 0x10000 if (len(sys.argv) > 3): start = int(sys.argv[3], 16) if (len(sys.argv) > 4): stop = int(sys.argv[4], 16) client.halt() h = IntelHex16bit(f) #Should this be default? #Makes flashing multiple images inconvenient. #client.ARMmasserase() count = 0 #Bytes in commit. first = 0 vals = [] last = 0 #Last address committed. for i in h._buf.keys(): if ((count > 0x40 or last + 2 != i) and count > 0 and i & 1 == 0): #print "%i, %x, %x" % (len(vals), last, i) client.ARMpokeflashblock(first, vals) count = 0 first = 0 last = 0 vals = [] if (i >= start and i < stop and i & 1 == 0): val = h[i >> 1] if (count == 0): first = i last = i count += 2 vals += [val & 0xff, (val & 0xff00) >> 8] if (i % 0x100 == 0): print "%04x" % i if count > 0: #last commit, ivt client.ARMpokeflashblock(first, vals) client.resume() if (sys.argv[1] == "verify"): f = sys.argv[2] start = 0 stop = 0xFFFF if (len(sys.argv) > 3): start = int(sys.argv[3], 16) if (len(sys.argv) > 4): stop = int(sys.argv[4], 16) client.halt() h = IntelHex16bit(f) for i in h._buf.keys(): if (i >= start and i < stop and i & 1 == 0): peek = client.peek(i) if (h[i >> 1] != peek): print "ERROR at %04x, found %04x not %04x" % (i, peek, h[i >> 1]) if (i % 0x100 == 0): print "%04x" % i client.resume() if (sys.argv[1] == "peek"): start = 0x0000 if (len(sys.argv) > 2): start = int(sys.argv[2], 16) stop = start + 4 if (len(sys.argv) > 3): stop = int(sys.argv[3], 16) print "Peeking from %04x to %04x." % (start, stop) client.halt() for dword in client.ARMreadChunk(start, (stop - start) / 4, verbose=0): print "%.4x: %.8x" % (start, dword) start += 4 client.resume() if (sys.argv[1] == "poke"): start = 0x0000 val = 0x00 if (len(sys.argv) > 2): start = int(sys.argv[2], 16) if (len(sys.argv) > 3): val = int(sys.argv[3], 16) print "Poking %06x to become %04x." % (start, val) client.halt() #???while client.ARMreadMem(start)[0]&(~val)>0: client.ARMwriteChunk(start, [val]) print "Poked to %.8x" % client.ARMreadMem(start)[0] client.resume() if (sys.argv[1] == "reset"): #Set PC to RESET vector's value. #client.ARMsetPC(0x00000000) #client.ARMset_regCPSR(0) #client.ARMreleasecpu() client.ARMresettarget(1000)
def getihex(self): ihex = IntelHex() ihex.puts(self.fw_info.tsb_start, self.tobinstr()) return ihex