def execute_command(self, command: Command, args: bytes = b'', status=True): data = pack("<I", command.value) + args Packet(PacketType.PT_COMMAND, data=data).write(self.ch) if status: done = False while not done: packet = Packet(None) packet.read(self.ch) if self.process_packet(packet) == True: continue if packet.type != PacketType.PT_STATUS and packet.type != PacketType.PT_STATUS_DATA: raise RuntimeError( 'protocol error, unexpected packet type {}'.format( packet.type)) if packet.status != 0: # if packet.status == 1: # self.setup_device() # return self.execute_command(command, args, status) # else: raise RuntimeError( 'command execution failed: status={:x}'.format( packet.status)) if packet.type == PacketType.PT_STATUS_DATA: return packet.data done = True return None
def setup_device(self): # Packet(PacketType.PT_ABORT).write(self.ch) Packet(PacketType.PT_SETUP).write(self.ch) packet = Packet(None) packet.read(self.ch) if packet.type != PacketType.PT_STATUS: raise RuntimeError('protocol error, unexpected packet {}'.format( packet.type))
def get_logs(self): self.execute_command(Command.CMD_GET_LOGS) done = False while not done: packet = Packet(None) packet.read(self.ch) if packet.type == PacketType.PT_CONSOLE: print(packet.data.decode("utf-8"), end='', flush=True) elif packet.type == PacketType.PT_STATUS: done = True assert packet.status == 0
def dump_bootinfo(self): self.execute_command(Command.CMD_PRINT_BOOTINFO) done = False while not done: packet = Packet(None) packet.read(self.ch) if packet.type == PacketType.PT_CONSOLE: print(packet.data.decode("utf-8"), end='', flush=True) elif packet.type == PacketType.PT_STATUS: done = True assert packet.status == 0
def efuse(self, verbose: bool): self.execute_command(Command.CMD_PRINT_EFUSE_CFG) done = False while not done: packet = Packet(None) packet.read(self.ch) if packet.type == PacketType.PT_CONSOLE: print(packet.data.decode("utf-8"), end='', flush=True) elif packet.type == PacketType.PT_STATUS: done = True assert packet.status == 0
def memory_read(self, address, block_size, num_blocks): self.execute_command(Command.CMD_READ_MEMORY, args=pack('<I', *(address, block_size, num_blocks))) buffer = b'' for _ in range(num_blocks): packet = Packet(None) packet.read(self.ch) if not self.process_packet(packet): if packet.type == PacketType.PT_DATA: buffer += packet.data
def attach_console(self): self.execute_command(Command.CMD_ENABLE_CONSOLE) while True: packet = Packet(None) packet.read(self.ch) if packet.type != PacketType.PT_CONSOLE: continue try: decoded = packet.data.decode("utf-8") print(decoded, end='', flush=True) except: sys.stdout.buffer.write(packet.data)
def send_payload(self, payload, block_size, num_blocks): while payload: data = payload[:block_size] packet = Packet(PacketType.PT_DATA, data=data) packet.write(self.ch) payload = payload[block_size:] done = False while not done: packet = Packet(None) packet.read(self.ch) if packet.type == PacketType.PT_CONSOLE: print(packet.data.decode("utf-8"), end='', flush=True) elif packet.type == PacketType.PT_STATUS: if packet.status != 0: raise RuntimeError('command failed: {}'.format( packet.status)) done = True
def partition_read(self, partition_name, output): if isinstance(partition_name, str): partition_name = bytes(partition_name, 'utf-8') else: raise ValueError() file = open(output, 'wb') offset = pack('<Q', 0) length = pack('<Q', 0xffffffff) mmc = pack('<I', 0) response = self.execute_command(Command.CMD_READ_P, args=offset + length + mmc + partition_name) if len(response) != 8: raise RuntimeError('protocol error') r_length = unpack('<Q', response)[0] #print('Receiving {} bytes'.format(r_length)) left = r_length while left > 0: packet = Packet(None) packet.read(self.ch) if not self.process_packet(packet): if packet.type == PacketType.PT_DATA: # print('.',flush=True,end='') file.write(packet.data) left -= len(packet.data) #print('%d bytes left' % left, flush=True) else: print('unexpected packet type {}'.format(packet.type)) file.close() packet = Packet(None) packet.read(self.ch) if (packet.type == PacketType.PT_STATUS or packet.type == PacketType.PT_STATUS_DATA) and packet.status != 0: print('status = %d' % packet.status, flush=True)
def partition_write(self, partition_name, input): if isinstance(partition_name, str): partition_name = bytes(partition_name, 'utf-8') else: raise ValueError() if isinstance(input, str): is_file = True elif isinstance(input, bytes): is_file = False else: raise ValueError() if is_file: data_size = os.path.getsize(input) file = open(input, 'rb') else: data_size = len(input) offset = pack('<Q', 0) length = pack('<Q', data_size) mmc = pack('<I', 0) if data_size % Device.MMC_BLOCK_SIZE != 0: raise RuntimeError('unimplemented') self.execute_command(Command.CMD_WRITE_P, args=offset + length + mmc + partition_name) left = data_size while left > 0: if is_file: packet = Packet(PacketType.PT_DATA, data=file.read(Device.MMC_BLOCK_SIZE)) else: packet = Packet(PacketType.PT_DATA, data=input[:Device.MMC_BLOCK_SIZE]) input = input[Device.MMC_BLOCK_SIZE:] packet.write(self.ch) left -= Device.MMC_BLOCK_SIZE print('%d bytes left ' % left, flush=True, end='\r')