From: Erik Andresen Date: Fri, 21 Jul 2017 18:24:45 +0000 (+0200) Subject: Added bootloader script X-Git-Url: https://defiant.homedns.org/gitweb/?a=commitdiff_plain;h=d5c8457c07ed2888798352e565556166d6b1d4a4;p=pyshared.git Added bootloader script --- diff --git a/bootloader.py b/bootloader.py new file mode 100755 index 0000000..04370cd --- /dev/null +++ b/bootloader.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# -*- coding: iso-8859-15 -*- + +import struct +import sys +import socket +from optparse import OptionParser +from time import sleep, time +from i2c import i2c + +CMD_READ = 0x1 +CMD_ERASE = 0x2 +CMD_WRITE = 0x3 +CMD_ERASE_ALL = 0x5 +CMD_JUMP = 0x6 +CMD_PAGESIZE = 0x7 +CMD_INFO = 0x99 + +class bootloader: + def __init__(self, addr): + self.i2c_addr = addr + self.boot_addr = 0x0 + + if not self.identify(): + raise "Bootloader not running" + self.pagesize = self.get_pagesize() + + def read_mem(self, addr, num): + self.run_cmd(CMD_READ, addr, num) + return self.read(num) + + def erase(self, addr): + self.run_cmd(CMD_ERASE) + + def erase_all(self): + self.run_cmd(CMD_ERASE_ALL) + + def __compare_memarea(self, addr, data): + mem_cmp = self.read_mem(addr, self.pagesize) + if mem_cmp != data: + print "Expected:", data.encode("hex") + print "Got: ", mem_cmp.encode("hex") + raise("Compare mismatch at 0x%x" % addr) + return + + def __program_memarea(self, addr, data): + self.run_cmd(CMD_WRITE, addr, self.pagesize, data) + sleep(0.1) + + def compare(self, filename): + return self.__process_hex(filename, self.__compare_memarea) + + def program(self, filename): + return self.__process_hex(filename, self.__program_memarea) + + def __process_hex(self, filename, handle): + next_addr = None + buf = "" + lFirstRow = None + + f = open(filename, "r") + count=0 + for line in f: + if line[0] != ':': + raise("Bad line start character") + hex = line[1:].replace("\r\n", "") + data = hex.decode("hex") + num = ord(data[0]) + chksum = 0 + for c in data: + chksum+=ord(c) + if chksum % 256 != 0: + raise("Checksum error") + addr, typ, data, chksum = struct.unpack(">HB%ssB" % num, data[1:]) + + if typ == 0: # Data Record + count+=len(data) + if next_addr is not None: + if next_addr != addr: + raise "Gap in file" + buf_addr = addr-len(buf) + buf+=data + if len(buf) >= self.pagesize: + if not lFirstRow: + # do the first as last one + lFirstRow = (buf_addr, buf[:self.pagesize]) + else: + print "Addr 0x%x" % buf_addr + handle(buf_addr, buf[:self.pagesize]) + buf = buf[self.pagesize:] + elif typ == 3: # Start Segment Address Record + self.boot_addr = int(data.encode("hex"), 16) + elif typ == 1: # End of File Record + print "Addr (rest) 0x%x" % buf_addr + buf_addr+=self.pagesize + diff = self.pagesize-len(buf) + buf+=chr(0xff)*diff # fill with 0xff + handle(buf_addr, buf[:self.pagesize]) + if lFirstRow: # was first + buf_addr = lFirstRow[0] + buf = lFirstRow[1] + print "Addr (First) 0x%x" % buf_addr + handle(buf_addr, buf) + else: + raise("Unknown type %d" % typ) + + next_addr = addr+num + print "Byte count:", count + f.close() + + def jump(self, addr): + self.run_cmd(CMD_JUMP) + + def wait_ping(self): + while(True): + try: + self.identify() + break + except: + sleep(1) + + def load(self, filename): + print "Erase..." + self.erase_all() + sleep(5) + self.wait_ping() + print "Erase Done." + print "Program..." + t1 = time() + self.program(filename) + print "Time: %.1fs" % (time() - t1) + print "Compare..." + t1 = time() + self.compare(filename) + print "Time: %.1fs" % (time() - t1) + print "Jump:" + self.jump(self.boot_addr) + + def write(self, s): + dev = i2c(self.i2c_addr) + dev.write(s) + dev.close() + + def read(self, num): + dev = i2c(self.i2c_addr) + s = dev.read(num) + dev.close() + return s + + def run_cmd(self, cmd, addr=0x0, num=0, data=""): + length = len(data) + s1 = struct.pack(" 0: + addr = int(args[0], 16) + if options.bToBoot: + to_bootloader(addr) + sleep(1) + loader = bootloader(addr) + if len(args) > 1: + loader.load(args[1])