def flashHex(target, filename): ''' flash a hex file to nRF51822 ''' ihex = IntelHex(filename) addresses = ihex.addresses() nbytes = len(addresses) addresses.sort() start = time() target.halt() if addresses[0] == 0: logging.info("Erase All") target.writeMemory(NVMC_CONFIG, 2) target.writeMemory(NVMC_ERASEALL, 1) while target.readMemory(NVMC_READY) == 0: pass logging.info("Prepare to write") target.writeMemory(NVMC_CONFIG, 1) while target.readMemory(NVMC_READY) == 0: pass nbytes_align32 = nbytes & ~(32 - 1) for i in range(0, nbytes_align32, 32): if (addresses[i] + 31) == addresses[i + 31]: start_address = addresses[i] # read 32 data bytes bytes = ihex.tobinarray(start=start_address, size=32) target.writeBlockMemoryUnaligned8(start_address, bytes) bytes_readback = target.readBlockMemoryUnaligned8(start_address, 32) for j in range(len(bytes)): if (bytes[j] != bytes_readback[j]): logging.info("Write: error at 0x%X - 0x%X | 0x%X", start_address + j, bytes[j], bytes_readback[j]) raise Exception("Verify Error") else: # data always 4 bytes aligned for j in range(0, 32, 4): start_address = addresses[i + j] bytes = ihex.tobinarray(start=start_address, size=4) target.writeBlockMemoryUnaligned8(start_address, bytes) for i in range(nbytes_align32, nbytes, 4): start_address = addresses[i] bytes = ihex.tobinarray(start=start_address, size=4) target.writeBlockMemoryUnaligned8(start_address, bytes) target.writeMemory(NVMC_CONFIG, 0) while target.readMemory(NVMC_READY) == 0: pass end = time() print("%f kbytes flashed in %f seconds ===> %f kbytes/s" %(nbytes/1000, end-start, nbytes/(1000*(end - start))))
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 ReadConfig( id = '', force_backup = False, clear_code_protect = True): print( "Read config area") if( force_backup == True): try: conf_hex = IntelHex( SAVE_PATH + '/' + List2Hex( id, '') + '_cfg.hex') if( len( conf_hex.tobinarray()) != 256): raise Exception( "ReadConfig: wrong config file size: " + SAVE_PATH + '/' + List2Hex( id, '') + '_cfg.hex') print( "\tloaded config from backup:") DecodeConfig( conf_hex, '\t\t') except: raise Exception( "ReadConfig: no backup config found") print( "\tDone") return conf_hex conf = ReadFlashPage( PAGE_CONF, SIZE_CONF) if( clear_code_protect == True): conf[1] = 0xFF; # disable code-protect hex = {} conf_hex = IntelHex( hex) i = 0 empty = True for c in conf: conf_hex[i] = c i+=1 if( c != 0xFF): empty = False if( id != ''): if( empty == True): try: print( "\tEmpty config area, read config from backup: " + SAVE_PATH + '/' + List2Hex( id, '') + '_cfg.hex') conf_hex = IntelHex( SAVE_PATH + '/' + List2Hex( id, '') + '_cfg.hex') if( len( conf_hex.tobinarray()) != 256): raise Exception( "ReadConfig: wrong config file size: " + SAVE_PATH + '/' + List2Hex( id, '') + '_cfg.hex') print( "\tloaded config from backup:") DecodeConfig( conf_hex, '\t\t') except: raise Exception( "ReadConfig: empty chip and no backup config found") else: conf_hex.tofile( SAVE_PATH + '/' + List2Hex( id, '') + '_cfg.hex', format='hex') print( "\tloaded config from module:") DecodeConfig( conf_hex, '\t\t') print( "\t\tdumped config to: " + SAVE_PATH + '/' + List2Hex( id, '') + '_cfg.hex') print( "\tDone") return conf_hex
def main(): addr = 0 page = 0 port = sys.argv[1] firmware = IntelHex(sys.argv[2]) # Wait for device to appear print "Waiting for device to appear" dev_found = False while dev_found == False: cmd_output = commands.getstatusoutput("ls " + port) if "such" not in cmd_output[1]: dev_found = True print "Device Found!" prog = loader() # try: # except: # print "Usage: "+sys.argv[0]+" name of hex file" # raise SystemExit prog.openSerial(port,57600) prog.getId() prog.getType() prog.getVersion() for i in range(0,len(firmware),128): prog.setAddress(addr) #print "Writing page", hex(addr) prog.writeFlashPage(firmware.tobinarray(start=addr, size=128)) addr += 128 prog.enableRwwSection() prog.ser.close()
def program(self, args): from intelhex import IntelHex nrf = SetupCommand(args) if args.eraseall: nrf.api.erase_all() if args.sectorsanduicrerase: nrf.api.erase_uicr() hex_file = IntelHex(args.file) for segment in hex_file.segments(): start_addr, end_addr = segment size = end_addr - start_addr if args.sectorserase or args.sectorsanduicrerase: start_page = int(start_addr / nrf.device.page_size) end_page = int(end_addr / nrf.device.page_size) for page in range(start_page, end_page + 1): nrf.api.erase_page(page * nrf.device.page_size) data = hex_file.tobinarray(start=start_addr, size=(size)) nrf.api.write(start_addr, data.tolist(), True) if args.verify: read_data = nrf.api.read(start_addr, len(data)) assert (self.byte_lists_equal(data, read_data)), 'Verify failed. Data readback from memory does not match data written.' self._reset(nrf, args) nrf.cleanup()
def _compute_crc(hex_file_path): # Read in hex file new_hex_file = IntelHex() new_hex_file.padding = 0xFF new_hex_file.fromfile(hex_file_path, format='hex') # Get the starting and ending address addresses = new_hex_file.addresses() addresses.sort() start_end_pairs = list(_ranges(addresses)) regions = len(start_end_pairs) assert regions == 1, ("Error - only 1 region allowed in " "hex file %i found." % regions) start, end = start_end_pairs[0] # Compute checksum over the range (don't include data at location of crc) size = end - start + 1 crc_size = size - 4 data = new_hex_file.tobinarray(start=start, size=crc_size) data_crc32 = binascii.crc32(data) & 0xFFFFFFFF # Grab the crc from the image embedded_crc32 = (((new_hex_file[end - 3] & 0xFF) << 0) | ((new_hex_file[end - 2] & 0xFF) << 8) | ((new_hex_file[end - 1] & 0xFF) << 16) | ((new_hex_file[end - 0] & 0xFF) << 24)) return data_crc32, embedded_crc32
def __init__(self, hexfile): try: self.app_size_packet = None self.app_crc_packet = 0xFFFF self.data_packets = [] ih = IntelHex(hexfile) bin_array = ih.tobinarray() fsize = len(bin_array) self.app_size_packet = [(fsize >> 0 & 0xFF), (fsize >> 8 & 0xFF), (fsize >> 16 & 0xFF), (fsize >> 24 & 0xFF)] for i in range(0, len(bin_array), PKT_SIZE): data = (bin_array[i:i+PKT_SIZE]) self.data_packets.append(data) self.crc16_compute(data) crc_packet = self.app_crc_packet self.app_crc_packet = [(crc_packet >> 0 & 0xFF), (crc_packet >> 8 & 0xFF)] except Exception, e1: print "HexToDFUPkts init Exception %s" % str(e1) sys.exit(0)
def main(): args = parser.parse_args() setup_logging(args) # Sanity checks before attaching to board if args.format == 'hex' and not intelhex_available: print("Unable to program hex file") print("Module 'intelhex' must be installed first") exit() if args.list_all: MbedBoard.listConnectedBoards() else: board_selected = MbedBoard.chooseBoard(board_id=args.board_id, target_override=args.target_override, frequency=args.frequency) with board_selected as board: flash = board.flash transport = board.transport # Boost speed with deferred transfers transport.setDeferredTransfer(True) progress = print_progress if args.hide_progress: progress = None chip_erase = None if args.chip_erase: chip_erase = True elif args.sector_erase: chip_erase = False # Binary file format if args.format == 'bin': # If no address is specified use the start of rom if args.address is None: args.address = board.flash.getFlashInfo().rom_start with open(args.file, "rb") as f: f.seek(args.skip, 0) data = f.read() args.address += args.skip data = unpack(str(len(data)) + 'B', data) flash.flashBlock(args.address, data, chip_erase=chip_erase, progress_cb=progress, fast_verify=args.fast_program) # Intel hex file format if args.format == 'hex': hex = IntelHex(args.file) addresses = hex.addresses() addresses.sort() flash_builder = flash.getFlashBuilder() data_list = list(ranges(addresses)) for start, end in data_list: size = end - start + 1 data = list(hex.tobinarray(start=start, size=size)) flash_builder.addData(start, data) flash_builder.program(chip_erase=chip_erase, progress_cb=progress, fast_verify=args.fast_program)
def mpmSecGetVersionNumberFromHex(firmwareName): firmware = IntelHex(firmwareName) firmware_bin = firmware.tobinarray() for i in range(len(firmware_bin) - 3): if chr(firmware_bin[i]) == 'v' and chr(firmware_bin[i + 1]) >= '1' and chr(firmware_bin[i + 1]) <= '9' and chr(firmware_bin[i + 2]) == '.' and chr(firmware_bin[i + 3]) >= '0' and chr(firmware_bin[i + 3]) <= '9': firmware_version = "".join(map(chr, firmware_bin[i:i+4])) return firmware_version return ""
def _program_hex(self, file_obj, **kwargs): hexfile = IntelHex(file_obj) addresses = hexfile.addresses() addresses.sort() data_list = list(ranges(addresses)) for start, end in data_list: size = end - start + 1 data = list(hexfile.tobinarray(start=start, size=size)) self._loader.add_data(start, data)
def verify(self, args): board = self._setup() hex_file = IntelHex(args.file) for segment in hex_file.segments(): start_addr, end_addr = segment size = end_addr - start_addr data = hex_file.tobinarray(start=start_addr, size=size) read_data = board.target.readBlockMemoryUnaligned8(start_addr, size) assert (self.byte_lists_equal(data, read_data)), 'Verify failed. Data readback from memory does not match data written.'
def hex_crc(args): ihex_file = args.file[0] programSize = int(args.size[0]) from intelhex import IntelHex ih = IntelHex() ih.loadfile(ihex_file, format="hex") ih.padding = 0xFF bin = ih.tobinarray(size=programSize) crc = stm32_crc32_bytes(0xffffffff, bin) print(hex(crc)) return 0
def verify(self, args): from intelhex import IntelHex nrf = SetupCommand(args) hex_file = IntelHex(args.file) for segment in hex_file.segments(): start_addr, end_addr = segment size = end_addr - start_addr data = hex_file.tobinarray(start=start_addr, size=size) read_data = nrf.api.read(start_addr, size) assert (self.byte_lists_equal(data, read_data)), 'Verify failed. Data readback from memory does not match data written.' nrf.cleanup()
def dfu_send_image(self): # Open the hex file to be sent ih = IntelHex(self.hexfile_path) bin_array = ih.tobinarray() hex_size = len(bin_array) print "Hex file size: ", hex_size size_array = 8 * [0x00] + convert_uint16_to_array(hex_size) + 2 * [0x00] # Enable Notifications - Setting the DFU Control Point CCCD to 0x0001 self.cpt.start_notify(self.received) # Sending 'START DFU' Command self._dfu_state_set(Commands.START_DFU) self.received_notify = 0 self._dfu_data_send(size_array) while self.received_notify == 0: pass # Send something like an address (sniffed this from the DFU app) self._dfu_state_set("080C00".decode("hex")) self._dfu_state_set(Commands.RECEIVE_FIRMWARE_IMAGE) # Send hex file data packets chunk = 0 self.received_notify = 0 for i in range(0, hex_size, 20): data_to_send = bin_array[i:i + 20] self._dfu_data_send(data_to_send) time.sleep(0.01) chunk += 1 if chunk % 15 == 0: while self.received_notify == 0: pass self.received_notify = 0 self.received_notify = 0 while self.received_notify == 0: pass self.received_notify = 0 # Send Validate Command self._dfu_state_set(Commands.VALIDATE_FIRMWARE_IMAGE) # Wait for notification while self.received_notify == 0: pass # Send Activate and Reset Command self._dfu_state_set(Commands.ACTIVATE_FIRMWARE_AND_RESET)
def _program_hex(self, file_obj, **kwargs): """! Intel hex file format loader""" hexfile = IntelHex(file_obj) addresses = hexfile.addresses() addresses.sort() data_list = list(ranges(addresses)) for start, end in data_list: size = end - start + 1 data = list(hexfile.tobinarray(start=start, size=size)) # Ignore invalid addresses for HEX files only # Binary files (obviously) don't contain addresses # For ELF files, any metadata that's not part of the application code # will be held in a section that doesn't have the SHF_WRITE flag set try: self._loader.add_data(start, data) except ValueError as e: LOG.warning("Failed to add data chunk: %s", e)
def load(self, path): """Load an image from a given file""" ext = os.path.splitext(path)[1][1:].lower() if ext == INTEL_HEX_EXT: ih = IntelHex(path) self.payload = ih.tobinarray() self.base_addr = ih.minaddr() else: with open(path, 'rb') as f: self.payload = f.read() # Add the image header if needed. if self.pad_header and self.header_size > 0: if self.base_addr: # Adjust base_addr for new header self.base_addr -= self.header_size self.payload = bytes([self.erased_val] * self.header_size) + \ self.payload self.check()
def GetHexCrc(file): # convert hex to bin ih = IntelHex() ih.fromfile(file, format='hex') bf = ih.tobinarray() #pad the array (flash size) for CRC calculation 220kb while len(bf) < (220 * 1024): bf.append(255) # calculate checksum for APP_HEX crc32_func = crcmod.mkCrcFun(int(0x104c11db7), initCrc=int(0xffffffff), rev=False, xorOut=0) checksum_val = crc32_func(bytearray(bf)) checksum_val = f'0x{checksum_val:X}' return checksum_val
def _program_hex(self, file_obj: IO[bytes], **kwargs: Any) -> None: """! Intel hex file format loader""" assert self._loader hexfile = IntelHex(file_obj) addresses = hexfile.addresses() addresses.sort() data_list = list(ranges(addresses)) for start, end in data_list: size = end - start + 1 data = list(hexfile.tobinarray(start=start, size=size)) # Ignore invalid addresses for HEX files only # Binary files (obviously) don't contain addresses # For ELF files, any metadata that's not part of the application code # will be held in a section that doesn't have the SHF_WRITE flag set try: self._loader.add_data(start, data) except ValueError as e: LOG.warning("Failed to add data chunk: %s", e)
def load(self, path): """Load an image from a given file""" ext = os.path.splitext(path)[1][1:].lower() if ext == INTEL_HEX_EXT: ih = IntelHex(path) self.payload = ih.tobinarray() self.image_address = ih.minaddr() self.slot_address = self.image_address - self.image_offset self.size = len(self.payload) self.payload = (b'\xff' * self.image_offset) + self.payload else: if self.slot_address is None: raise Exception("Input type bin requires a slot address") with open(path, 'rb') as f: self.payload = f.read() self.size = len(self.payload) # Add empty image header. self.payload = (b'\xff' * self.image_offset) + self.payload self.image_address = self.slot_address + self.image_offset self.check()
def loadFirmwareFromHex(filename): """Loads firmware image from hex file. @param filename valid firmware in intel hex format @return tuple (start address, list of segments, crc for firmware) """ import array import crc16 from intelhex import IntelHex SEGMENT_SIZE = 256 CRC_START = 0xFFFF PADDING_BYTE = 0xFF ih = IntelHex(filename) startaddr = ih.minaddr() bin = ih.tobinarray() segcount = (len(bin) - 1) / SEGMENT_SIZE + 1 segs = [] # create packets for i in xrange(segcount): # fill array with default value if necessary b = bin[(i * SEGMENT_SIZE):((i + 1) * SEGMENT_SIZE)] segs.append(b) # use padding for last segment (a generator expression is used) b.extend((PADDING_BYTE for x in xrange(len(b), SEGMENT_SIZE))) #crcfile = open("crcs.dat", 'w') # create CRC16 for crc = CRC_START #k = 0 for s in segs: crc = crc16.crc16xmodem(s.tostring(), crc) #crcfile.write(str(k) + " " + str(crc) + "\n") #k += 1 return (startaddr, segs, crc)
def dfu_send_image(self): # Open the hex file to be sent ih = IntelHex(self.hexfile_path) bin_array = ih.tobinarray() hex_size = len(bin_array) print "Hex file size: ", hex_size # Enable Notifications - Setting the DFU Control Point CCCD to 0x0001 self._dfu_enable_cccd() # Sending 'START DFU' Command self._dfu_state_set(Commands.START_DFU) # Transmit image size hex_size_array_lsb = convert_uint32_to_array(len(bin_array)) self._dfu_data_send(hex_size_array_lsb) print "Sending hex file size" # Send 'RECEIVE FIRMWARE IMAGE' command to set DFU in firmware receive state. self._dfu_state_set(Commands.RECEIVE_FIRMWARE_IMAGE) # Send hex file data packets chunk = 1 for i in range(0, hex_size, 20): data_to_send = bin_array[i:i + 20] self._dfu_data_send(data_to_send) print "Chunk #", chunk chunk += 1 # Send Validate Command self._dfu_state_set(Commands.VALIDATE_FIRMWARE_IMAGE) # Wait a bit for copy on the peer to be finished time.sleep(1) # Send Activate and Reset Command self._dfu_state_set(Commands.ACTIVATE_FIRMWARE_AND_RESET)
def _download(self, addr, filename): """Downloads a binary file to the target system Args: addr: Start address where the binary file is stored filename: File name of the binary file """ import platform if platform.architecture()[0] == '64bit': filenamebuf = c_char_p(filename.encode('UTF-8')) c_addr = c_uint32(addr) self.jl.JLINK_DownloadFile(filenamebuf, c_addr) else: from intelhex import IntelHex ih = IntelHex() extension = os.path.splitext(filename)[1][1:] ih.fromfile(filename,format=extension) for (a, d) in zip(ih.addresses(), ih.tobinarray()): self.wr_mem(8, addr+a, d)
def get_firmware_object(sk_name, hex_file): from ecdsa import SigningKey, NIST256p sk = SigningKey.from_pem(open(sk_name).read()) fw = open(hex_file, "r").read() fw = base64.b64encode(fw.encode()) fw = to_websafe(fw.decode()) ih = IntelHex() ih.fromfile(hex_file, format="hex") # start of firmware and the size of the flash region allocated for it. # TODO put this somewhere else. START = ih.segments()[0][0] END = (0x08000000 + ((128 - 19) * 2048)) - 8 ih = IntelHex(hex_file) segs = ih.segments() arr = ih.tobinarray(start=START, size=END - START) im_size = END - START print("im_size: ", im_size) print("firmware_size: ", len(arr)) byts = (arr).tobytes() if hasattr(arr, "tobytes") else (arr).tostring() h = sha256() h.update(byts) sig = binascii.unhexlify(h.hexdigest()) print("hash", binascii.hexlify(sig)) sig = sk.sign_digest(sig) print("sig", binascii.hexlify(sig)) sig = base64.b64encode(sig) sig = to_websafe(sig.decode()) # msg = {'data': read()} msg = {"firmware": fw, "signature": sig} return msg
def input_setup(self): print "input_setup" if self.hexfile_path == None: raise Exception("input invalid") name, extent = os.path.splitext(self.hexfile_path) if extent == ".bin": self.bin_array = array('B', open(self.hexfile_path, 'rb').read()) self.hex_size = len(self.bin_array) print "bin array size: ", self.hex_size return if extent == ".hex": intelhex = IntelHex(self.hexfile_path) self.bin_array = intelhex.tobinarray() self.hex_size = len(self.bin_array) print "bin array size: ", self.hex_size return raise Exception("input invalid")
def _process_image(self): """ Read image address and size and calculate image hash """ ih = IntelHex(self.image) ih.padding = 0x00 image_addr = ih.minaddr() image_size = ih.maxaddr() - ih.minaddr() + 1 sha256 = hashlib.sha256() sha256.update(ih.tobinarray(start=image_addr, size=image_size)) image_hash = sha256.digest() image_attr = dict() image_attr['image_hash'] = image_hash image_attr['image_addr'] = image_addr image_attr['image_size'] = image_size image_attr['image_id'] = self.image_id image_attr['version'] = self.version return image_attr
def load_ihex(self, filename): """ Load from intel hex format """ self.logger.info("Loading from hexfile '{}'".format(filename)) from intelhex import IntelHex ih = IntelHex() ih.loadhex(filename) data = ih.tobinarray() start_address = ih.minaddr() self.logger.info("Loaded {0:d} bytes from ihex starting at address 0x{1:04X}".format(len(data), start_address)) # Size check if len(data) > self.device.flash_size: raise Exception("ihex too large for flash") # Offset to actual flash start if start_address < self.device.flash_start: self.logger.info("Adjusting flash offset to address 0x{:04X}".format(self.device.flash_start)) start_address += self.device.flash_start return data, start_address
def _build_record(slot_number, image_path, record_type, args): """Builds the appropriate record for the slot given the specified record type""" hex_data = IntelHex(image_path) hex_data.padding = 0xFF offset = hex_data.minaddr() bin_data = bytearray(hex_data.tobinarray(offset, hex_data.maxaddr())) if slot_number == 0: # If slot is controller if record_type == 2: # kReflashControllerTile return ReflashControllerRecord(bin_data, offset) elif record_type == 3: # kExecuteRPCWithoutCheck pass # Not implemented yet elif record_type == 4: # kExecuteRPCWithCheck pass # Not implemented yet elif record_type == 5: # kResetController pass # Not implemented yet elif record_type == 6: # kEnhancedReflashControllerTile if args['reboot'] == "True": skip_reboot_flag = 0 else: skip_reboot_flag = 1 return EnhancedReflashControllerRecord(bin_data, offset, flags=skip_reboot_flag) else: raise BuildError("Invalid record type for this slot.", slot=slot_number, record=record_type) else: # If slot is a tile if record_type == 1: # kReflashExternalTile return ReflashTileRecord(slot_number, bin_data, offset) else: raise BuildError("Invalid record type for this slot.", slot=slot_number, record=record_type)
def main(): inifile = configparser.ConfigParser() inifile.read('bootloader.ini') comport = inifile.get('settings', 'comport') # baudrate = inifile.get('settings', 'baudrate') print('-------------------------------------------------------- START {}'. format(sys.argv[0])) bl = stm32bootloader(comport) if bl.init() < 0: return 1 # error if 0 != bl.set_loadermode(): print('boot loaderに同期できません。') return 1 # error # --------------------------------------------------------------- fn = 'template.hex' try: ih = IntelHex(fn) except FileNotFoundError: print('ファイルが見つかりません [{}]'.format(fn)) return 1 # error file_buf = ih.tobinarray() file_size = len(file_buf) file_md5 = hashlib.md5(file_buf).hexdigest() flash_buf = bl.ReadMemory(0x08000000, file_size) flash_size = len(flash_buf) flash_md5 = hashlib.md5(flash_buf).hexdigest() print('{} {:7d} {}'.format(fn, file_size, file_md5)) print(' FLASH {:7d} {}'.format(flash_size, flash_md5)) with open('flash.bin', 'wb') as f: f.write(flash_buf) if flash_md5 != file_md5: print('MD5 チェックサムエラー') return 1 # error print('MD5 チェックサム OK') return 0 # no error
def upload(filename): ih = IntelHex(filename) #Transfer programm data dev.ctrl_transfer(0x40, 0xa0, 0, 0 , ih.tobinarray())
def hexFileToArr(filename): log.i("filename " + filename) ih = IntelHex(filename) buf = ih.tobinarray() log.d("End and start of the binary: " + str(ih._get_start_end())) return buf
def generateFlashAndEepromHex(originalFlashHexName, bootloaderHexName, serialNumber, AESKey1, AESKey2, UIDKey, UID, newFlashHexName, newEeepromHex, verbose): FW_MAX_LENGTH = 28672 BL_MAX_LENGTH = 4096 AES_KEY_LENGTH = 256/8 AES_BLOCK_LENGTH = 128/8 UID_REQUEST_KEY_LENGTH = 16 UID_KEY_LENGTH = 6 # Check for original firmware file presence if not os.path.isfile(originalFlashHexName): print "Couldn't find firmware hex file", originalFlashHexName return False # Check for bootloader file presence if not os.path.isfile(bootloaderHexName): print "Couldn't find bootloader hex file", bootloaderHexName return False # Check AES Key Length if len(AESKey1) != AES_KEY_LENGTH: print "Wrong AES Key1 length!" return False # Check AES Key Length if len(AESKey2) != AES_KEY_LENGTH: print "Wrong AES Key2 length!" return False # Check UID Req Key Length if len(UIDKey) != UID_REQUEST_KEY_LENGTH: print "Wrong UID request key length!" return False # Check UID Key Length if len(UID) != UID_KEY_LENGTH: print "Wrong UID key length!" return False # Read firmware Hex flashHex = IntelHex(originalFlashHexName) if len(flashHex) > FW_MAX_LENGTH: print "Firmware file too long:", len(flashHex), "bytes long" return False else: if verbose == True: print "Firmware file is", len(flashHex), "bytes long" # Read bootloader hex bootloaderHex = IntelHex(bootloaderHexName) if len(bootloaderHex) > BL_MAX_LENGTH: print "Bootloader file too long:", len(bootloaderHex), "bytes long" return False else: if verbose == True: print "Bootloader file is", len(bootloaderHex), "bytes long" # Merge firmware with bootloader flashHex.merge(bootloaderHex) # Print hash if need if verbose == True: print "Original Firmware/Bootloader Hash:", hashlib.sha1(flashHex.tobinarray()).hexdigest() # Check there's nothing where we want to put the serial number if flashHex[0x7F7C] != 0xFF: print "No space to write serial number inside the bootloader hex!" return False # Include serial number in the hex to be flashed flashHex[0x7F7C] = (serialNumber >> 24) & 0x000000FF flashHex[0x7F7D] = (serialNumber >> 16) & 0x000000FF flashHex[0x7F7E] = (serialNumber >> 8) & 0x000000FF flashHex[0x7F7F] = (serialNumber >> 0) & 0x000000FF # Write production firmware file flashHex.tofile(newFlashHexName, format="hex") # Generate blank eeprom file eepromHex = IntelHex() for i in range(0x400): eepromHex[i] = 0xFF # Modify the byte in eeprom to indicate normal boot # Address 0: 0xDEAD, little endian eepromHex[0] = 0xAD eepromHex[1] = 0xDE # Address 2: 0xAB (bootloader password set) eepromHex[2] = 0xAB # Address 98: mass production boolean eepromHex[98] = 0xCD # Address 999: boolean specifiying that uid key is set eepromHex[999] = 0xBB # Address 1000: UID request key eepromHex[1000:1000+UID_REQUEST_KEY_LENGTH] = UIDKey # Address 1016: UID key eepromHex[1000+UID_REQUEST_KEY_LENGTH:1000+UID_REQUEST_KEY_LENGTH+UID_KEY_LENGTH] = UID # Address 0x03: 32 bytes of AES key 1 + 30 first bytes of AES key 2 eepromHex[3:3+AES_KEY_LENGTH] = AESKey1 eepromHex[3+AES_KEY_LENGTH:3+AES_KEY_LENGTH+30] = AESKey2[0:30] # Last 2 bytes in EEPROM: last 2 AESKey 2 bytes eepromHex[0x400-2] = AESKey2[30] eepromHex[0x400-1] = AESKey2[31] # Write new eeprom file eepromHex.tofile(newEeepromHex, format="hex")
def main(): args = parser.parse_args() setup_logging(args) # Sanity checks before attaching to board if args.format == 'hex' and not intelhex_available: print("Unable to program hex file") print("Module 'intelhex' must be installed first") exit() if args.list_all: MbedBoard.listConnectedBoards() else: board_selected = MbedBoard.chooseBoard(board_id=args.board_id, target_override=args.target_override, frequency=args.frequency) with board_selected as board: flash = board.flash transport = board.transport # Boost speed with deferred transfers transport.setDeferredTransfer(True) progress = print_progress if args.hide_progress: progress = None has_file = args.file is not None chip_erase = None if args.chip_erase: chip_erase = True elif args.sector_erase: chip_erase = False if not has_file: if chip_erase: print("Erasing chip...") flash.init() flash.eraseAll() print("Done") elif args.sector_erase and args.address is not None: flash.init() page_addr = args.address for i in range(args.count): page_info = flash.getPageInfo(page_addr) if not page_info: break # Align page address on first time through. if i == 0: delta = page_addr % page_info.size if delta: print("Warning: sector address 0x%08x is unaligned" % page_addr) page_addr -= delta print("Erasing sector 0x%08x" % page_addr) flash.erasePage(page_addr) page_addr += page_info.size else: print("No operation performed") return # If no format provided, use the file's extension. if not args.format: args.format = os.path.splitext(args.file)[1][1:] # Binary file format if args.format == 'bin': # If no address is specified use the start of rom if args.address is None: args.address = board.flash.getFlashInfo().rom_start with open(args.file, "rb") as f: f.seek(args.skip, 0) data = f.read() args.address += args.skip data = unpack(str(len(data)) + 'B', data) flash.flashBlock(args.address, data, chip_erase=chip_erase, progress_cb=progress, fast_verify=args.fast_program) # Intel hex file format elif args.format == 'hex': hex = IntelHex(args.file) addresses = hex.addresses() addresses.sort() flash_builder = flash.getFlashBuilder() data_list = list(ranges(addresses)) for start, end in data_list: size = end - start + 1 data = list(hex.tobinarray(start=start, size=size)) flash_builder.addData(start, data) flash_builder.program(chip_erase=chip_erase, progress_cb=progress, fast_verify=args.fast_program) else: print("Unknown file format '%s'" % args.format)
def upgrade_fluke(url=None): #define UF_SUCCESS 42 #define UF_ERROR 1 #define UF_SEGMENT_SIZE 132 if myro.globvars.robot == None: print("Connecting to Fluke for firmware installation...") myro.globvars.robot = SerialRobot() s = myro.globvars.robot.ser info = get_info_timeout(s) if "fluke" in info: info = info["fluke"] else: info = "0.0.0" elif myro.globvars.robot.dongle: info = myro.globvars.robot.dongle s = myro.globvars.robot.ser print(info) version = list(map(int, info.split("."))) print("Version of fluke", version) if version <= [2, 4, 0]: print("(If you just upgraded Myro, please restart Python.)") print("Sorry, I can't upgrade the Fluke over Bluetooth.") print( "It must be upgraded manually over the serial port using lpc21isp." ) print("Please see http://wiki.roboteducation.org/IPRE_Fluke_Setup") return if url == None: #url = "http://myro.roboteducation.org/upgrade/fluke/" url = "http://www.betterbots.com/upgrade/fluke/" install_count = 0 filename = None if url.startswith("http://"): #fluke_ver = info["fluke"].split(".") print("Looking for Fluke upgrade at", url, "...") myro_ver = myro_version.split(".") # go to site, check for latest greater than our version #infp = urlopen(url) try: infp = urlopen(url) except: print( "ERROR: There was an error connecting to the web to download updates. Please check your internet connection. For example, see if you can access", url, "using a web browser.") return if version >= [3, 0, 0]: upgrade_prefix = "/fluke2-upgrade-" else: upgrade_prefix = "/fluke-upgrade-" contents = infp.read().decode('utf-8') lines = contents.split("\n") infp.close() for file in lines: file = file.strip() if file != "" and file[0] != '#': print("Considering", file, "...") if file.startswith(upgrade_prefix): end = file.index(".hex") #patch_ver = file[15:end].split(".") patch_ver = file[len(upgrade_prefix):end].split(".") print(patch_ver, version) if list(map(int, patch_ver)) > list(map(int, version)): # download it print(" Downloading...") filename = url_retrieve(url + file) break else: filename = url if filename == None: print("Nothing found to upgrade!") return #info = myro.globvars.robot.getInfo() sendMagicKey = True if version <= [2, 5, 0]: sendMagicKey = False print("Older firmware version, Not sending magic key") else: print("Sending magic key") if version >= [3, 0, 0]: import time s.flushOutput() s.flushInput() print("Sending firmware") s.write(mybytes(UPDATE_FIRMWARE)) # magic code to ensure we don't enter program by accident s.write(mybytes(0x01)) s.write(mybytes(0x23)) upfp = open(filename, "rb") bytes = upfp.read() upfp.close() size = len(bytes) s.write(mybytes((size >> 24) & 0xFF)) s.write(mybytes((size >> 16) & 0xFF)) s.write(mybytes((size >> 8) & 0xFF)) s.write(mybytes((size) & 0xFF)) while True: ns = s.write(bytes) if ns == 0 or ns == None: break size -= ns if size <= 0: break bytes = bytes[ns:] sys.stdout.write('.') print( "Installing update. Do not turn off the Fluke2 while the red CPU activity LED is flashing brightly." ) for i in range(21): time.sleep(3) sys.stdout.write('.') print("") print( "Finalizing installation. Please exit and restart Python and Myro." ) else: from intelhex import IntelHex import time ih = IntelHex(filename) binarray = ih.tobinarray() arlen = len(binarray) print("%d bytes of firmware." % arlen) print("checksumming interrupt vectors") sum = check_sum(binarray, arlen) #declare a finite sized array to hold eeprom dump. #Dynamic appending of lists always comes with a performance hit eepromdump = [0] * 135168 s.flushOutput() s.flushInput() #print "Getting old EEPROM" #s.write(mybytes(SAVE_EEPROM)) #uf_saveEEPROMdump() print("Sending firmware") s.write(mybytes(UPDATE_FIRMWARE)) if sendMagicKey: # magic code to ensure we don't enter program by accident s.write(mybytes(0x01)) s.write(mybytes(0x23)) uf_storeinEEPROM(s, arlen, binarray) print("Waiting for reboot...") time.sleep(2) print( "Done upgrading! Please turn your robot off and then back on, and exit and restart Python and Myro." ) s.close()
def dfu(serial, connect_attempts, detach, dry_run, firmware): """Program via STMicroelectronics DFU interface. Enter dfu mode using `solo program aux enter-dfu` first. """ import time import usb.core from intelhex import IntelHex dfu = solo.dfu.find(serial, attempts=connect_attempts) if dfu is None: print("No STU DFU device found.") if serial is not None: print("Serial number used: ", serial) sys.exit(1) dfu.init() if not dry_run: # The actual programming # TODO: move to `operations.py` or elsewhere ih = IntelHex() ih.fromfile(firmware, format="hex") chunk = 2048 # Why is this unused # seg = ih.segments()[0] size = sum([max(x[1] - x[0], chunk) for x in ih.segments()]) total = 0 t1 = time.time() * 1000 print("erasing...") try: dfu.mass_erase() except usb.core.USBError: # garbage write, sometimes needed before mass_erase dfu.write_page(0x08000000 + 2048 * 10, "ZZFF" * (2048 // 4)) dfu.mass_erase() page = 0 for start, end in ih.segments(): for i in range(start, end, chunk): page += 1 data = ih.tobinarray(start=i, size=chunk) dfu.write_page(i, data) total += chunk # here and below, progress would overshoot 100% otherwise progress = min(100, total / float(size) * 100) sys.stdout.write( "downloading %.2f%% %08x - %08x ... \r" % (progress, i, i + page)) # time.sleep(0.100) # print('done') # print(dfu.read_mem(i,16)) t2 = time.time() * 1000 print() print("time: %d ms" % (t2 - t1)) print("verifying...") progress = 0 for start, end in ih.segments(): for i in range(start, end, chunk): data1 = dfu.read_mem(i, 2048) data2 = ih.tobinarray(start=i, size=chunk) total += chunk progress = min(100, total / float(size) * 100) sys.stdout.write("reading %.2f%% %08x - %08x ... \r" % (progress, i, i + page)) if (end - start) == chunk: assert data1 == data2 print() print("firmware readback verified.") if detach: dfu.prepare_options_bytes_detach() dfu.detach() print("Please powercycle the device (pull out, plug in again)") hot_patch_windows_libusb()
def load(mw, transport, args): bl = MW.Bootloader() bl.start() sleep(1) retval = 1 uid = MW.BootMsg.UID.getUIDFromHexString(args.uid[0]) ihex_file = args.file[0] if not uid in bl.getSlaves(): print("Device is not in bootload mode") return 1 if not bl.select(uid): print("Cannot select device") return 1 try_again = True if try_again: desc = bl.describe_v3(uid) if desc is None: try_again = True else: print("TARGET:" + formatDescription_V3(uid, desc)) try_again = False if try_again: desc = bl.describe_v2(uid) if desc is None: try_again = True else: print("TARGET:" + formatDescription_V2(uid, desc)) try_again = False if try_again: retval = 1 else: programSize = desc.program ih = IntelHex() ih.loadfile(ihex_file, format="hex") ih.padding = 0xFF bin = ih.tobinarray(size=programSize) crc = stm32_crc32_bytes(0xffffffff, bin) print("CRC: " + hex(crc)) what = args.what[0] if what == 'program': if not bl.eraseProgram(uid): print("Cannot erase program") return 1 with open(ihex_file) as f: data = f.read().splitlines() write_ihex(bl, data, crc) if what == 'program': if not bl.write_program_crc(uid, crc): print("Cannot write CRC") return 1 bl.deselect(uid) bl.stop() return retval
def use_dfu(args): fw = args.__dict__["[firmware]"] for i in range(0, 8): dfu = DFUDevice() try: dfu.find(ser=args.dfu_serial) except RuntimeError: time.sleep(0.25) dfu = None if dfu is None: print("No STU DFU device found. ") if args.dfu_serial: print("Serial number used: ", args.dfu_serial) sys.exit(1) dfu.init() if fw: ih = IntelHex() ih.fromfile(fw, format="hex") chunk = 2048 seg = ih.segments()[0] size = sum([max(x[1] - x[0], chunk) for x in ih.segments()]) total = 0 t1 = time.time() * 1000 print("erasing...") try: dfu.mass_erase() except usb.core.USBError: dfu.write_page(0x08000000 + 2048 * 10, "ZZFF" * (2048 // 4)) dfu.mass_erase() page = 0 for start, end in ih.segments(): for i in range(start, end, chunk): page += 1 s = i data = ih.tobinarray(start=i, size=chunk) dfu.write_page(i, data) total += chunk progress = total / float(size) * 100 sys.stdout.write( "downloading %.2f%% %08x - %08x ... \r" % (progress, i, i + page)) # time.sleep(0.100) # print('done') # print(dfu.read_mem(i,16)) t2 = time.time() * 1000 print() print("time: %d ms" % (t2 - t1)) print("verifying...") progress = 0 for start, end in ih.segments(): for i in range(start, end, chunk): data1 = dfu.read_mem(i, 2048) data2 = ih.tobinarray(start=i, size=chunk) total += chunk progress = total / float(size) * 100 sys.stdout.write("reading %.2f%% %08x - %08x ... \r" % (progress, i, i + page)) if (end - start) == chunk: assert data1 == data2 print() print("firmware readback verified.") if args.detach: dfu.detach()
def _build_reflash_script_action(target, source, env): """Create a TRUB script containing tile and controller reflashes and/or sensorgraph If the app_info is provided, then the final source file will be a sensorgraph. All subsequent files in source must be in intel hex format. This is guaranteed by the ensure_image_is_hex call in build_update_script. """ out_path = str(target[0]) source = [str(x) for x in source] records = [] if env['USE_SAFEUPDATE']: sgf_off = SendRPCRecord(8, 0x2005, bytearray([0])) # Disable Sensorgraph records.append(sgf_off) safemode_enable = SendRPCRecord(8, 0x1006, bytearray([1])) # Enable Safemode records.append(safemode_enable) # Update application firmwares if env['SLOTS'] is not None: for (controller, slot_id), image_path in zip(env['SLOTS'], source): hex_data = IntelHex(image_path) hex_data.padding = 0xFF offset = hex_data.minaddr() bin_data = bytearray( hex_data.tobinarray(offset, hex_data.maxaddr())) if controller: record = ReflashControllerRecord(bin_data, offset) else: record = ReflashTileRecord(slot_id, bin_data, offset) records.append(record) # Update sensorgraph if env['UPDATE_SENSORGRAPH']: sensor_graph_file = source[-1] sensor_graph = compile_sgf(sensor_graph_file) output = format_script(sensor_graph) records += UpdateScript.FromBinary(output).records # Update App and OS Tag os_info = env['OS_INFO'] app_info = env['APP_INFO'] if os_info is not None: os_tag, os_version = os_info records.append(SetDeviceTagRecord(os_tag=os_tag, os_version=os_version)) if app_info is not None: app_tag, app_version = app_info records.append( SetDeviceTagRecord(app_tag=app_tag, app_version=app_version)) if env['USE_SAFEUPDATE']: safemode_disable = SendRPCRecord(8, 0x1006, bytearray([0])) # Disable safemode records.append(safemode_disable) sgf_on = SendRPCRecord(8, 0x2005, bytearray([1])) # Enable Sensorgraph records.append(sgf_on) script = UpdateScript(records) with open(out_path, "wb") as outfile: outfile.write(script.encode())
#ih.dump() print("Erasing...") sendblock(0x41,[1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8]) ser.timeout=1 ackdat=ser.read(1) if ackdat: print("\t",ackdat) else: print("timeout") # break print("Programming...") for addr in range(0, bootstart, 16): sendblock(0x42,ih.tobinarray(start=addr, size=16)) ser.timeout=0.2 ackdat=ser.read(1) if ackdat: print("addr:",hex(addr),ackdat) else: print("timeout") print("Done!") break except KeyboardInterrupt: print("Aborted!") break
def load(self, path): ih = IntelHex(path) return ih.tobinarray(), ih.minaddr()
if args.update: print("reading input file: {}".format(args.filename)) try: ih.fromfile(args.filename, format='hex') except FileNotFoundError: exit_by_error(msg="file not found") except (AddressOverlapError, HexRecordError): exit_by_error(msg="error, file format") print("writing flash: {} bytes".format(ih.maxaddr())) bar = progressbar.ProgressBar(max_value=ih.maxaddr(), prefix="writing ") bar.start(init=True) for address in range(0, ih.maxaddr(), ab.cpu_page_size): buffer = ih.tobinarray(start=address, size=ab.cpu_page_size) if not prg.write_memory(buffer, address): exit_by_error(msg="writing flash memory") bar.update(address) bar.finish() dict_hex = dict() if args.update: max_address = ih.maxaddr() print("reading and verifying flash memory") elif args.read: max_address = int(ab.cpu_page_size * ab.cpu_pages) print("reading flash memory")
def upload(filename): ih = IntelHex(filename) #Transfer programm data dev.ctrl_transfer(0x40, 0xa0, 0, 0, ih.tobinarray())
print str('-' * (len(sHexFilePath) + 20)) print "Hex File Path = \"" + sHexFilePath + "\"" print str('-' * (len(sHexFilePath) + 20)) # Fetching Hex File and Storing hexFile = IntelHex(sHexFilePath) if sGenerateBinary == "y": # Create a Binary File of this Hex File sBinFilePath = string.replace(sHexFilePath, ".hex", ".bin") logging.debug("Binary File Path : %s", sBinFilePath) hexFile.tofile(sBinFilePath, format='bin') # Obtain the actual Binary content from the Hex File binArray = hexFile.tobinarray() sPort = serial.Serial(port=sDeviceFile, baudrate=sInitialDeviceBaud, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS) # sPort.rts = True # sPort.dtr = True # time.sleep(2) # Put device into reset state sPort.rts = True sPort.dtr = True time.sleep(0.5)
#print "Writing %d segments" % segs write_2byte(s,segs) for i in range (0,segs) : print '\r' + "%d %%" % ((i*100)/segs), sys.stdout.flush() uf_sendPage(i,binarray) print "" if len(sys.argv) < 2: print sys.argv[0], "firmware-file-as-hex" sys.exit(-1) ih = IntelHex(sys.argv[1]) binarray = ih.tobinarray() arlen = len(binarray) print "%d bytes of firmware." % arlen #print "checksumming interrupt vectors" for i in range(20,24): binarray[i] = 0 sum=0 for i in range(0,8): temp_int = 0 temp_int = binarray[i*4 + 0] | binarray[i*4 + 1] << 8 | binarray[i*4 + 2] << 16 | binarray[i*4 + 3] << 24 sum = sum + temp_int sum = -sum binarray[20] = sum & 0x000000ff
def main(): # Check if one input argument is provided if len(sys.argv) != 2: print "Usage:", sys.argv[0], "bootloader.hex" sys.exit(1) # Input arguments hexfile = sys.argv[1] # Check if file exists if not os.path.isfile(hexfile): print "Error: File does not exist." sys.exit(2) # Read bootloader data bootloader = IntelHex(hexfile) bootloader_bin = bootloader.tobinarray() #bootloader.dump() # Start address loaderStart = bootloader.minaddr() # Given a start address, deduce where the bootloader ends end_addresses = { 0x1000: 0x2000, 0x1C00: 0x2000, 0x1D00: 0x2000, 0x1E00: 0x2000, 0x3000: 0x4000, 0x3800: 0x4000, 0x3E00: 0x4000, 0x7000: 0x8000, 0x7800: 0x8000, 0x7E00: 0x8000, 0xF800: 0x10000, 0x1F000: 0x20000, 0x1FC00: 0x20000, 0x3E000: 0x40000, } if not loaderStart in end_addresses: print "Error: Unkown bootloader start address." sys.exit(3) loaderEnd = end_addresses[loaderStart] # Len loaderLen = loaderEnd - loaderStart if loaderLen < len(bootloader_bin): print "Error: Invalid bootloader length." sys.exit(4) # Calculate md5sum from hexfile and add padding bytes with 0xFF md5 = hashlib.md5() md5.update(bootloader_bin) padding = [0xFF] * (loaderLen - len(bootloader_bin)) md5.update(bytearray(padding)) # Calculatae md5sum from the original file so we know which disk file it came from filemd5 = hashlib.md5() fd = open(hexfile, 'rb') filemd5.update(fd.read()) fd.close() # Filename without full path and without ".hex" filename = os.path.splitext(os.path.basename(hexfile))[0] # Print header print '// File =', filename + ".hex" print '// Loader start:', hex(loaderStart), 'length', loaderLen print '// Bootloader MD5 sum =', md5.hexdigest() print '// Original file MD5 sum =', filemd5.hexdigest() print print 'const uint8_t', filename + '_hex [] PROGMEM = {' # Print data line = "" for i in range(len(bootloader_bin)): line += hex(bootloader_bin[i]) + ', ' if i % 16 == 15: print line line = '' if line: print line # Print footer print '}; // end of', filename + '_hex'
def dfu_send_image(self): # scan for characteristics: status = self._dfu_check_mode() if not status: return False self._dfu_get_handles() # Enable Notifications - Setting the DFU Control Point CCCD to 0x0001 status = self._dfu_enable_cccd() if not status: return False # Open the hex file to be sent ih = IntelHex(self.hexfile_path) bin_array = ih.tobinarray() hex_size = len(bin_array) # print "Hex file size: ", hex_size # Sending 'START DFU' Command self._dfu_state_set(Commands.START_DFU) # Transmit image size hex_size_array_lsb = convert_uint32_to_array(len(bin_array)) self._dfu_data_send(hex_size_array_lsb) # print "Sending hex file size" # Send 'RECEIVE FIRMWARE IMAGE' command to set DFU in firmware receive state. self._dfu_state_set(Commands.RECEIVE_FIRMWARE_IMAGE) print "Start sending data" # Send hex file data packets timeStart = time.time() chunk = 1 self.ble_conn.delaybeforesend = 0.0 for i in range(0, hex_size, CHUNK_SIZE): data_to_send = bin_array[i:i + CHUNK_SIZE] self._dfu_data_send(data_to_send) if chunk % 100 == 0: print "Chunk #", chunk, "/" , hex_size / CHUNK_SIZE chunk += 1 print "Firmware transferred in ", time.time() - timeStart self.ble_conn.delaybeforesend = 0.05 time.sleep(1) # Send Validate Command print "Validating..." status = self._dfu_state_set(Commands.VALIDATE_FIRMWARE_IMAGE) if not status: print "Could not validate firmware." return False # Wait a bit for copy on the peer to be finished time.sleep(3) # Send Activate and Reset Command status = self._dfu_state_set(Commands.ACTIVATE_FIRMWARE_AND_RESET) if not status: print "Could not activate." return False print "Validated. Rebooting application." return True
def program_file(self, name): def parseField(f): return base64.b64decode(helpers.from_websafe(f).encode()) def isCorrectVersion(current, target): """ current is tuple (x,y,z). target is string '>=x.y.z'. Return True if current satisfies the target expression. """ if "=" in target: target = target.split("=") assert target[0] in [">", "<"] target_num = [int(x) for x in target[1].split(".")] assert len(target_num) == 3 comp = target[0] + "=" else: assert target[0] in [">", "<"] target_num = [int(x) for x in target[1:].split(".")] comp = target[0] target_num = ((target_num[0] << 16) | (target_num[1] << 8) | (target_num[2] << 0)) current_num = (current[0] << 16) | (current[1] << 8) | ( current[2] << 0) return eval(str(current_num) + comp + str(target_num)) if name.lower().endswith(".json"): data = json.loads(open(name, "r").read()) fw = parseField(data["firmware"]) sig = None if "versions" in data: current = (0, 0, 0) try: current = self.bootloader_version() except CtapError as e: if e.code == CtapError.ERR.INVALID_COMMAND: pass else: raise (e) for v in data["versions"]: if isCorrectVersion(current, v): print("using signature version", v) sig = parseField(data["versions"][v]["signature"]) break if sig is None: raise RuntimeError( "Improperly formatted firmware file. Could not match version." ) else: sig = parseField(data["signature"]) ih = IntelHex() tmp = tempfile.NamedTemporaryFile(delete=False) tmp.write(fw) tmp.seek(0) tmp.close() ih.fromfile(tmp.name, format="hex") else: if not name.lower().endswith(".hex"): print('Warning, assuming "%s" is an Intel Hex file.' % name) sig = None ih = IntelHex() ih.fromfile(name, format="hex") if self.exchange == self.exchange_hid: chunk = 2048 else: chunk = 240 seg = ih.segments()[0] size = seg[1] - seg[0] total = 0 t1 = time.time() * 1000 print("erasing firmware...") for i in range(seg[0], seg[1], chunk): s = i e = min(i + chunk, seg[1]) data = ih.tobinarray(start=i, size=e - s) self.write_flash(i, data) total += chunk progress = total / float(size) * 100 sys.stdout.write("updating firmware %.2f%%...\r" % progress) sys.stdout.write("updated firmware 100% \r\n") t2 = time.time() * 1000 print("time: %.2f s" % ((t2 - t1) / 1000.0)) if sig is None: sig = b"A" * 64 if self.do_reboot: self.verify_flash(sig) return sig
def bundlePackAndSign(bundleName, firmwareName, oldAesKey, newAesKey, updateFileName, verbose): # Rather than at the beginning of the files, constants are here VERSION_LENGTH = 4 # FW version length HASH_LENGH = 128/8 # Hash length (128 bits) AES_KEY_LENGTH = 256/8 # AES key length (256 bits) FW_VERSION_LENGTH = 4 # Length of the firmware version in the bundle AES_KEY_UPDATE_FLAG_LGTH = 1 # Length of the tag which specifies a firmware udpate FW_MAX_LENGTH = 28672 # Maximum firmware length, depends on size allocated to bootloader FLASH_SECTOR_0_LENGTH = 264*8 # Length in bytes of sector 0a in external flash (to change for 16Mb & 32Mb flash!) STORAGE_SPACE = 65536 - FLASH_SECTOR_0_LENGTH # Uint16_t addressing space - sector 0a length (dedicated to other storage...) BUNDLE_MAX_LENGTH = STORAGE_SPACE - FW_MAX_LENGTH - HASH_LENGH - AES_KEY_LENGTH - FW_VERSION_LENGTH - AES_KEY_UPDATE_FLAG_LGTH # Robust RNG rng = Random.new() # Extracted firmware version firmware_version = None # AES Key Update Bool aes_key_update_bool = True # Check that all required files are here if isfile(bundleName): if verbose == True: print "Bundle file found" else: print "Couldn't find bundle file" return False if isfile(firmwareName): if verbose == True: print "Firmware file found" else: print "Couldn't find firmware file" return False # Read bundle and firmware data firmware = IntelHex(firmwareName) firmware_bin = firmware.tobinarray() fd = open(bundleName, 'rb') bundle = fd.read() fd.close() # Check that the firmware data actually starts at address 0 if firmware.minaddr() != 0: print "Firmware start address isn't correct" return False # Check that the bundle & firmware data aren't bigger than they should be if len(bundle) > BUNDLE_MAX_LENGTH: print "Bundle file too long:", len(bundle), "bytes long" return False else: if verbose == True: print "Bundle file is", len(bundle), "bytes long" if len(firmware) > FW_MAX_LENGTH-VERSION_LENGTH: print "Firmware file too long:", len(firmware), "bytes long" return False else: if verbose == True: print "Firmware file is", len(firmware), "bytes long" if verbose == True: print "Remaining space in MCU flash:", FW_MAX_LENGTH - len(firmware), "bytes" if verbose == True: print "Remaining space in bundle:", STORAGE_SPACE - FW_MAX_LENGTH - HASH_LENGH - AES_KEY_LENGTH - FW_VERSION_LENGTH - AES_KEY_UPDATE_FLAG_LGTH - len(bundle), "bytes" # Beta testers devices have their aes key set to 00000... and the bootloader will always perform a key update if oldAesKey == "0000000000000000000000000000000000000000000000000000000000000000" and newAesKey == None: if verbose == True: print "Bundle update for beta testers unit, setting 00000... as new AES key" newAesKey = "0000000000000000000000000000000000000000000000000000000000000000" # If no new aes key is specified, don't set the aes key update flag if newAesKey == None: if verbose == True: print "No new AES key set" aes_key_update_bool = False else: if verbose == True: print "Encrypting new AES key" # If needed, check the new aes key if aes_key_update_bool == True: new_aes_key = array('B', newAesKey.decode("hex")) if len(new_aes_key) != AES_KEY_LENGTH: print "Wrong New AES Key Length:", len(new_aes_key) return False # Convert & check the old aes key old_aes_key = array('B', oldAesKey.decode("hex")) if len(old_aes_key) != AES_KEY_LENGTH: print "Wrong Old AES Key Length:", len(oldAesKey) return False # Get version number for i in range(len(firmware_bin) - 3): if chr(firmware_bin[i]) == 'v' and \ chr(firmware_bin[i + 1]) >= '1' and chr(firmware_bin[i + 1]) <= '9' and \ chr(firmware_bin[i + 2]) == '.' and \ chr(firmware_bin[i + 3]) >= '0' and chr(firmware_bin[i + 3]) <= '9': firmware_version = firmware_bin[i:i+4] if verbose == True: print "Extracted firmware version:", "".join(chr(firmware_version[j]) for j in range(0, 4)) break; # Write it in the last 4 bytes of the firmware hex firmware[FW_MAX_LENGTH-4] = firmware_version[0] firmware[FW_MAX_LENGTH-3] = firmware_version[1] firmware[FW_MAX_LENGTH-2] = firmware_version[2] firmware[FW_MAX_LENGTH-1] = firmware_version[3] # Check if we extracted the firmware version and it has the correct length if firmware_version == None or len(firmware_version) != FW_VERSION_LENGTH: print "Problem while extracting firmware version" return False # If needed, encrypt the new AES key with the old one if aes_key_update_bool == True: cipher = AES.new(old_aes_key, AES.MODE_ECB, array('B',[0]*AES.block_size)) # IV ignored in ECB enc_password = cipher.encrypt(new_aes_key) if len(enc_password) != AES_KEY_LENGTH: print "Encoded password is too long!" return False else: enc_password = [255]*AES_KEY_LENGTH # Generate beginning of update file data: bundle | padding | firmware version | new aes key bool | firmware | padding | new aes key encoded update_file_data = array('B') update_file_data.extend(bytearray(bundle)) update_file_data.extend(array('B',[0]*(STORAGE_SPACE-HASH_LENGH-AES_KEY_LENGTH-FW_MAX_LENGTH-FW_VERSION_LENGTH-AES_KEY_UPDATE_FLAG_LGTH-len(bundle)))) update_file_data.extend(firmware_version) if aes_key_update_bool == True: update_file_data.append(255) else: update_file_data.append(0) update_file_data.extend(firmware.tobinarray()) update_file_data.extend(array('B',[0]*(STORAGE_SPACE-HASH_LENGH-AES_KEY_LENGTH-len(update_file_data)))) update_file_data.extend(bytearray(enc_password)) # Check length if len(update_file_data) != (STORAGE_SPACE - HASH_LENGH): print "Problem with update file length!" return False # Generate CBCMAC, IV is ZEROS cipher = AES.new(old_aes_key, AES.MODE_CBC, array('B',[0]*AES.block_size)) cbc_mac = cipher.encrypt(update_file_data)[-AES.block_size:] # Append it to update file data: bundle | padding | firmware version | new aes key bool | firmware | padding | new aes key encoded | cbcmac update_file_data.extend(bytearray(cbc_mac)) # Check length if len(update_file_data) != STORAGE_SPACE: print "Problem with update file length!" return False # Write our update image file data_fd = open(updateFileName, 'wb') data_fd.write(update_file_data) data_fd.close() if verbose == True: print "Update file written!" return True
import logging import time from intelhex import IntelHex logging.basicConfig(level=logging.DEBUG) FLASH_BASE = 0x0 FLASH_SIZE = 0x20000 PAGE_SIZE = 256 TOTAL_ROWS = FLASH_SIZE / PAGE_SIZE #hex = IntelHex(r"Phoenix_CYPD5125-40LQXI.cydsn\noboot.cydsn\CortexM0\ARM_GCC_541\Release\noboot.hex") hex = IntelHex(r"noboot.hex") bin = hex.tobinarray(start=FLASH_BASE, size=FLASH_SIZE) CPUSS_SYSREQ = 0x40100004 CPUSS_SYSARG = 0x40100008 SROM_KEY1 = 0xB6 SROM_KEY2 = 0xD3 SROM_SYSREQ_BIT = 0x80000000 SROM_PRIVILEGED_BIT = 0x10000000 SROM_STATUS_SUCCEEDED = 0xA0000000 SROM_CMD_GET_SILICON_ID = 0x00 SROM_CMD_LOAD_LATCH = 0x04 SROM_CMD_PROGRAM_ROW = 0x06
class PhyDownloader: def __init__(self, serialName, hexfile): self.hex = IntelHex(hexfile) self.serial = serial.Serial(serialName, 115200, timeout=5) self.write_index = 0 def reset(self, boot=True): # reset = LOW, TM = HIGH self.serial.dtr = False self.serial.rts = True time.sleep(0.1) # reset = HIGH, TM = HIGH if boot == True: self.serial.rts = False # reset = HIGH, TM = LOW else: self.serial.rts = False self.serial.dtr = True time.sleep(0.1) def change_baudrate(self, baudrate): if baudrate > 2000000 or baudrate < 9600: raise Exception("baudrate must be in range [9600, 2000000]") self.serial.flushInput() cmd = "uarts{0}".format(baudrate) self.serial.write(cmd.encode()) print('>: ' + cmd) time.sleep(0.2) # self.serial._set_special_baudrate(baudrate) # self.serial.baudrate = baudrate # self.serial.flushInput() # print(self.serial.baudrate) self.serial.baudrate = baudrate self.serial.flushInput() ret = self.serial.read_until(b'#OK>>:') print(ret) print('<: ' + ret.decode()) if ret.endswith(b'#OK>>:') == False: print('change baudrate failed, will use default baudrate(115200)') else: self.serial.baudrate = baudrate print('change baudrate successed, use baudrate:{0}'.format(baudrate)) def erase_512k(self): self.serial.flushInput() # write commnad er512 = 'er512' self.serial.write(er512.encode()) print('>: ' + er512) # read response ret = self.serial.read_until(b'#OK>>:') print('<: ' + ret.decode()) # is successed? if ret.endswith(b'#OK>>:') == False: raise Exception("erase failed") def write_cpnum(self, num): self.serial.flushInput() # write command # cpnum = 'cpnum {0}'.format(num) // 无效??? cpnum = 'cpnum ffffffff' self.serial.write(cpnum.encode()) print('>: ' + cpnum) # read response ret = self.serial.read_until(b'#OK>>:') print('<: ' + ret.decode()) # is successed? if ret.endswith(b'#OK>>:') == False: raise Exception("cpnum write failed") def write_bin(self, start_address, end_address): print('-------------------------------') # cpbin 指令 # cpbin [index] [flash address] [size] [run address] flash_address = start_address % 0x100000 size = end_address - start_address cmd = 'cpbin c{0} {1:06x} {2:x} {3:x}'.format(self.write_index, flash_address, size, start_address) self.serial.flushInput() self.serial.write(cmd.encode()) print('>: ' + cmd) # wait for response:'by hex mode' # ret = self.serial.read(len(expecting_response)) ret = self.serial.read_until(b':') print('<: ' + ret.decode()) # 是否成功进入hex模式? if ret != b'by hex mode:': raise Exception("device no response") # send [data] bin = self.hex.tobinarray(start_address, end_address-1) print('>: ' + 'upload {0:x} byte binary stub'.format(len(bin))) self.serial.write(bin) send_checksum = sum(bin) # 求 bin 文件数据的字节累加和,累加和的数据类型为无符号整型四字节,不计进位 # 等待返回校验值 ret = self.serial.readline() # wait for checksum:'checksum is 0x--------\n' print('<:' + ret.decode().strip('\n')) if ret == None: raise Exception('checksum no response') else: recv_checksum = int(ret[-8:], base=16) if recv_checksum != send_checksum: raise Exception('checksum mismatch') # send checksum checksum_bytes = bytes('{:08x}'.format(send_checksum), encoding='utf-8') self.serial.write(checksum_bytes) print('>: ' + 'checksum:' + checksum_bytes.decode()) # and wait for:'#OK>>:' ret = self.serial.read_until(b'#OK>>:') print('<: ' + ret.decode()) # is OK? if ret != b'#OK>>:': raise Exception('checksum failed') print('send bin sucesssed\n') self.write_index = self.write_index + 1 def write_mac(self, mac = b'\xA5\x00\x00\x00\00\00'): if (len(mac) != 6 or type(mac) != bytes): raise Exception("invalid mac address") # mac_l32, = struct.unpack('>I', mac[-4:]) # mac_h32, = struct.unpack('>I', b'\x00\x00' + mac[:2]) # 1. 启动特殊寄存器读写 cmd = "ufifo3" self.serial.write(cmd.encode()) print('>: ' + cmd) # read response ret = self.serial.read_until(b'#OK>>:') print('<: ' + ret.decode()) # 2. 写入MAC 0-3字节 mac_0_3 = "{0:02x}{1:02x}{2:02x}{3:02x}".format(mac[-1],mac[-2],mac[-3],mac[-4]) cmd = "wrrsd4000 " + mac_0_3 self.serial.write(cmd.encode()) print('>: ' + cmd) # read response ret = self.serial.read_until(b'#OK>>:') print('<: ' + ret.decode()) # 校验 cmd = "rdreg11004000" self.serial.write(cmd.encode()) print('>: ' + cmd) # 寄存器读取返回值 ret = self.serial.read_until(b'#OK>>:') print('<: ' + ret.decode()) if ret.decode()[0] != '=': raise Exception("read mac failed") if ret.decode().find(mac_0_3) == -1: raise Exception("write mac failed") # 读写不匹配 # 3. 写入MAC 4-5字节 mac_4_5 = "{0:02x}{1:02x}".format(mac[-5],mac[-6]) cmd = "wrrsd4004 " + mac_4_5 self.serial.write(cmd.encode()) print('>: ' + cmd) # read response ret = self.serial.read_until(b'#OK>>:') print('<: ' + ret.decode()) # 校验 cmd = "rdreg11004004" self.serial.write(cmd.encode()) print('>: ' + cmd) # 寄存器读取返回值 ret = self.serial.read_until(b'#OK>>:') print('<: ' + ret.decode()) if ret.decode()[0] != '=': raise Exception("read mac failed") if ret.decode().find(mac_4_5) == -1: raise Exception("write mac failed") # 读写不匹配 print('write mac successed, mac = ' + mac_4_5 + mac_0_3)
def main(): args = parser.parse_args() setup_logging(args) # Sanity checks before attaching to board if args.format == 'hex' and not intelhex_available: print("Unable to program hex file") print("Module 'intelhex' must be installed first") exit() if args.list_all: MbedBoard.listConnectedBoards() else: board_selected = MbedBoard.chooseBoard( board_id=args.board_id, target_override=args.target_override, frequency=args.frequency) with board_selected as board: flash = board.flash transport = board.transport # Boost speed with deferred transfers transport.setDeferredTransfer(True) progress = print_progress if args.hide_progress: progress = None has_file = args.file is not None chip_erase = None if args.chip_erase: chip_erase = True elif args.sector_erase: chip_erase = False if not has_file: if chip_erase: print("Erasing chip...") flash.init() flash.eraseAll() print("Done") elif args.sector_erase and args.address is not None: flash.init() page_addr = args.address for i in range(args.count): page_info = flash.getPageInfo(page_addr) if not page_info: break # Align page address on first time through. if i == 0: delta = page_addr % page_info.size if delta: print( "Warning: sector address 0x%08x is unaligned" % page_addr) page_addr -= delta print("Erasing sector 0x%08x" % page_addr) flash.erasePage(page_addr) page_addr += page_info.size else: print("No operation performed") return # If no format provided, use the file's extension. if not args.format: args.format = os.path.splitext(args.file)[1][1:] # Binary file format if args.format == 'bin': # If no address is specified use the start of rom if args.address is None: args.address = board.flash.getFlashInfo().rom_start with open(args.file, "rb") as f: f.seek(args.skip, 0) data = f.read() args.address += args.skip data = unpack(str(len(data)) + 'B', data) flash.flashBlock(args.address, data, chip_erase=chip_erase, progress_cb=progress, fast_verify=args.fast_program) # Intel hex file format elif args.format == 'hex': hex = IntelHex(args.file) addresses = hex.addresses() addresses.sort() flash_builder = flash.getFlashBuilder() data_list = list(ranges(addresses)) for start, end in data_list: size = end - start + 1 data = list(hex.tobinarray(start=start, size=size)) flash_builder.addData(start, data) flash_builder.program(chip_erase=chip_erase, progress_cb=progress, fast_verify=args.fast_program) else: print("Unknown file format '%s'" % args.format)
def upgrade_fluke(url=None): #define UF_SUCCESS 42 #define UF_ERROR 1 #define UF_SEGMENT_SIZE 132 if myro.globvars.robot == None: # force upgrade print "Connecting for firmware installation..." myro.globvars.robot = SerialRobot() s = myro.globvars.robot.ser # check to see if we can even upgrade info = get_info_timeout(s) print info if "fluke" not in info.keys(): print "(If you just upgraded Myro, please restart Python.)" print "Sorry, I can't upgrade the Fluke over Bluetooth." print "It must be upgraded manually over the serial port using lpc21isp." print "Please see http://wiki.roboteducation.org/IPRE_Fluke_Setup" return if url == None: url = "http://myro.roboteducation.org/upgrade/fluke/" install_count = 0 filename = None if url.startswith("http://"): fluke_ver = info["fluke"].split(".") print "Looking for Fluke upgrade at", url, "..." myro_ver = myro_version.split(".") # go to site, check for latest greater than our version #infp = urllib.urlopen(url) try: infp = urllib.urlopen(url) except: print "ERROR: There was an error connecting to the web to download updates. Please check your internet connection. For example, see if you can access", url, "using a web browser." return contents = infp.read() lines = contents.split("\n") infp.close() for file in lines: file = file.strip() if file != "" and file[0] != '#': print "Considering", file, "..." if file.startswith("/fluke-upgrade-"): end = file.index(".hex") patch_ver = file[15:end].split(".") print patch_ver, fluke_ver if map(int, patch_ver) > map(int, fluke_ver): # download it print " Downloading..." filename = url_retrieve(url + file) break else: filename = url if filename == None: print "Nothing found to upgrade!" return #info = myro.globvars.robot.getInfo() sendMagicKey = True version = map(int, info["fluke"].split(".")) print "Version of fluke", version if version <= [2, 5, 0]: sendMagicKey = False print "Older firmware version, Not sending magic key" else: print "Sending magic key" from intelhex import IntelHex import time ih = IntelHex(filename) binarray = ih.tobinarray() arlen = len(binarray) print "%d bytes of firmware." % arlen print "checksumming interrupt vectors" sum = check_sum(binarray, arlen) #declare a finite sized array to hold eeprom dump. #Dynamic appending of lists always comes with a performance hit eepromdump = [0] * 135168 s.flushOutput() s.flushInput() #print "Getting old EEPROM" #s.write(chr(SAVE_EEPROM)) #uf_saveEEPROMdump() print "Sending firmware" s.write(chr(UPDATE_FIRMWARE)) if sendMagicKey: # magic code to ensure we don't enter program by accident s.write(chr(0x01)) s.write(chr(0x23)) uf_storeinEEPROM(s, arlen, binarray) print "Waiting for reboot" time.sleep(2) s.close()
def ReadProgram( prog_file): prog_hex = IntelHex( prog_file) if( len( prog_hex.tobinarray()) % 256 != 0): raise Exception( "ReadProgram: wrong program file size: " + prog_file) return prog_hex
print str('-' * (len(sHexFilePath) + 20)) print "Hex File Path = \"" + sHexFilePath + "\"" print str('-' * (len(sHexFilePath) + 20)) # Fetching Hex File and Storing hexFile = IntelHex(sHexFilePath) if sGenerateBinary == "y": # Create a Binary File of this Hex File sBinFilePath = string.replace(sHexFilePath, ".hex", ".bin") logging.debug("Binary File Path : %s", sBinFilePath) hexFile.tofile(sBinFilePath, format='bin') # Obtain the actual Binary content from the Hex File binArray = hexFile.tobinarray() sPort = serial.Serial( port=sDeviceFile, baudrate=sInitialDeviceBaud, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS) # sPort.rts = True # sPort.dtr = True # time.sleep(2) # Put device into reset state sPort.rts = True sPort.dtr = True
def execute(self, capability, *args, **kwargs): """! Executes capability by name @param capability Capability name @param args Additional arguments @param kwargs Additional arguments @return Capability call return value """ if not self.check_parameters(capability, *args, **kwargs): return False if not kwargs['image_path']: self.print_plugin_error("Error: image path not specified") return False if not kwargs['target_id']: self.print_plugin_error("Error: Target ID") return False target_id = kwargs['target_id'] image_path = os.path.normpath(kwargs['image_path']) with MbedBoard.chooseBoard(board_id=target_id) as board: # Performance hack! # Eventually pyOCD will know default clock speed # per target test_clock = 10000000 target_type = board.getTargetType() if target_type == "nrf51": # Override clock since 10MHz is too fast test_clock = 1000000 if target_type == "ncs36510": # Override clock since 10MHz is too fast test_clock = 1000000 # Configure link board.link.set_clock(test_clock) board.link.set_deferred_transfer(True) # Collect address, data pairs for programming program_list = [] extension = os.path.splitext(image_path)[1] if extension == '.bin': # Binary file format memory_map = board.target.getMemoryMap() rom_region = memory_map.getBootMemory() with open(image_path, "rb") as file_handle: program_data = file_handle.read() program_list.append((rom_region.start, program_data)) elif extension == '.hex': # Intel hex file format ihex = IntelHex(image_path) addresses = ihex.addresses() addresses.sort() for start, end in _enum_continguous_addr_start_end(addresses): size = end - start + 1 data = ihex.tobinarray(start=start, size=size) data = bytearray(data) program_list.append((start, data)) else: # Unsupported raise Exception("Unsupported file format %s" % extension) # Program data flash_builder = board.flash.getFlashBuilder() for addr, data in program_list: flash_builder.addData(addr, list(bytearray(data))) flash_builder.program() # Read back and verify programming was successful for addr, data in program_list: read_data = board.target.readBlockMemoryUnaligned8( addr, len(data)) read_data = bytearray(read_data) if bytes(data) != bytes(read_data): raise Exception("Flash programming error - failed to " "program address 0x%x size %s" % (addr, len(data))) # Cleanup board.uninit(resume=False) return True
def dfu_send_image(self): """ Send hex to peer in chunks of 20 bytes. """ if not self.connected: return # Open the hex file to be sent ih = IntelHex(self.hexfile_path) bin_array = ih.tobinarray() hex_size = len(bin_array) hex_size_array_lsb = convert_uint32_to_array(len(bin_array)) # CCCD Enable notification bytes enable_notifications = System.Array[System.Byte](convert_uint16_to_array(0001)) start_time = time.time() # Setting the DFU Control Point - CCCD to 0x0001 self.send_data(self.pipe_dfu_cccd_control_point_write, enable_notifications, num_of_send_tries, "Enabling DFU control point notification") if num_of_packets_between_notif: # Subscribing for packet receipt notifications self.send_data(self.pipe_dfu_control_point, System.Array[System.Byte]([OpCodes.REQ_PKT_RCPT_NOTIF] + convert_uint16_to_array(num_of_packets_between_notif)), num_of_send_tries, "Enabling Packet receipt notifications from peer device") # Sending 'START DFU' command self.send_data(self.pipe_dfu_control_point, System.Array[System.Byte]([OpCodes.START_DFU]), num_of_send_tries, "Sending 'START DFU' command") # Sending image size self.send_data(self.pipe_dfu_packet, System.Array[System.Byte](hex_size_array_lsb), num_of_send_tries, "Sending image size") # Send 'RECEIVE FIRMWARE IMAGE' command to set DFU in firmware receive state. self.send_data(self.pipe_dfu_control_point, System.Array[System.Byte]([OpCodes.RECEIVE_FIRMWARE_IMAGE]), num_of_send_tries, "Send 'RECEIVE FIRMWARE IMAGE' command") self.ready_to_send = True; pkts_sent = 0; # Send application data packets for i in range(0, hex_size, 20): if num_of_packets_between_notif: while not self.ready_to_send: self.log_handler.log("Waiting for packet receipt notification") time.sleep(0.1) #wait for 'self.ready_to_send' to be True data_to_send = bin_array[i:i + 20] # Send 20 bytes of hex image data self.send_data(self.pipe_dfu_packet, System.Array[System.Byte](data_to_send), num_of_send_tries, "Sending Firmware bytes [%i, %i]" % (i, i + len(data_to_send))) pkts_sent = pkts_sent + 1 if ((num_of_packets_between_notif != 0) and ((pkts_sent % num_of_packets_between_notif) == 0)): # Need to wait for a notification from peer self.log_handler.log("Need to wait for a notification from peer") self.ready_to_send = False # Send Validate self.send_data(self.pipe_dfu_control_point, System.Array[System.Byte]([OpCodes.VALIDATE_FIRMWARE_IMAGE]), num_of_send_tries, "Sending 'VALIDATE FIRMWARE IMAGE' command") # Wait for notification time.sleep(1) # Send Activate and Reset self.send_data(self.pipe_dfu_control_point, System.Array[System.Byte]([OpCodes.ACTIVATE_FIRMWARE_AND_RESET]), num_of_send_tries, "Sending 'ACTIVATE FIRMWARE AND RESET' command") end_time = time.time() self.log_handler.log("Total size of the Image = {0} bytes".format(len(bin_array))) self.log_handler.log("Time taken (excluding the service discovery) = {0} seconds".format(end_time - start_time))
#!/usr/bin/python import sys from intelhex import IntelHex basename = sys.argv[1].rsplit(".", 1)[0] outfile = open(basename + ".rmh", 'w') outfile_bin = open(basename + ".bin", 'wb') ih = IntelHex(sys.argv[1]) arr = ih.tobinarray() outfile.write("@0000\n") for i, e in enumerate(arr): outfile.write("{0:02x}\n".format(e)) ih.tobinfile(outfile_bin)
print "Device found: " + list(set(new_com_ports) - set(orig_com_ports))[0] + ", starting programming process..." # Starting the programming process addr = 0 page = 0 prog = loader() firmware = IntelHex("Mooltipass.hex") port = list(set(new_com_ports) - set(orig_com_ports))[0] prog.openSerial(port,57600) prog.getId() prog.getType() prog.getVersion() for i in range(0,len(firmware),128): prog.setAddress(addr) #print "Writing page", hex(addr) prog.writeFlashPage(firmware.tobinarray(start=addr, size=128)) addr += 128 prog.enableRwwSection() prog.ser.close() print "Programming done... reconnecting to device..." time.sleep(10) # Upload bundle, set password... hid_device = None while hid_device == None: hid_device, intf, epin, epout = findHIDDevice(USB_VID, USB_PID, False) time.sleep(1) print "Connected to device, reuploading bundle and resetting device password..." mooltipassInit(hid_device, intf, epin, epout)