def appstat(self, data): """ Compute length of application code and CRC. The CRC is computed from the end to the beginning of the memory, skipping the 0xFF bytes at the end. For devices without boot section the first two bytes of reset vector (rjmp to Diabolo) are not computed. """ crc = CRC.init() if not self.bootsection: end = 1 else: end = -1 top = min( len(data), self.bladdr )-1 for x in range(top, end, -1): if data[x] != '\xFF': break for i in range(x, end, -1): crc = CRC.add(crc, data[i]) return x+1, crc
def appstat(self, data): """ Compute length of application code and CRC. The CRC is computed from the end to the beginning of the memory, skipping the 0xFF bytes at the end. For devices without boot section the first two bytes of reset vector (rjmp to Diabolo) are not computed. """ crc = CRC.init() if not self.bootsection: end = 1 else: end = -1 top = min(len(data), self.bladdr) - 1 for x in range(top, end, -1): if data[x] != '\xFF': break for i in range(x, end, -1): crc = CRC.add(crc, data[i]) return x + 1, crc
p = self.device.read_flash_page(a) if p == None: cerr(_("\nRead page failed at 0x%04X.\n" % a)) return False cout('.') flushout() data += p # Compute the CRC # crc = CRC.init() i = len(data) - 1 while i >= 0 and data[i] == '\xFF': i -= 1 while i >= 0: crc = CRC.add(crc, data[i]) i -= 1 # x, crc = self.device.appstat(data) cout( _("\nRead %d bytes of firmware, CRC=0x%04X.\n" % (len(data), crc))) return # Read flash memory? # if self.options.read_flash: data = self.read_flash() if self.options.hexdump: sys.stdout.write(hexdump(0, data) + "\n") if self.options.cache:
p = self.device.read_flash_page(a) if p == None: cerr(_("\nRead page failed at 0x%04X.\n" % a)) return False cout('.') flushout() data += p # Compute the CRC # crc = CRC.init() i = len(data)-1 while i>=0 and data[i]=='\xFF': i -= 1 while i>=0: crc = CRC.add(crc, data[i]) i -= 1 # x, crc = self.device.appstat(data) cout(_("\nRead %d bytes of firmware, CRC=0x%04X.\n" % (len(data), crc))) return # Read flash memory? # if self.options.read_flash: data = self.read_flash() if self.options.hexdump: sys.stdout.write(hexdump(0,data)+"\n") if self.options.cache:
def run(self): flash = None # Data to burn into flash start_time = timer() # Compute a CRC? # if self.options.stat or self.options.crc or self.options.size: if not self.options.filename: die(_("Input file is required for CRC computation.\n")) if not self.options.mcu: die(_("Target device is required for CRC computation.\n")) try: self.device = devices.devices[self.options.mcu.lower()]() except: die(_("\"%s\": no such device.\n" % self.options.mcu.lower())) data = self.read_file(self.options.filename) x, crc = self.device.appstat(data) if self.options.stat: # # Use sys.stdout.write instead of cout to bypass '--quiet' # sys.stdout.write( _("%s: %d /%d application bytes, CRC=0x%04X.\n" % (self.options.filename, x, self.device.flashsize, crc))) elif self.options.crc: sys.stdout.write("%04X\n" % crc) else: sys.stdout.write("%d\n" % x) return # Compute a CRC32? # if self.options.crc32: if not self.options.filename: die(_("Input file is required for CRC32 computation.\n")) import binascii s = open(self.options.filename, 'rb').read() crc32 = binascii.crc32(s) sys.stdout.write("%08x\n" % (crc32 & 0xFFFFFFFF)) return # List available ttys? # if self.options.tty == "list": ttys = link.list() cout(_("Available ttys:\n" + str(ttys))) return # Open the communication channel # try: self.link = link.get(self.options) except link.serial.SerialException as e: die(str(e)) # Reset the device connected to the serial interface # self.link.set_TXD(0) self.link.set_RESET(0) if self.options.reset_length: time.sleep(self.options.reset_length) self.link.set_RESET(1) # Just reset the device and quit? # if self.options.reset_and_exit: return if self.options.keep_txd_low == 0: cout( "WARNING: target will probably not remain in Diabolo if TXD is not " "maintained low long enough!\n") else: time.sleep(self.options.keep_txd_low) self.link.set_TXD(1) # This is the best moment for detecting how many wires are used for the # serial communication since the target device is supposed to be # waiting in Diabolo for the synchronization. # # It is safe to send data on the serial line now even if the RESET # signal is used to drive the power supply (sending data while the # device is not powered could cause troubles). # self.link.detect_wires(b'?') cout(_("Tty wires: %d\n") % self.link.wires) # We can now send synchronization sequences # if not self.link.sync(): die(_("Synchronization failed.\n")) # Identify device # self.device = devices.get_device(self.link) cout(_("Connected to device (protocol %d):\n" % self.device.protocol)) cout( self.device.str(self.options.show_fuses, self.options.decode_fuses)) # Check target name # if self.options.mcu and self.device.name.lower( ) != self.options.mcu.lower(): die( _("Target mismatch: connected to %s, %s expected.\n" % (self.device.name, self.options.mcu))) # Compute the CRC of the firmware? # if self.options.fwcrc: cout("\nReading firmware flash: ") data = bytearray() if self.device.protocol == 4: step = self.device.pagesize else: # protocol 5 step = 256 for a in range(self.device.bladdr, self.device.flashsize, step): page = self.device.read_flash_page(a) if page == None: cerr(_("\nRead page failed at 0x%04X.\n" % a)) return False cout('.') flushout() data.extend(page) # Compute the CRC # crc = CRC.init() i = len(data) - 1 while i >= 0 and data[i] == 0xFF: i -= 1 while i >= 0: crc = CRC.add(crc, data[i]) i -= 1 # x, crc = self.device.appstat(data) cout( _("\nRead %d bytes of firmware, CRC=0x%04X.\n" % (len(data), crc))) return # Read flash memory? # if self.options.read_flash: data = self.read_flash() if self.options.hexdump: cout(hexdump(0, data) + "\n") if self.options.cache: self.write_file(self.options.cache, data) #return # Read eeprom memory? # if self.options.read_eeprom: data = self.read_eeprom() if self.options.hexdump: cout(hexdump(0, data) + "\n") if self.options.cache: self.write_file(self.options.cache, data) #return # Erase flash memory? # if self.options.clear_flash: flash = bytearray.fromhex('FF' * self.device.flashsize) # Write flash memory? # if self.options.burn_flash: if not self.options.filename: die(_("Input file is required to program flash memory.\n")) cache = None if self.options.cache: if os.path.isfile(self.options.cache): cache = self.read_file(self.options.cache) if len(cache) < self.device.bladdr: cout(_("Wrong cache size. Dropping cache data.\n")) cache = None else: x, cache_crc = self.device.appstat(cache) if self.device.appcrc != cache_crc: cout(_("Cache CRC (%04X) does not match device CRC. "\ "Dropping cache data.\n" % cache_crc)) cache = None else: cout( _("Cache file does not exist yet, reading flash" " memory is required.\n")) if cache == None: cache = self.read_flash() if self.options.cache: self.write_file(self.options.cache, cache) x, cache_crc = self.device.appstat(cache) flash = self.read_file(self.options.filename) if len(flash) < self.device.bladdr: cout(_("Padding data with 0xFF bytes\n")) flash.extend( bytes.fromhex('FF' * (self.device.bladdr - len(flash)))) # Program flash memory # if flash: # # Override RESET vector for device without bootsection # RJMP opcode: 1111 aaaa aaaa aaaa = 0xC000 + Addr # if not self.device.bootsection: addr = int(self.device.bladdr / 2) - 1 if addr > 0x0FFF: die(_("Can not set RESET vector opcode.\n")) opcode = 0xC000 + addr byte0 = opcode & 0xFF byte1 = opcode >> 8 cout( _("Device without bootsection, " "setting RESET vector to computed opcode: %02x %02x\n") % (byte0, byte1)) #flash = opcode.to_bytes(2,byteorder="little")+flash[2:] flash[0] = byte0 flash[1] = byte1 x, flash_crc = self.device.appstat(flash) if flash_crc == cache_crc: cout( _("Cache and data CRC match, nothing to program in Flash memory.\n" )) if self.device.eeappcrc != flash_crc: self.device.write_eeprom_appcrc(flash_crc) check = self.device.read_eeprom_appcrc() if check == flash_crc: cout( _("Updated application CRC in EEPROM: 0x%04X\n" % flash_crc)) else: raise Exception(_("update of application CRC in EEPROM failed: %04X!=%04X" %\ (check, flash_crc)) ) x_restart = True else: self.write_flash(flash, cache) x_restart = False if self.device.flash_changed: # trace() self.device.pgmcount += 1 self.device.write_eeprom_pgmcount(self.device.pgmcount) check = self.device.read_eeprom_pgmcount() if check == self.device.pgmcount: cout(_("Set program count to %d\n" % self.device.pgmcount)) else: cout( _("Failed to set program count to %d (read %d)." % (self.device.pgmcount, check))) x_restart = True if self.device.eeappcrc != flash_crc: # trace() self.device.write_eeprom_appcrc(flash_crc) cout( _("Stored application CRC in EEPROM: 0x%04X\n" % flash_crc)) x_restart = True if x_restart: # trace() #cout(_("Reset device's Diabolo\n")) self.device.resume() self.link.tx( b'*') # Send a bad command to force CRC re-computation # # Wait up to 1 s for CRC computation (~50 cycles/byte) # t = timer() + 1.0 while timer() < t and not self.link.rx(1): pass if timer() >= t: raise Exception("timeout waiting CRC recomputation") if self.link.lastchar != ord('!'): raise Exception( "unexpected reply (0x%02X) to '*' command" % ord(c)) self.link.tx(b'\n') # Resume self.link.rx(1) self.device = self.device.identify() cout(" Application CRC:\n") cout(_(" computed: 0x%04X\n" % self.device.appcrc)) cout(_(" EEPROM: 0x%04X\n" % self.device.eeappcrc)) cout(_(" Programmings: %d\n" % self.device.pgmcount)) # Update flash cache # if self.options.cache: # trace() self.write_file(self.options.cache, flash) # Start application # if self.device.appcrc == self.device.eeappcrc \ and self.device.appcrc != 0xFFFF: if self.device.start_application(): cout("Target started its application.\n") else: cout("ERROR: target did not start its application.\n") self.link.close() if self.options.diag: cout( _("%d commands, %d fails, %d resumes, %d crc errors, total time: %.1f s.\n" % (self.device.ncmds, self.device.ncmdfails, self.device.nresumes, self.device.ncrcerrors, timer() - start_time + 0.05)))