def install_files(self, files, command): if ConfigArgs.XMODEM_BAUD: command += " -b " + ConfigArgs.XMODEM_BAUD if os.name == 'nt': modem = xmodem.XMODEM(self.serial.getc, self.serial.putc_win, 'xmodem1k') else: modem = xmodem.XMODEM(self.serial.getc, self.serial.putc, 'xmodem1k') for file in files: with open(file, "rb") as bin: filename = os.path.basename(file) self.send("%s %s/%s" % (command, DEST_DIR, filename)) print("Install " + file) print("|0%" + "-" * (int(MAX_DOT_COUNT / 2) - 6) + "50%" + "-" * (MAX_DOT_COUNT - int(MAX_DOT_COUNT / 2) - 5) + "100%|") if ConfigArgs.XMODEM_BAUD: self.serial.setBaudrate(ConfigArgs.XMODEM_BAUD) self.serial.discard_inputs() # Clear input buffer to sync self.serial.set_file_size(os.path.getsize(file)) streamSplitter = StreamSplitter(bin) while True: # Pop buffer eof = streamSplitter.pop() # Send data from buffer via xmodem modem.send(streamSplitter) if eof: break if ConfigArgs.XMODEM_BAUD: self.serial.setBaudrate(115200) self.wait_for_prompt() print("\nTransfer completed.") self.serial.reboot()
def save_files(self, files) : if ConfigArgs.XMODEM_BAUD: command = "save_file -b " + ConfigArgs.XMODEM_BAUD + " -x " else: command = "save_file -x " if os.name == 'nt': modem = xmodem.XMODEM(self.serial.getc, self.serial.putc_win, 'xmodem1k') else: modem = xmodem.XMODEM(self.serial.getc, self.serial.putc, 'xmodem1k') for file in files: with open(file, "rb") as bin : self.send(command + os.path.basename(file)) print("Save " + file) self.wait(XMDM_MSG) if ConfigArgs.XMODEM_BAUD: self.serial.setBaudrate(ConfigArgs.XMODEM_BAUD) self.serial.discard_inputs() # Clear input buffer to sync self.serial.set_file_size(os.path.getsize(file)) modem.send(bin) if ConfigArgs.XMODEM_BAUD: self.serial.setBaudrate(115200) self.wait_for_prompt() self.send("chmod d+rw " + os.path.basename(file)) self.wait_for_prompt()
def _put_bytes(self, buf: bytes, remotefile: str): # OK, a little explanation on what we're doing here: # XMODEM is a fairly simple, but also a fairly historic protocol. For example, all packets # carry exactly 128 bytes of payload, and if the file being sent is not a multiple of 128 # bytes, the last packet will be padded by CPM's EOF, which is 0x1a. There is no file size # or anything in the protocol itself, so we'll have to take care of that and truncate the # file ourselves. def _target_cleanup(tmpfile): self._run("rm -f '{}'".format(tmpfile)) stream = io.BytesIO(buf) # We first write to a temp file, which we'll `dd` onto the destination file later tmpfile = self._run_check('mktemp') if not tmpfile: raise ExecutionError('Could not make temporary file on target') tmpfile = tmpfile[0] try: rx_cmd = self._get_xmodem_rx_cmd(tmpfile) self.logger.debug('XMODEM receive command on target: ' + rx_cmd) except ExecutionError: _target_cleanup(tmpfile) raise self._start_xmodem_transfer(rx_cmd) modem = xmodem.XMODEM(self._xmodem_getc, self._xmodem_putc) ret = modem.send(stream) self.logger.debug('xmodem.send() returned %r' % ret) self.console.expect(self.prompt, timeout=30) # truncate the file to get rid of CPMEOF padding dd_cmd = "dd if='{}' of='{}' bs=1 count={}".format( tmpfile, remotefile, len(buf)) self.logger.debug('dd command: ' + dd_cmd) out, _, ret = self._run(dd_cmd) _target_cleanup(tmpfile) if ret != 0: raise ExecutionError( 'Could not truncate destination file: dd returned {}: {}'. format(ret, out))
def __init__(self, transport): """Constructs an XMODEM transport. Args: transport : Existing transport to wrap with an XMODEM stream. """ try: import xmodem except ImportError as e: self.LOG.fatal('Could not import xmodem library. Is it installed?') raise e if not isinstance(transport, Transport.TransportBase): raise AssertionError('XMODEM transport must wrap an existing transport instance.') self.transport = transport self.xmodem = xmodem.XMODEM(self._read_byte, self._write_byte)
def upload_binary(self, index, description, stream): # type: (int, str, file) -> bool self._port.write('x') self._wait_for('Boot Index: ') self._port.write(str(index)) self._wait_for('Upload Binary: ') widgets = [ 'Uploading to slot %d ' % index, progressbar.Percentage(), ' ', progressbar.Bar(marker='#', left='[', right=']'), ' ', progressbar.ETA(), ' ', progressbar.FileTransferSpeed(), ] file_size = os.fstat(f.fileno()).st_size with progressbar.ProgressBar(widgets=widgets, max_value=file_size) as bar: modem = xmodem.XMODEM(getc=self._xmodem_getc, putc=self._xmodem_putc) r = modem.send(stream, quiet=True, callback=self._xmodem_report_progress( bar, file_size)) if not r: print 'Upload failed!' return False self._wait_for('Boot Description: ') self._port.write(description) self._port.write('\0\n') self._wait_for('Done!')
def _get_bytes(self, remotefile: str): buf = io.BytesIO() cmd = self._get_xmodem_sx_cmd(remotefile) self.logger.info('XMODEM send command on target: ' + cmd) # get file size to remove XMODEM's CPMEOF padding at the end of the last packet out, _, ret = self._run("stat '{}'".format(remotefile)) match = re.search(r'Size:\s+(?P<size>\d+)', '\n'.join(out)) if ret != 0 or not match or not match.group("size"): raise ExecutionError( "Could not stat '{}' on target".format(remotefile)) file_size = int(match.group('size')) self.logger.debug('file size on target is %d', file_size) self._start_xmodem_transfer(cmd) modem = xmodem.XMODEM(self._xmodem_getc, self._xmodem_putc) recvd_size = modem.recv(buf) self.logger.debug('xmodem.recv() returned %r' % recvd_size) # remove CPMEOF (0x1a) padding if recvd_size < file_size: raise ExecutionError( 'Only received {} bytes of {} expected'.format( recvd_size, file_size)) self.logger.debug('received %d bytes of payload', file_size) buf.truncate(file_size) self.console.expect(self.prompt, timeout=30) # return everything as bytes buf.seek(0) return buf.read()
def putc(data, timeout=1): bar.update() return s.write(data) # noinspection PyUnusedLocal def putc_user(data, timeout=1): bar_user.update() return s.write(data) def pgupdate(read, total): print "\r%d/%d bytes (%2.f%%) ..." % (read, total, read * 100 / total) m = xmodem.XMODEM(getc, putc, mode='xmodem1k') stream = open(da_path, 'rb') m.send(stream) s.baudrate = 115200 * 8 # Parse DA output to get on-board N9 firmware version string. # Note that the DA behavior is now coupled with this Python script. print >> sys.stderr, "\nWaiting for DA output..." line = s.readline() while not line.startswith("@FWVER="): line = s.readline() onboard_fw_version = line.lstrip("@FWVER=").rstrip() print >> sys.stderr, "DA uploaded, start uploading user binary..." time.sleep(1)
bar.update() value = value + 1 print >> sys.stderr, "progess:%s" % (value) return s.write(data) def putc_user(data, timeout=1): global value bar_user.update() value = value + 1 print >> sys.stderr, "progess:%s" % (value) return s.write(data) def pgupdate(read, total): print "\r%d/%d bytes (%2.f%%) ..." % (read, total, read*100/total) m = xmodem.XMODEM(getc, putc) stream = open(da_path, 'rb') m.send(stream) s.baudrate = 115200*2 print >> sys.stderr, "DA uploaded, start uploading the user bin" time.sleep(1) value = 0 if opt.target == 'ldr': s.write("1\r") pass if opt.target == 'n9': s.write("3\r") pass if opt.target == 'cm4':
def getc(size, timeout=1): data = to_bytes(ser.read(size)) return data def putc(data, timeout=1): data = to_bytes(data) return ser.write(data) while ser.in_waiting: ser.read() modem = xmodem.XMODEM(getc, putc) modem.log.setLevel("INFO") modem.log.addHandler(logging.StreamHandler(sys.stdout)) def sendname(filename): global modem crc_mode = 0 cancel = 0 error_count = 0 retry = 10 while True: char = getc(1) if char: if char == xmodem.NAK: modem.log.debug('standard checksum requested (NAK). Ignoring.')
def __init__(self, device=DEFAULT_SERIAL_DEVICE, timeout=DEFAULT_SERIAL_TIMEOUT, cautious=False): self.cautious = cautious self.timeout = timeout #cmdlist self.cmd_umanager_invocation = '+++' self.cmd_umanager_termination = 'exit' self.cmd_download = 'download' self.cmd_flash_volume = 'set volume={:+03d}' self.cmd_current_volume = 'V{:+03d}' self.cmd_input_selection = 'I{:d}' self.cmd_update = 'update' self.cmd_mode = 'set mode={:s}' self.cmd_current_fset = 'F{:d}' self.cmd_flash_fset = 'set filter={:s}' self.cmd_current_filter_list = 'filters' self.cmd_all_filter_list = 'filters all' #internal stuff self.cr = '\r' self.umanager_prompt = '# ' self.umanager_errtxt = 'invalid command' self.umanager_opened = False self.buf_on_exit = '\r\n' self.read_loop_timeout = 0.25 self.readsize = 300 self.umanager_waitcoeff = 1.5 self.volume_inf = VOLUME_INF self.volume_sup = VOLUME_SUP self.volume_pot = VOLUME_POT self.fset_str_d = FSET_EXT_STR_TO_INT_D self.fset_num_d = FSET_EXT_NUM_TO_INT_D self.opmodes = OPMODES self.input_src_set = INPUT_SRC_SET self.xmodem_crc = 'C' self.reprogram_ack = 'programmed' self.update_confirmation = 'umanager firmware update, are you sure ? ' self.update_ack = 'y' self.update_reset = 'updated, reset' def putc_generator(ser): def putc(data, timeout=1): instance_timeout = ser.timeout ser.timeout = timeout rv = ser.write(data) ser.timeout = instance_timeout return rv if rv else None return putc def getc_generator(ser): def getc(size, timeout=1): instance_timeout = ser.timeout ser.timeout = timeout rv = ser.read(size) ser.timeout = instance_timeout return rv if rv else None return getc self.ser = serial.Serial(device, 115200, timeout=0.25) self.xmodem = xmodem.XMODEM(getc_generator(self.ser), putc_generator(self.ser)) log.debug("Serial port opened")