def dev(self): if not self._dev: self.log("Getting target device properties.") if self.device_id: self._dev = next((d for d in devices if d.devid == self.device_id), None) if not self._dev: raise DWException("Device '{0}' is not supported.".format(self.device_id)) sig = self.dw.read_signature() if sig != self._dev.signature: raise DWException("Device signature mismatch (expected {0:04x}, got {1:04x})" .format(self._dev.signature, sig)) else: self.log("Auto-detecting target device...") sig = self.dw.read_signature() self._dev = next((d for d in devices if d.signature == sig), None) if not self._dev: raise DWException("Device with signature {0:04x} is not supported." .format(sig)) self.log("Target is: {0} (signature 0x{1:04x})" .format(self._dev.name, self._dev.signature)) return self._dev
def parse_hex(f): mem = memlist() for line in f: if line[0:1] != b":": raise DWException("Invalid hex line prefix") lb = bytes.fromhex(line.decode("ascii").strip(":\r\n")) count = lb[0] if count + 5 != len(lb): raise DWException("Invalid hex line length") addr = (lb[1] << 8) | lb[2] rtype = lb[3] checksum = 0x100 - (sum(lb[:-1]) & 0xff) if checksum != lb[-1]: raise DWException("Invalid hex line checksum") if rtype == 0x00: mem.write(addr, lb[4:-1]) elif rtype == 0x01: break else: raise DWException("Unknown hex line") return mem
def _detect_port(self): from serial.tools.list_ports import comports for p in comports(): if p.vid: self.port = p.device break else: raise DWException("Failed to find a USB serial adapter.")
def write(self, offset, values): if offset + len(values) > MAX_ADDRESS: raise DWException("Binary is too large.") while len(self) < offset + len(values): self.append(None) for i, b in enumerate(values): self[offset + i] = b
def _detect_baudrate(self): # TODO: Make an actual auto-detection algorithm for guess in [62500, 12500, 7812, 5000, 6250]: self.dev.baudrate = guess if 0x55 in self.send_break(): self._log("Baudrate detected as {}".format(guess)) return self.dev.baudrate raise DWException("Failed to autodetect baudrate.")
def parse_binary(filename): with open(filename, "rb") as f: magic = f.read(9) f.seek(0) if magic[:4] == b"\x7fELF": return parse_elf(f) elif len(magic) == 9 and magic[0:1] == b":" and magic[7:9] in (b"00", b"01"): return parse_hex(f) else: raise DWException("Unknown binary file type.")
def read(self, nread, _log=True): start = time.time() buf = b"" while len(buf) < nread: buf += self.dev.read(nread - len(buf)) if time.time() - start >= self.timeout: raise DWException( "Read timeout. Check connections and make sure debugWIRE is enabled." ) if _log: self._log("<" + hexdump(buf)) return buf
def split_into_pages(self, mem): if len(mem) > self.dev.flash_size: raise DWException("Binary too large for target.") pages = [] for start in range(0, self.dev.flash_size, self.dev.flash_pagesize): page = mem[start:start+self.dev.flash_pagesize] if any(b is not None for b in page): pagebytes = bytes(0 if b is None else b for b in page) pagebytes += b"\00" * max(0, self.dev.flash_pagesize - len(pagebytes)) pages.append((start, pagebytes)) return pages
def parse_elf(f): from elftools.elf.elffile import ELFFile from elftools.elf.enums import ENUM_E_MACHINE elf = ELFFile(f) if elf["e_machine"] != "EM_AVR": raise DWException("Invalid ELF architecture") mem = memlist() for s in elf.iter_segments(): if s["p_filesz"] > 0: mem.write(s["p_paddr"], s.data()) return mem
def write(self, data): data = bytes(data) self._log(">" + hexdump(data)) start = time.time() nwrite = 0 while nwrite < len(data): nwrite += self.dev.write(data[nwrite:]) if time.time() - start >= self.timeout: raise DWException( "Write timeout. Check connections and make sure debugWIRE is enabled." ) self.read(nwrite, _log=False)