Example #1
0
    def writeFromFile(self, file, fileformat="bin"):

        ih = IntelHex()
        ih.loadfile(file, fileformat)
        bytesToWrite = ih.tobinarray()

        return self.write(bytesToWrite)
Example #2
0
def addInfo(hex_file, flash_size, VMajor, Vminor):
    # Load application hex file and convert to byte array
    # The hex file must have a start address corresponding to BOOTSIZE*512
    # Array size is increased to multiples of Flash page size and is padded with 0xFF
    # Information is added at the beginning of file
    flashsize = flash_size
    ih = IntelHex()
    fileextension = hex_file[-3:]
    ih.loadfile(hex_file, format=fileextension)
    append = ih.maxaddr()
    if (append > flashsize):
        print("Error: Flashsize input: %#06x, " % (flashsize) +
              "Minimum size needed: %#06x." % (append))
        sys.exit(1)
    appstart = ih.minaddr()
    print("\n", "Start Address: %#06x" % (appstart))
    flashsize = ((append & 0xFFFFFE00) + 0x200
                 )  # Round to multiple page number and add 0x200

    # Pack integers in a binary string
    start_address = struct.pack(
        "<i", appstart)  # Start address of the application image
    app_image_size = struct.pack("<i", flashsize -
                                 appstart)  # Length of the application image
    version = (VMajor << 16) + Vminor
    app_image_version = struct.pack(
        "<i", version)  # Version of the application image

    start_app = ih.tobinarray(end=flashsize - 1)
    bin_start_file = os.path.splitext(hex_file)[0] + ".bin"

    # Save original file
    fq = open(bin_start_file, 'wb')
    fq.write(start_app)
    fq.close()

    # Add info to file, new flashsize = flashsize + 0x200

    app = ih.tobinarray(end=flashsize - 1)
    bin_file = os.path.splitext(hex_file)[0] + "_w_info.bin"

    # Save to bin file
    f = open(bin_file, 'wb')

    # Write the information section
    f.write(b"INFO")
    f.write(start_address)
    f.write(app_image_size)
    f.write(app_image_version)

    # Round to page size (512) and fill with 0xFF
    counter = 0
    while counter < 112:  # 128B(page size) - 16B(information section size)
        counter += 1
        f.write(b"\xFF")

    f.write(b"STX0")
    f.write(app)

    f.close()
Example #3
0
    def verifyFile(self, file, fileformat="bin"):

        ih = IntelHex()
        ih.loadfile(file, fileformat)
        bytesToVerify = ih.tobinarray()

        return self.verify(bytesToVerify)
Example #4
0
 def load_image(self, path):
     retst = True
     self.data_buffer = bytearray()
     if path.lower().endswith(".bin"):
         with open(path, "rb") as f:
             self.data_buffer = f.read()
             f.close()
     elif path.lower().endswith(".hex"):
         ihex = IntelHex()
         try:
             ihex.loadfile(path, format="hex")
         except Exception as e:
             wx.MessageBox("Could not read from file: %s\n\n%s" % (path, str(e)), "ERROR", wx.OK | wx.ICON_ERROR)
             retst = False
         else:
             dhex = ihex.todict()
             self.data_buffer = bytearray([0xFF] * (max(dhex.keys()) + 1))
             for i, val in dhex.items():
                 self.data_buffer[i] = val
     elif path.lower().endswith((".s19", ".srec")):
         srec = SRecFile()
         try:
             srec.open(path)
         except Exception as e:
             wx.MessageBox("Could not read from file: %s\n\n%s" % (path, str(e)), "ERROR", wx.OK | wx.ICON_ERROR)
             retst = False
         else:
             self.data_buffer = srec.data
     else:
         retst = False
         wx.MessageBox("Not supported file Type !", "ERROR", wx.OK | wx.ICON_ERROR)
     return retst
Example #5
0
class Hex2BinConv:
    def __init__(self, out):
        self.hex = IntelHex()
        self.out = out

    def load(self, filename):
        print
        print "Loading application from hex"
        self.hex.loadfile(filename, "hex")

        size = self.hex.maxaddr() - self.hex.minaddr()
        print " size: %0.2f KiB (%d B)" % (size / 1024.0, size)

    def conv(self, label):
        done = False
        adr = self.hex.minaddr()
        max_adr = self.hex.maxaddr()

        out_file = open(self.out, "wb")

        lab_str = ""

        if label == "ee":
            f = open("../utils/build/build_number.txt", "r")
            number = int(f.readline())
            f.close()

            # lab_str += struct.pack("<H", number)
        else:
            for i in range(32):
                if i >= len(label):
                    c = chr(0)
                else:
                    c = label[i]
                lab_str += c

        out_file.write(lab_str)

        print " label: %s" % lab_str
        print "Converting HEX 2 BIN ...",

        while adr <= max_adr:
            out_file.write(chr(self.hex[adr]))

            adr += 1

        out_file.close()
        print "Done"

    def batch(self, filename, label):
        start = time.clock()

        self.load(filename)
        self.conv(label)

        end = time.clock()
        print
        print "That's all folks! (%.2f seconds)" % (end - start)
Example #6
0
class Hex2BinConv():
    def __init__(self, out):
        self.hex = IntelHex()
        self.out = out

    def load(self, filename):
        print
        print "Loading application from hex"
        self.hex.loadfile(filename, "hex")

        size = self.hex.maxaddr() - self.hex.minaddr()
        print " size: %0.2f KiB (%d B)" % (size / 1024.0, size)

    def conv(self, label):
        done = False
        adr = self.hex.minaddr()
        max_adr = self.hex.maxaddr()

        out_file = open(self.out, "wb")

        lab_str = ''

        if (label == "ee"):
            f = open("../utils/build/build_number.txt", "r")
            number = int(f.readline())
            f.close()

            #lab_str += struct.pack("<H", number)
        else:
            for i in range(32):
                if i >= len(label):
                    c = chr(0)
                else:
                    c = label[i]
                lab_str += c

        out_file.write(lab_str)

        print " label: %s" % lab_str
        print "Converting HEX 2 BIN ...",

        while (adr <= max_adr):
            out_file.write(chr(self.hex[adr]))

            adr += 1

        out_file.close()
        print "Done"

    def batch(self, filename, label):
        start = time.clock()

        self.load(filename)
        self.conv(label)

        end = time.clock()
        print
        print "That's all folks! (%.2f seconds)" % (end - start)
Example #7
0
def merge_images(hexf0, hexf1=None):
    ihex = IntelHex()
    ihex.padding = 0x00
    ihex.loadfile(hexf0, "hex")
    if hexf1 is not None:
        # Merge the CM0+ image
        ihex1 = IntelHex(hexf1)
        ihex.merge(ihex1, 'ignore')
    return ihex
    def writeFromFile(self, file, fileformat="bin"):

        try:
            ih = IntelHex()
            ih.loadfile(file, fileformat)
            bytesToWrite = ih.tobinarray()

            return self.write(bytesToWrite)
        except BaseException:
            raise RuntimeError("Failed to write from File") from BaseException
Example #9
0
class Hex2BinConv():
    def __init__(self, out):
        self.hex = IntelHex()
        self.out = out
 
        
    def load(self, filename):
        print
        print "Loading application from hex"
        self.hex.loadfile(filename, "hex")
        
        size = self.hex.maxaddr() - self.hex.minaddr()
        print " size: %0.2f KiB (%d B)" % (size/1024, size) 

    
    def conv(self, label):
        done = False
        adr = self.hex.minaddr()
        max_adr = self.hex.maxaddr()

        out_file = open(self.out, "wb");
        
        lab_str = '';
        
        for i in range(32):
            if i >= len(label):
                c = chr(0)
            else:
                c = label[i]
            lab_str += c
        
        print " label: %s" % lab_str
        print "Converting HEX 2 BIN ...", 
        
        out_file.write(lab_str)

        while(adr <= max_adr):
            out_file.write(chr(self.hex[adr]))

            adr += 1
        
        out_file.close()
        print "Done"
        
            
    def batch(self, filename, label):
        start = time.clock()
        
        self.load(filename)
        self.conv(label)
        
        end = time.clock()
        print 
        print "That's all folks! (%.2f seconds)" % (end - start)
Example #10
0
def write(addr, offset, file):

    if file.lower().endswith('.bin'):
        with open(file, "rb") as f:
            data = f.read()
            f.close()
    elif file.lower().endswith('.hex'):
        ihex = IntelHex()
        try:
            ihex.loadfile(file, format='hex')
        except Exception as e:
            raise Exception('Could not read from file: %s \n [%s]' % (file, str(e)))
        else:
            dhex = ihex.todict()
            data = bytearray([0xFF]*(max(dhex.keys()) + 1))
            for i, val in dhex.items():
                data[i] = val
    else:
        srec = kboot.SRecFile()
        try:
            srec.open(file)
        except Exception as e:
            raise Exception('Could not read from file: %s \n [%s]' % (file, str(e)))
        else:
            data = srec.data
            if addr ==  0:
                addr = srec.start_addr

    if offset < len(data):
        data = data[offset:]

    click.echo('\n Writing into MCU memory, please wait !\n')

    # Read Flash Sector Size of connected MCU
    flashSectorSize = KBOOT.get_property(kboot.Property.FlashSectorSize)['raw_value']

    # Align Erase Start Address and Len to Flash Sector Size
    saddr = (addr & ~(flashSectorSize - 1))
    slen = (len(data) & ~(flashSectorSize - 1))
    if (len(data) % flashSectorSize) > 0:
        slen += flashSectorSize

    # Erase specified region in MCU Flash memory
    KBOOT.flash_erase_region(saddr, slen)

    # Write data into MCU Flash memory
    KBOOT.write_memory(addr, data)

    # Disconnect KBoot device
    KBOOT.disconnect()

    click.secho(" Done Successfully. \n")
Example #11
0
def hex_crc(args):
    ihex_file = args.file[0]
    programSize = int(args.size[0])

    from intelhex import IntelHex

    ih = IntelHex()
    ih.loadfile(ihex_file, format="hex")
    ih.padding = 0xFF
    bin = ih.tobinarray(size=programSize)
    crc = stm32_crc32_bytes(0xffffffff, bin)
    print(hex(crc))

    return 0
Example #12
0
def hex_crc(args):
    ihex_file = args.file[0]
    programSize = int(args.size[0])

    from intelhex import IntelHex

    ih = IntelHex()
    ih.loadfile(ihex_file, format="hex")
    ih.padding = 0xFF
    bin = ih.tobinarray(size=programSize)
    crc = stm32_crc32_bytes(0xffffffff, bin)
    print(hex(crc))

    return 0
Example #13
0
class Hex2BinConv():
    def __init__(self, out):
        self.hex = IntelHex()
        self.out = out
 
        
    def load(self, filename):
        print
        print "Loading application from hex"
        self.hex.loadfile(filename, "hex")
        
        size = self.hex.maxaddr() - self.hex.minaddr()
        print " size: %0.2f KiB (%d B)" % (size/1024, size) 

    
    def conv(self, label):
        done = False
        adr = self.hex.minaddr()
        max_adr = self.hex.maxaddr()

        tmp_file = open("tmp.bin", "wb")
        out_file = open(self.out, "w")

        print "Converting HEX 2 BIN ...", 

        while(adr <= max_adr):
            tmp_file.write(chr(self.hex[adr]))
            adr += 1

        tmp_file.close()
        
        tmp_file = open("tmp.bin", "r")
        
        base64.encode(tmp_file, out_file)
        
        out_file.close()

        print "Done"
        
            
    def batch(self, filename, label):
        start = time.clock()
        
        self.load(filename)
        self.conv(label)
        
        end = time.clock()
        print 
        print "That's all folks! (%.2f seconds)" % (end - start)
Example #14
0
def merge_images(hexf0, hexf1=None):
    ihex = IntelHex()
    ihex.padding = 0x00
    ihex.loadfile(hexf0, "hex")
    if hexf1 is not None:
        # get chip ID from metadata and compare
        ihex1 = IntelHex(hexf1)
        type0 = ihex.tobinarray(start=0x90500002, size=4)
        type1 = ihex1.tobinarray(start=0x90500002, size=4)
        if type0 != type1:
            raise HookError(
                "Incompatible processor type: %s in '%s' and 0x%s in '%s'" %
                (hexf0, type0, hexf1, type1))
        ihex.merge(ihex1, 'ignore')
    return ihex
Example #15
0
class Hex2BinConv():
    def __init__(self, out):
        self.hex = IntelHex()
        self.out = out

    def load(self, filename):
        print
        print "Loading application from hex"
        self.hex.loadfile(filename, "hex")

        size = self.hex.maxaddr() - self.hex.minaddr()
        print " size: %0.2f KiB (%d B)" % (size / 1024, size)

    def conv(self, label):
        done = False
        adr = self.hex.minaddr()
        max_adr = self.hex.maxaddr()

        tmp_file = open("tmp.bin", "wb")
        out_file = open(self.out, "w")

        print "Converting HEX 2 BIN ...",

        while (adr <= max_adr):
            tmp_file.write(chr(self.hex[adr]))
            adr += 1

        tmp_file.close()

        tmp_file = open("tmp.bin", "r")

        base64.encode(tmp_file, out_file)

        out_file.close()

        print "Done"

    def batch(self, filename, label):
        start = time.clock()

        self.load(filename)
        self.conv(label)

        end = time.clock()
        print
        print "That's all folks! (%.2f seconds)" % (end - start)
Example #16
0
def hex2bin(hex_file, flash_size):
    # Load application hex file and convert to bin file
    ih = IntelHex()
    fileextension = hex_file[-3:]
    ih.loadfile(hex_file, format=fileextension)

    appstart = ih.minaddr()
    # print("\n", "Start Address: %#06x" % (appstart))

    start_app = ih.tobinarray(end=flash_size - 1)
    bin_start_file = os.path.splitext(hex_file)[0] + ".bin"

    # Save original file
    fq = open(bin_start_file, 'wb')
    fq.write(start_app)
    fq.close()

    return appstart
def main():
    if len(sys.argv) > 1:
        currentworkdir = os.path.abspath(os.path.dirname(sys.argv[0]))
        evenfilepath = str(os.path.abspath(sys.argv[1]))
        oddfilepath  = str(os.path.abspath(sys.argv[2]))
        newfilepath = os.path.join(currentworkdir , "output.hex")
        tempfileeven = open(evenfilepath, "r")
        tempfileodd = open(oddfilepath, "r")
        evenfile = IntelHex()
        evenfile.loadfile(tempfileeven,evenfilepath.split(".")[-1])
        #evenfile = IntelHex(evenfilepath)
        oddfile = IntelHex()
        oddfile.loadfile(tempfileodd,oddfilepath.split(".")[-1])
        #oddfile = IntelHex(oddfilepath)
        evendict = evenfile.todict()
        odddict = oddfile.todict()
        newdict = {}
        newindex = 0
        if evenfile.maxaddr() >= oddfile.maxaddr():
            maxaddr = evenfile.maxaddr()
        else:
            maxaddr = oddfile.maxaddr()
        #for i in range(len(evendict)):
        for i in range(0,maxaddr+1): #Evtl immer bei 0 und nicht bei inputfile.minaddr() anfangen
            try:
                newdict[newindex] = evendict[i]
            except KeyError: #Leere Adressen werden manchmal beim Speichern übersprungen
                #newdicteven[newindex] = 0xFF
                pass
            newindex+=1
            try:
                newdict[newindex] = odddict[i]
            except KeyError: #Leere Adressen werden manchmal beim Speichern übersprungen
                #newdicteven[newindex] = 0xFF
                pass
            newindex+=1
        newhex = IntelHex(newdict)
        output = open(newfilepath, 'w')
        newhex.write_hex_file(output)
        output.close()
Example #18
0
 def load_image(self, path):
     retst = True
     self.data_buffer = bytearray()
     if path.lower().endswith('.bin'):
         with open(path, "rb") as f:
             self.data_buffer = f.read()
             f.close()
     elif path.lower().endswith('.hex'):
         ihex = IntelHex()
         try:
             ihex.loadfile(path, format='hex')
         except Exception as e:
             wx.MessageBox(
                 "Could not read from file: %s\n\n%s" % (path, str(e)),
                 'ERROR', wx.OK | wx.ICON_ERROR)
             retst = False
         else:
             dhex = ihex.todict()
             self.data_buffer = bytearray([0xFF] * (max(dhex.keys()) + 1))
             for i, val in dhex.items():
                 self.data_buffer[i] = val
     elif path.lower().endswith(('.s19', '.srec')):
         srec = SRecFile()
         try:
             srec.open(path)
         except Exception as e:
             wx.MessageBox(
                 "Could not read from file: %s\n\n%s" % (path, str(e)),
                 'ERROR', wx.OK | wx.ICON_ERROR)
             retst = False
         else:
             self.data_buffer = srec.data
     else:
         retst = False
         wx.MessageBox('Not supported file Type !', 'ERROR',
                       wx.OK | wx.ICON_ERROR)
     return retst
Example #19
0
def load(mw, transport, args):
    bl = MW.Bootloader()
    bl.start()
    sleep(1)

    retval = 1

    uid = MW.BootMsg.UID.getUIDFromHexString(args.uid[0])
    ihex_file = args.file[0]

    if not uid in bl.getSlaves():
        print("Device is not in bootload mode")
        return 1

    if not bl.select(uid):
        print("Cannot select device")
        return 1

    try_again = True

    if try_again:
        desc = bl.describe_v3(uid)
        if desc is None:
            try_again = True
        else:
            print("TARGET:" + formatDescription_V3(uid, desc))
            try_again = False

    if try_again:
        desc = bl.describe_v2(uid)
        if desc is None:
            try_again = True
        else:
            print("TARGET:" + formatDescription_V2(uid, desc))
            try_again = False

    if try_again:
        retval = 1
    else:
        programSize = desc.program

        ih = IntelHex()
        ih.loadfile(ihex_file, format="hex")
        ih.padding = 0xFF
        bin = ih.tobinarray(size=programSize)
        crc = stm32_crc32_bytes(0xffffffff, bin)
        print("CRC: " + hex(crc))

        what = args.what[0]
        if what == 'program':
            if not bl.eraseProgram(uid):
                print("Cannot erase program")
                return 1

        with open(ihex_file) as f:
            data = f.read().splitlines()

        write_ihex(bl, data, crc)

        if what == 'program':
            if not bl.write_program_crc(uid, crc):
                print("Cannot write CRC")
                return 1

    bl.deselect(uid)

    bl.stop()

    return retval
Example #20
0
class StaxProg():
    def __init__(self, port, speed):
        port = port
        speed = speed
        self.hex = IntelHex()
        self.port = port
        self.speed = speed

        
    def load(self, filename):
        print "Loading application from hex"
        self.hex.loadfile(filename, "hex")
        
        size = self.hex.maxaddr() - self.hex.minaddr()
        print " size: %0.2f KiB (%d B)" % (size/1024, size) 

    def read(self):
        c = self.handle.read()
        return c 

    def open(self):
        print "Programer ready connect SkyBean...", 
        sys.stdout.flush()
        
        self.handle = serial.Serial(self.port, self.speed, timeout=.2)
        
        done = False
        i = 0
        first = True
        while (not done):
            i += 1
            
            time.sleep(0.1)


            self.handle.write("ebl")
            str = self.handle.read(10)
                
            if (str == 'bootloader'):
                done = True
                verh = ord(self.handle.read(1))
                verl = ord(self.handle.read(1))
                ver = (verh << 8) | verl 
            else:
                if first:
#                     print "Unable to reset automatically. Press reset now."
                    sys.stdout.flush()
                    first = False
                
                self.handle.flushInput();    
                time.sleep(.1)
                
            if (i > 1000):
                raise Exception("Unable to acquire bootloader control")

        print "done"
        print "Bootloader version %d" % ver
        self.handle.setTimeout(2)
        
    def erase(self):
        print "Erasing application...",
        sys.stdout.flush()
        self.handle.write('e')
        
        c = self.read()

        if c == 'd':
            print "done"
        else:
            raise Exception("Unexpected character (%c = %d)" % (c, ord(c)))

    def boot(self):
        print "Booting application..."
        self.handle.write('b')
    
    def prog(self):
        done = False
        adr = self.hex.minaddr()
        
#         self.handle.write('s')
#         adrh = (self.hex.maxaddr() & 0xFF0000) >> 16
#         adrm = (self.hex.maxaddr() & 0x00FF00) >> 8
#         adrl = (self.hex.maxaddr() & 0x0000FF) >> 0
#         
#         self.handle.write(chr(adrl))
#         self.handle.write(chr(adrm))
#         self.handle.write(chr(adrh))        
        
        print "Programing application..."
        while(not done):
            self.handle.write('p')

            adrh = (adr & 0xFF0000) >> 16
            adrm = (adr & 0x00FF00) >> 8
            adrl = (adr & 0x0000FF) >> 0
            
            self.handle.write(chr(adrl))
            self.handle.write(chr(adrm))
            self.handle.write(chr(adrh))
            
            max_size = 64
            
            size = self.hex.maxaddr() - adr
            if (size > max_size):
                size = max_size
                
            sizel = chr(size & 0x00FF)
            sizeh = chr((size & 0xFF00) >> 8)
                
            self.handle.write(sizel)
            self.handle.write(sizeh)

            for i in range(size):
                low = self.hex[adr + i*2]
                high = self.hex[adr + i*2 + 1]
                
                self.handle.write(chr(low))
                self.handle.write(chr(high))

            adr += size << 1
            
            if adr >= self.hex.maxaddr():
                adr = self.hex.maxaddr()
                done = True

            print " adr 0x%04X  size %03X  (%3.0f%%)" % (adr, size, (float(adr)/float(self.hex.maxaddr()))*100)
            sys.stdout.flush()
                       
            c = self.read()
            
            if c != 'd':
                a = self.read()               
                raise Exception("Unexpected character (%c = %d)" % (a, ord(a)))
        print "Done"
        
    def verify(self):
        print "Verifying application..."
        
        #atxmega128a3 app section size
#        max_adr = 0x20000


        self.handle.write('s')
        adrh = (self.hex.maxaddr() & 0xFF0000) >> 16
        adrm = (self.hex.maxaddr() & 0x00FF00) >> 8
        adrl = (self.hex.maxaddr() & 0x0000FF) >> 0
        
        self.handle.write(chr(adrl))
        self.handle.write(chr(adrm))
        self.handle.write(chr(adrh))    

        max_adr = self.hex.maxaddr()
         
        size = 512
        done = False
        adr = 0

        read_data = []
                
        while (not done):
            self.handle.write('r')


            adrh = (adr & 0xFF0000) >> 16
            adrm = (adr & 0x00FF00) >> 8
            adrl = (adr & 0x0000FF) >> 0
            
            self.handle.write(chr(adrl))
            self.handle.write(chr(adrm))
            self.handle.write(chr(adrh))
            
            if (size > max_adr - adr):
                size = (max_adr - adr) * 2

            sizel = chr(size & 0x00FF)
            sizeh = chr((size & 0xFF00) >> 8)
                
            self.handle.write(sizel)
            self.handle.write(sizeh)
            
            for i in range(size):
                cadr = adr + i
                data = ord(self.handle.read())
                if (cadr >= self.hex.minaddr() and cadr <= self.hex.maxaddr()):
                    read_data.append(data)
                else:
                    if (data is not 0xFF):
                        print "FF expected on %06X" % cadr

            adr += size
            if (adr >= max_adr):
                adr = max_adr
                done = True
 
            print " adr 0x%04X  size %03X  (%3.0f%%)" % (adr, size/2, (float(adr)/float(self.hex.maxaddr()))*100)
            sys.stdout.flush()

            
        if (self.hex.tobinarray() == read_data):
            print "Verification OK"
        else:
            print "Verification FAILED"
        
            print self.hex.tobinarray()
            print read_data
        
            wrong = 0    
        
            for i in range(self.hex.maxaddr() - self.hex.minaddr()):
                cadr = i + self.hex.minaddr()
                if (self.hex._buf[cadr] is not read_data[cadr]):
                    wrong += 1
            
            print "Wrong bytes %d/%d (%d %%)" % (wrong, self.hex.maxaddr(), (wrong*100)/self.hex.maxaddr())
                
            
    def batch(self, filename):
        start = time.clock()
        
        self.load(filename)
        self.open()
        self.erase()
        self.prog()
        #self.verify()
        self.boot()
        
        end = time.clock()
        print 
        print "That's all folks! (%.2f seconds)" % (end - start)
Example #21
0
    def program_hex_nrf53(self, erase_arg, program_commands):
        # program_hex() helper for nRF53.

        # *********************** NOTE *******************************
        # self.hex_ can contain code for both the application core and
        # the network core.
        #
        # We can't assume, for example, that
        # CONFIG_SOC_NRF5340_CPUAPP=y means self.hex_ only contains
        # data for the app core's flash: the user can put arbitrary
        # addresses into one of the files in HEX_FILES_TO_MERGE.
        #
        # Therefore, on this family, we may need to generate two new
        # hex files, one for each core, and flash them individually
        # with the correct '--coprocessor' arguments.
        #
        # Kind of hacky, but it works, and nrfjprog is not capable of
        # flashing to both cores at once. If self.hex_ only affects
        # one core's flash, then we skip the extra work to save time.
        # ************************************************************

        def add_program_cmd(hex_file, coprocessor):
            program_commands.append([
                'nrfjprog', '--program', hex_file, erase_arg, '-f', 'NRF53',
                '--snr', self.dev_id, '--coprocessor', coprocessor
            ] + self.tool_opt)

        full_hex = IntelHex()
        full_hex.loadfile(self.hex_, format='hex')
        min_addr, max_addr = full_hex.minaddr(), full_hex.maxaddr()

        # Base address of network coprocessor's flash. From nRF5340
        # OPS. We should get this from DTS instead if multiple values
        # are possible, but this is fine for now.
        net_base = 0x01000000

        if min_addr < net_base <= max_addr:
            net_hex, app_hex = IntelHex(), IntelHex()

            for start, stop in full_hex.segments():
                segment_hex = net_hex if start >= net_base else app_hex
                segment_hex.merge(full_hex[start:stop])

            hex_path = Path(self.hex_)
            hex_dir, hex_name = hex_path.parent, hex_path.name

            net_hex_file = os.fspath(hex_dir /
                                     f'GENERATED_CP_NETWORK_{hex_name}')
            app_hex_file = os.fspath(hex_dir /
                                     f'GENERATED_CP_APPLICATION_{hex_name}')

            self.logger.info(
                f'{self.hex_} targets both nRF53 coprocessors; '
                f'splitting it into: {net_hex_file} and {app_hex_file}')

            net_hex.write_hex_file(net_hex_file)
            app_hex.write_hex_file(app_hex_file)

            add_program_cmd(net_hex_file, 'CP_NETWORK')
            add_program_cmd(app_hex_file, 'CP_APPLICATION')
        else:
            coprocessor = 'CP_NETWORK' if max_addr >= net_base else 'CP_APPLICATION'
            add_program_cmd(self.hex_, coprocessor)
Example #22
0
class StaxProg():
    def __init__(self, port, speed):
        port = port
        speed = speed
        self.hex = IntelHex()
        self.port = port
        self.speed = speed

    def load(self, filename):
        #         print "Loading application from hex"
        self.hex.loadfile(filename, "hex")

        size = self.hex.maxaddr() - self.hex.minaddr()
#         print " size: %0.2f KiB (%d B)" % (size/1024, size)

    def read(self):
        c = self.handle.read()
        return c

    def open(self):
        print(" * Power off and power on SkyBean")

        self.handle = serial.Serial(self.port, self.speed, timeout=2)

        done = False
        while (not done):
            c = self.handle.read(1)
            if c == b'b':
                break
        i = 0
        first = True
        while (not done):
            i += 1

            time.sleep(0.1)

            self.handle.write(b'ebl')
            str = self.handle.read(10)

            if (str == b'bootloader'):
                done = True
                verh = ord(self.handle.read(1))
                verl = ord(self.handle.read(1))
                ver = (verh << 8) | verl
            else:
                if first:
                    #                     print "Unable to reset automatically. Press reset now."
                    sys.stdout.flush()
                    first = False

                self.handle.flushInput()
                time.sleep(.1)

            if (i > 1000):
                raise Exception("Unable to acquire bootloader control")

        print("Bootloader version %d" % ver)
        #self.handle.setTimeout(2)

    def erase(self):
        print("Erasing application...", end=' ')
        sys.stdout.flush()
        self.handle.write(b'e')

        c = self.read()

        if c == b'd':
            print("done")
        else:
            raise Exception("Unexpected character (%c = %d)" % (c, ord(c)))

    def boot(self):
        print("Booting application...")
        self.handle.write(b'b')

    def prog(self):
        done = False
        adr = self.hex.minaddr()

        print("Programing application...")
        while (not done):
            self.handle.write(b'p')

            adrh = (adr & 0xFF0000) >> 16
            adrm = (adr & 0x00FF00) >> 8
            adrl = (adr & 0x0000FF) >> 0

            self.handle.write(bytes([adrl]))
            self.handle.write(bytes([adrm]))
            self.handle.write(bytes([adrh]))

            max_size = 64

            size = self.hex.maxaddr() - adr
            if (size > max_size):
                size = max_size

            sizel = bytes([size & 0x00FF])
            sizeh = bytes([(size & 0xFF00) >> 8])

            self.handle.write(sizel)
            self.handle.write(sizeh)

            for i in range(size):
                low = self.hex[adr + i * 2]
                high = self.hex[adr + i * 2 + 1]

                self.handle.write(bytes([low]))
                self.handle.write(bytes([high]))

            adr += size << 1

            if adr >= self.hex.maxaddr():
                adr = self.hex.maxaddr()
                done = True


#             print " adr 0x%04X  size %03X  (%3.0f%%)" % (adr, size, (float(adr)/float(self.hex.maxaddr()))*100)
            print(".", end=' ')
            sys.stdout.flush()

            c = self.read()

            if c != b'd':
                a = self.read()
                raise Exception("Unexpected character (%c = %d)" % (a, ord(a)))
        print("Done")

    def verify(self):
        print("Verifying application...")

        #atxmega128a3 app section size
        #        max_adr = 0x20000

        self.handle.write('s')
        adrh = (self.hex.maxaddr() & 0xFF0000) >> 16
        adrm = (self.hex.maxaddr() & 0x00FF00) >> 8
        adrl = (self.hex.maxaddr() & 0x0000FF) >> 0

        self.handle.write(chr(adrl))
        self.handle.write(chr(adrm))
        self.handle.write(chr(adrh))

        max_adr = self.hex.maxaddr()

        size = 512
        done = False
        adr = 0

        read_data = []

        while (not done):
            self.handle.write('r')

            adrh = (adr & 0xFF0000) >> 16
            adrm = (adr & 0x00FF00) >> 8
            adrl = (adr & 0x0000FF) >> 0

            self.handle.write(chr(adrl))
            self.handle.write(chr(adrm))
            self.handle.write(chr(adrh))

            if (size > max_adr - adr):
                size = (max_adr - adr) * 2

            sizel = chr(size & 0x00FF)
            sizeh = chr((size & 0xFF00) >> 8)

            self.handle.write(sizel)
            self.handle.write(sizeh)

            for i in range(size):
                cadr = adr + i
                data = ord(self.handle.read())
                if (cadr >= self.hex.minaddr() and cadr <= self.hex.maxaddr()):
                    read_data.append(data)
                else:
                    if (data is not 0xFF):
                        print("FF expected on %06X" % cadr)

            adr += size
            if (adr >= max_adr):
                adr = max_adr
                done = True

            print(" adr 0x%04X  size %03X  (%3.0f%%)" %
                  (adr, size / 2,
                   (float(adr) / float(self.hex.maxaddr())) * 100))
            sys.stdout.flush()

        if (self.hex.tobinarray() == read_data):
            print("Verification OK")
        else:
            print("Verification FAILED")

            print(self.hex.tobinarray())
            print(read_data)

            wrong = 0

            for i in range(self.hex.maxaddr() - self.hex.minaddr()):
                cadr = i + self.hex.minaddr()
                if (self.hex._buf[cadr] is not read_data[cadr]):
                    wrong += 1

            print("Wrong bytes %d/%d (%d %%)" %
                  (wrong, self.hex.maxaddr(),
                   (wrong * 100) / self.hex.maxaddr()))

    def batch(self, filename):
        start = time.clock()

        if hasattr(sys, "_MEIPASS"):
            filename = os.path.join(sys._MEIPASS, filename)

        self.load(filename)
        self.open()
        self.erase()
        self.prog()
        #         self.verify()
        self.boot()

        end = time.clock()
        print()
        print("Programming done! (%.2f seconds)\n" % (end - start))
Example #23
0
def load(mw, transport, args):
    bl = MW.Bootloader()
    bl.start()
    sleep(1)

    retval = 1

    uid = MW.BootMsg.UID.getUIDFromHexString(args.uid[0])
    ihex_file = args.file[0]

    if not uid in bl.getSlaves():
        print("Device is not in bootload mode")
        return 1

    if not bl.select(uid):
        print("Cannot select device")
        return 1

    try_again = True

    if try_again:
        desc = bl.describe_v3(uid)
        if desc is None:
            try_again = True
        else:
            print("TARGET:" + formatDescription_V3(uid, desc))
            try_again = False

    if try_again:
        desc = bl.describe_v2(uid)
        if desc is None:
            try_again = True
        else:
            print("TARGET:" + formatDescription_V2(uid, desc))
            try_again = False

    if try_again:
        retval = 1
    else:
        programSize = desc.program
        
        ih = IntelHex()
        ih.loadfile(ihex_file, format="hex")
        ih.padding = 0xFF
        bin = ih.tobinarray(size=programSize)
        crc = stm32_crc32_bytes(0xffffffff, bin)
        print("CRC: " + hex(crc))

        what = args.what[0]
        if what == 'program':
            if not bl.eraseProgram(uid):
                print("Cannot erase program")
                return 1

        with open(ihex_file) as f:
            data = f.read().splitlines()

        write_ihex(bl, data, crc)

        if what == 'program':
            if not bl.write_program_crc(uid, crc):
                print("Cannot write CRC")
                return 1

    bl.deselect(uid)

    bl.stop()

    return retval
from intelhex import IntelHex

input_string = input("Enter filename of intel hex file:")

lh = IntelHex()
lh.loadfile(input_string, format='hex')

f = open("h.txt", 'w')

f.write("uint8_t array[")
f.write(str(len(lh)))
f.write("] = { ")

pydict = lh.todict()

for line in pydict.values():
    f.write(str(hex(line)))
    f.write(", ")

f.seek(f.tell() - 2, 0)
f.write(" };")

f.close()
Example #25
0
class StaxProg():
    def __init__(self, port, speed):
        port = port
        speed = speed
        self.hex = IntelHex()
        self.port = port
        self.speed = speed

        
    def load(self, filename):
        print "Loading application from hex"
        self.hex.loadfile(filename, "hex")
        
        size = self.hex.maxaddr() - self.hex.minaddr()
        print " size: %0.2f KiB (%d B)" % (size/1024, size) 

    def read(self):
        c = self.handle.read()
        return c 

    def open(self):
        print "Programer ready connect SkyBean...", 
        sys.stdout.flush()
        
        self.handle = serial.Serial(self.port, self.speed, timeout=.2)
        
        done = False
        i = 0
        first = True
        while (not done):
            i += 1
            
            time.sleep(0.1)


            self.handle.write("ebl")
            str = self.handle.read(10)
                
            if (str == 'bootloader'):
                done = True
                verh = ord(self.handle.read(1))
                verl = ord(self.handle.read(1))
                ver = (verh << 8) | verl 
            else:
                if first:
#                     print "Unable to reset automatically. Press reset now."
                    sys.stdout.flush()
                    first = False
                
                self.handle.flushInput();    
                time.sleep(.1)
                
            if (i > 1000):
                raise Exception("Unable to acquire bootloader control")

        print "done"
        print "Bootloader version %d" % ver
        self.handle.timeout=2
        
    def erase(self):
        print "Erasing application...",
        sys.stdout.flush()
        self.handle.write('e')
        
        c = self.read()

        if c == 'd':
            print "done"
        else:
            raise Exception("Unexpected character (%c = %d)" % (c, ord(c)))

    def boot(self):
        print "Booting application..."
        self.handle.write('b')
    
    def prog(self):
        done = False
        adr = self.hex.minaddr()
        
#         self.handle.write('s')
#         adrh = (self.hex.maxaddr() & 0xFF0000) >> 16
#         adrm = (self.hex.maxaddr() & 0x00FF00) >> 8
#         adrl = (self.hex.maxaddr() & 0x0000FF) >> 0
#         
#         self.handle.write(chr(adrl))
#         self.handle.write(chr(adrm))
#         self.handle.write(chr(adrh))        
        
        print "Programing application..."
        while(not done):
            self.handle.write('p')

            adrh = (adr & 0xFF0000) >> 16
            adrm = (adr & 0x00FF00) >> 8
            adrl = (adr & 0x0000FF) >> 0
            
            self.handle.write(chr(adrl))
            self.handle.write(chr(adrm))
            self.handle.write(chr(adrh))
            
            max_size = 64
            
            size = self.hex.maxaddr() - adr
            if (size > max_size):
                size = max_size
                
            sizel = chr(size & 0x00FF)
            sizeh = chr((size & 0xFF00) >> 8)
                
            self.handle.write(sizel)
            self.handle.write(sizeh)

            for i in range(size):
                low = self.hex[adr + i*2]
                high = self.hex[adr + i*2 + 1]
                
                self.handle.write(chr(low))
                self.handle.write(chr(high))

            adr += size << 1
            
            if adr >= self.hex.maxaddr():
                adr = self.hex.maxaddr()
                done = True

            print " adr 0x%04X  size %03X  (%3.0f%%)" % (adr, size, (float(adr)/float(self.hex.maxaddr()))*100)
            sys.stdout.flush()
                       
            c = self.read()
            
            if c != 'd':
                a = self.read()               
                raise Exception("Unexpected character (%c = %d)" % (a, ord(a)))
        print "Done"
        
    def verify(self):
        print "Verifying application..."
        
        #atxmega128a3 app section size
#        max_adr = 0x20000


        self.handle.write('s')
        adrh = (self.hex.maxaddr() & 0xFF0000) >> 16
        adrm = (self.hex.maxaddr() & 0x00FF00) >> 8
        adrl = (self.hex.maxaddr() & 0x0000FF) >> 0
        
        self.handle.write(chr(adrl))
        self.handle.write(chr(adrm))
        self.handle.write(chr(adrh))    

        max_adr = self.hex.maxaddr()
         
        size = 512
        done = False
        adr = 0

        read_data = []
                
        while (not done):
            self.handle.write('r')


            adrh = (adr & 0xFF0000) >> 16
            adrm = (adr & 0x00FF00) >> 8
            adrl = (adr & 0x0000FF) >> 0
            
            self.handle.write(chr(adrl))
            self.handle.write(chr(adrm))
            self.handle.write(chr(adrh))
            
            if (size > max_adr - adr):
                size = (max_adr - adr) * 2

            sizel = chr(size & 0x00FF)
            sizeh = chr((size & 0xFF00) >> 8)
                
            self.handle.write(sizel)
            self.handle.write(sizeh)
            
            for i in range(size):
                cadr = adr + i
                data = ord(self.handle.read())
                if (cadr >= self.hex.minaddr() and cadr <= self.hex.maxaddr()):
                    read_data.append(data)
                else:
                    if (data is not 0xFF):
                        print "FF expected on %06X" % cadr

            adr += size
            if (adr >= max_adr):
                adr = max_adr
                done = True
 
            print " adr 0x%04X  size %03X  (%3.0f%%)" % (adr, size/2, (float(adr)/float(self.hex.maxaddr()))*100)
            sys.stdout.flush()

            
        if (self.hex.tobinarray() == read_data):
            print "Verification OK"
        else:
            print "Verification FAILED"
        
            print self.hex.tobinarray()
            print read_data
        
            wrong = 0    
        
            for i in range(self.hex.maxaddr() - self.hex.minaddr()):
                cadr = i + self.hex.minaddr()
                if (self.hex._buf[cadr] is not read_data[cadr]):
                    wrong += 1
            
            print "Wrong bytes %d/%d (%d %%)" % (wrong, self.hex.maxaddr(), (wrong*100)/self.hex.maxaddr())
                
            
    def batch(self, filename):
        start = time.clock()
        
        self.load(filename)
        self.open()
        self.erase()
        self.prog()
        #self.verify()
        self.boot()
        
        end = time.clock()
        print 
        print "That's all folks! (%.2f seconds)" % (end - start)
Example #26
0
class NrfJprogBinaryRunner(ZephyrBinaryRunner):
    '''Runner front-end for nrfjprog.'''
    def __init__(self,
                 cfg,
                 family,
                 softreset,
                 dev_id,
                 erase=False,
                 tool_opt=[],
                 force=False,
                 recover=False):
        super().__init__(cfg)
        self.hex_ = cfg.hex_file
        self.family = family
        self.softreset = softreset
        self.dev_id = dev_id
        self.erase = bool(erase)
        self.force = force
        self.recover = bool(recover)

        self.tool_opt = []
        for opts in [shlex.split(opt) for opt in tool_opt]:
            self.tool_opt += opts

    @classmethod
    def name(cls):
        return 'nrfjprog'

    @classmethod
    def capabilities(cls):
        return RunnerCaps(commands={'flash'}, dev_id=True, erase=True)

    @classmethod
    def dev_id_help(cls) -> str:
        return '''Device identifier. Use it to select the J-Link Serial Number
                  of the device connected over USB. '*' matches one or more
                  characters/digits'''

    @classmethod
    def do_add_parser(cls, parser):
        parser.add_argument('--nrf-family',
                            choices=['NRF51', 'NRF52', 'NRF53', 'NRF91'],
                            help='''MCU family; still accepted for
                            compatibility only''')
        parser.add_argument('--softreset',
                            required=False,
                            action='store_true',
                            help='use reset instead of pinreset')
        parser.add_argument('--snr',
                            required=False,
                            dest='dev_id',
                            action=partial(depr_action,
                                           replacement='-i/--dev-id'),
                            help='Deprecated: use -i/--dev-id instead')
        parser.add_argument('--tool-opt',
                            default=[],
                            action='append',
                            help='''Additional options for nrfjprog,
                            e.g. "--recover"''')
        parser.add_argument(
            '--force',
            required=False,
            action='store_true',
            help='Flash even if the result cannot be guaranteed.')
        parser.add_argument('--recover',
                            required=False,
                            action='store_true',
                            help='''erase all user available non-volatile
                            memory and disable read back protection before
                            flashing (erases flash for both cores on nRF53)''')

    @classmethod
    def do_create(cls, cfg, args):
        return NrfJprogBinaryRunner(cfg,
                                    args.nrf_family,
                                    args.softreset,
                                    args.dev_id,
                                    erase=args.erase,
                                    tool_opt=args.tool_opt,
                                    force=args.force,
                                    recover=args.recover)

    def ensure_snr(self):
        if not self.dev_id or "*" in self.dev_id:
            self.dev_id = self.get_board_snr(self.dev_id or "*")
        self.dev_id = self.dev_id.lstrip("0")

    def get_boards(self):
        snrs = self.check_output(['nrfjprog', '--ids'])
        snrs = snrs.decode(sys.getdefaultencoding()).strip().splitlines()
        if not snrs:
            raise RuntimeError('"nrfjprog --ids" did not find a board; '
                               'is the board connected?')
        return snrs

    @staticmethod
    def verify_snr(snr):
        if snr == '0':
            raise RuntimeError('"nrfjprog --ids" returned 0; '
                               'is a debugger already connected?')

    def get_board_snr(self, glob):
        # Use nrfjprog --ids to discover connected boards.
        #
        # If there's exactly one board connected, it's safe to assume
        # the user wants that one. Otherwise, bail unless there are
        # multiple boards and we are connected to a terminal, in which
        # case use print() and input() to ask what the user wants.

        re_glob = escape(glob).replace(r"\*", ".+")
        snrs = [snr for snr in self.get_boards() if fullmatch(re_glob, snr)]

        if len(snrs) == 0:
            raise RuntimeError('There are no boards connected{}.'.format(
                f" matching '{glob}'" if glob != "*" else ""))
        elif len(snrs) == 1:
            board_snr = snrs[0]
            self.verify_snr(board_snr)
            print("Using board {}".format(board_snr))
            return board_snr
        elif not sys.stdin.isatty():
            raise RuntimeError(
                f'refusing to guess which of {len(snrs)} '
                'connected boards to use. (Interactive prompts '
                'disabled since standard input is not a terminal.) '
                'Please specify a serial number on the command line.')

        snrs = sorted(snrs)
        print('There are multiple boards connected{}.'.format(
            f" matching '{glob}'" if glob != "*" else ""))
        for i, snr in enumerate(snrs, 1):
            print('{}. {}'.format(i, snr))

        p = 'Please select one with desired serial number (1-{}): '.format(
            len(snrs))
        while True:
            try:
                value = input(p)
            except EOFError:
                sys.exit(0)
            try:
                value = int(value)
            except ValueError:
                continue
            if 1 <= value <= len(snrs):
                break

        return snrs[value - 1]

    def ensure_family(self):
        # Ensure self.family is set.

        if self.family is not None:
            return

        if self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF51X'):
            self.family = 'NRF51'
        elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF52X'):
            self.family = 'NRF52'
        elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF53X'):
            self.family = 'NRF53'
        elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF91X'):
            self.family = 'NRF91'
        else:
            raise RuntimeError(f'unknown nRF; update {__file__}')

    def hex_refers_region(self, region_start, region_end):
        for segment_start, _ in self.hex_contents.segments():
            if region_start <= segment_start <= region_end:
                return True
        return False

    def check_force_uicr(self):
        # On SoCs without --sectoranduicrerase, we want to fail by
        # default if the application contains UICR data and we're not sure
        # that the flash will succeed.

        # A map from SoCs which need this check to their UICR address
        # ranges. If self.family isn't in here, do nothing.
        uicr_ranges = {
            'NRF53': ((0x00FF8000, 0x00FF8800), (0x01FF8000, 0x01FF8800)),
            'NRF91': ((0x00FF8000, 0x00FF8800), ),
        }

        if self.uicr_data_ok or self.family not in uicr_ranges:
            return

        for region_start, region_end in uicr_ranges[self.family]:
            if self.hex_refers_region(region_start, region_end):
                # Hex file has UICR contents, and that's not OK.
                raise RuntimeError(
                    'The hex file contains data placed in the UICR, which '
                    'needs a full erase before reprogramming. Run west '
                    'flash again with --force, --erase, or --recover.')

    @property
    def uicr_data_ok(self):
        # True if it's OK to try to flash even with UICR data
        # in the image; False otherwise.

        return self.force or self.erase or self.recover

    def recover_target(self):
        if self.family == 'NRF53':
            self.logger.info(
                'Recovering and erasing flash memory for both the network '
                'and application cores.')
        else:
            self.logger.info('Recovering and erasing all flash memory.')

        if self.family == 'NRF53':
            self.check_call([
                'nrfjprog', '--recover', '-f', self.family, '--coprocessor',
                'CP_NETWORK', '--snr', self.dev_id
            ])

        self.check_call(
            ['nrfjprog', '--recover', '-f', self.family, '--snr', self.dev_id])

    def program_hex(self):
        # Get the nrfjprog command use to actually program self.hex_.
        self.logger.info('Flashing file: {}'.format(self.hex_))

        # What type of erase argument should we pass to nrfjprog?
        if self.erase:
            erase_arg = '--chiperase'
        else:
            if self.family == 'NRF52':
                erase_arg = '--sectoranduicrerase'
            else:
                erase_arg = '--sectorerase'

        xip_ranges = {
            'NRF52': (0x12000000, 0x19FFFFFF),
            'NRF53': (0x10000000, 0x1FFFFFFF),
        }
        qspi_erase_opt = []
        if self.family in xip_ranges:
            xip_start, xip_end = xip_ranges[self.family]
            if self.hex_refers_region(xip_start, xip_end):
                qspi_erase_opt = ['--qspisectorerase']

        # What nrfjprog commands do we need to flash this target?
        program_commands = []
        if self.family == 'NRF53':
            # nRF53 requires special treatment due to the extra coprocessor.
            self.program_hex_nrf53(erase_arg, qspi_erase_opt, program_commands)
        else:
            # It's important for tool_opt to come last, so it can override
            # any options that we set here.
            program_commands.append(
                ['nrfjprog', '--program', self.hex_, erase_arg] +
                qspi_erase_opt +
                ['--verify', '-f', self.family, '--snr', self.dev_id] +
                self.tool_opt)

        try:
            for command in program_commands:
                self.check_call(command)
        except subprocess.CalledProcessError as cpe:
            if cpe.returncode == UnavailableOperationBecauseProtectionError:
                if self.family == 'NRF53':
                    family_help = (
                        '  Note: your target is an nRF53; all flash memory '
                        'for both the network and application cores will be '
                        'erased prior to reflashing.')
                else:
                    family_help = (
                        '  Note: this will recover and erase all flash memory '
                        'prior to reflashing.')
                self.logger.error(
                    'Flashing failed because the target '
                    'must be recovered.\n'
                    '  To fix, run "west flash --recover" instead.\n' +
                    family_help)
            raise

    def program_hex_nrf53(self, erase_arg, qspi_erase_opt, program_commands):
        # program_hex() helper for nRF53.

        # *********************** NOTE *******************************
        # self.hex_ can contain code for both the application core and
        # the network core.
        #
        # We can't assume, for example, that
        # CONFIG_SOC_NRF5340_CPUAPP=y means self.hex_ only contains
        # data for the app core's flash: the user can put arbitrary
        # addresses into one of the files in HEX_FILES_TO_MERGE.
        #
        # Therefore, on this family, we may need to generate two new
        # hex files, one for each core, and flash them individually
        # with the correct '--coprocessor' arguments.
        #
        # Kind of hacky, but it works, and nrfjprog is not capable of
        # flashing to both cores at once. If self.hex_ only affects
        # one core's flash, then we skip the extra work to save time.
        # ************************************************************

        def add_program_cmd(hex_file, coprocessor, qspi_erase_opt):
            program_commands.append(
                ['nrfjprog', '--program', hex_file, erase_arg] +
                qspi_erase_opt + [
                    '--verify', '-f', 'NRF53', '--snr', self.dev_id,
                    '--coprocessor', coprocessor
                ] + self.tool_opt)

        # Address range of the network coprocessor's flash. From nRF5340 OPS.
        # We should get this from DTS instead if multiple values are possible,
        # but this is fine for now.
        net_flash_start = 0x01000000
        net_flash_end = 0x0103FFFF

        # If there is nothing in the hex file for the network core,
        # only the application core is programmed.
        if not self.hex_refers_region(net_flash_start, net_flash_end):
            add_program_cmd(self.hex_, 'CP_APPLICATION', qspi_erase_opt)
        # If there is some content that addresses a region beyond the network
        # core flash range, two hex files are generated and the two cores
        # are programmed one by one.
        elif self.hex_contents.minaddr() < net_flash_start or \
             self.hex_contents.maxaddr() > net_flash_end:

            net_hex, app_hex = IntelHex(), IntelHex()
            for start, end in self.hex_contents.segments():
                if net_flash_start <= start <= net_flash_end:
                    net_hex.merge(self.hex_contents[start:end])
                else:
                    app_hex.merge(self.hex_contents[start:end])

            hex_path = Path(self.hex_)
            hex_dir, hex_name = hex_path.parent, hex_path.name

            net_hex_file = os.fspath(hex_dir /
                                     f'GENERATED_CP_NETWORK_{hex_name}')
            app_hex_file = os.fspath(hex_dir /
                                     f'GENERATED_CP_APPLICATION_{hex_name}')

            self.logger.info(
                f'{self.hex_} targets both nRF53 coprocessors; '
                f'splitting it into: {net_hex_file} and {app_hex_file}')

            net_hex.write_hex_file(net_hex_file)
            app_hex.write_hex_file(app_hex_file)

            add_program_cmd(net_hex_file, 'CP_NETWORK', [])
            add_program_cmd(app_hex_file, 'CP_APPLICATION', qspi_erase_opt)
        # Otherwise, only the network core is programmed.
        else:
            add_program_cmd(self.hex_, 'CP_NETWORK', [])

    def reset_target(self):
        if self.family == 'NRF52' and not self.softreset:
            self.check_call([
                'nrfjprog', '--pinresetenable', '-f', self.family, '--snr',
                self.dev_id
            ])  # Enable pin reset

        if self.softreset:
            self.check_call([
                'nrfjprog', '--reset', '-f', self.family, '--snr', self.dev_id
            ])
        else:
            self.check_call([
                'nrfjprog', '--pinreset', '-f', self.family, '--snr',
                self.dev_id
            ])

    def do_run(self, command, **kwargs):
        self.require('nrfjprog')

        self.ensure_output('hex')
        if IntelHex is None:
            raise RuntimeError('one or more Python dependencies were missing; '
                               'see the getting started guide for details on '
                               'how to fix')
        self.hex_contents = IntelHex()
        try:
            self.hex_contents.loadfile(self.hex_, format='hex')
        except FileNotFoundError:
            pass

        self.ensure_snr()
        self.ensure_family()
        self.check_force_uicr()

        if self.recover:
            self.recover_target()
        self.program_hex()
        self.reset_target()

        self.logger.info(f'Board with serial number {self.dev_id} '
                         'flashed successfully.')
Example #27
0
#!/usr/bin/python

import sys
from intelhex import IntelHex

print('Number of arguments:', len(sys.argv), 'arguments.')
print('Argument List:', str(sys.argv))
if (len(sys.argv) > 2):
    print(
        'Too many arguments, use this instead: python dump_hex.py <hex_file>.hex'
    )
    exit(-1)

hex_file = IntelHex()
hex_file.loadfile(sys.argv[1], format='hex')

file = open((str(sys.argv[1]) + ".txt"), 'w')

print('Dumping hex file contents into: ' + (str(sys.argv[1]) + ".txt"))
hex_file.dump(file)

file.close()
Example #28
0
def main(argv):

    options = myargs(argv)
    print("options: {}".format(options))

    if not options.policy_path:
        options.policy_path = 'policy'

    tools = CySecureTools(
        options.target_name,
        options.policy_path + "/" + options.policy_file + '.json')
    if (options.toolchain == 'ARM'):
        fromelf_cmd = options.toolchain_path + "/bin/fromelf"
        app_elf_file = options.build_dir + "/" + options.app_name + ".elf"
        fromelf_result_dir = options.build_dir + "/" + "fromelf_result"
        # Check if gcc tools path is valid
        if (os.path.isdir(options.toolchain_path) == False):
            print("ERROR: 'ARM Compiler' tools folder not found in path: {}".
                  format(options.toolchain_path))
            exit(-1)

        # Check if elf is valid
        if (os.path.isfile(app_elf_file) == False):
            print("ERROR: ELF file not found in path: {}\r\n".format(
                app_elf_file))
            exit(-1)

        # Split elf file into sections
        shell_cmd = [
            fromelf_cmd, '--i32', '--output=' + fromelf_result_dir,
            app_elf_file
        ]
        ret = exec_shell_command(shell_cmd)
        if (ret != 0):
            exit(ret)

        em_eeprom_hex = fromelf_result_dir + "/" + ".cy_em_eeprom"
        app_hex_path = options.build_dir + '/' + options.app_name + '.hex'
        if (os.path.isfile(em_eeprom_hex) == True):
            sections_list = [
                f for f in os.listdir(fromelf_result_dir)
                if os.path.isfile(os.path.join(fromelf_result_dir, f))
            ]
            sections_list.remove('.cy_em_eeprom')
            flash = IntelHex()

            for section in sections_list:
                sect = IntelHex(fromelf_result_dir + "/" + section)
                flash.merge(sect, overlap='replace')

            flash.write_hex_file(app_hex_path, False)

        CM0_app_src_path = options.cm0_app_path + '/' + options.cm0_app_name + '.hex'
        CM0_app_dst_path = options.build_dir + '/' + options.cm0_app_name + '.hex'

        # CySecureTools Image ID for CM4 Applications is
        # 1) 1 for single-stage,
        # 2) 16 in case of multi-stage,
        # Image ID for CM0 Applications is always 1
        if (options.core == "CM4"):
            if (options.secure_boot_stage == "single"):
                # Sign CM4 image
                tools.sign_image(app_hex_path, 1)
            else:
                # Sign CM4 image
                tools.sign_image(app_hex_path, 16)
                # Make a copy of CM0P app image in build folder
                shutil.copy2(CM0_app_src_path, CM0_app_dst_path)

                # Sign CM0 image
                tools.sign_image(CM0_app_dst_path, 1)

                # Merge CM0, CM4 into a single hex file
                ihex = IntelHex()
                ihex.padding = 0x00
                ihex.loadfile(app_hex_path, 'hex')                 \
                                        ihex.merge(IntelHex(CM0_app_dst_path), 'ignore')                 \
                                        ihex.write_hex_file(app_hex_path, write_start_addr=False, byte_count=16)
        else:
            tools.sign_image(app_hex_path, 1)

        if (os.path.isfile(em_eeprom_hex) == True):
            # Add emulated EEPROM Section back
            flash = IntelHex(app_hex_path)
            eeprom = IntelHex(em_eeprom_hex)
            flash.merge(eeprom)
            flash.write_hex_file(app_hex_path, False)
    else:
        gcc_objcopy_eabi_cmd = options.toolchain_path + '/bin/arm-none-eabi-objcopy'
        app_elf_file = options.build_dir + "/" + options.app_name + ".elf"

        # Check if gcc tools path is valid
        if (os.path.isdir(options.toolchain_path) == False):
            print("ERROR: GCC tools folder not found in path: {}".format(
                options.toolchain_path))
            exit(-1)

        # Check if elf is valid
        if (os.path.isfile(app_elf_file) == False):
            print("ERROR: ELF file not found in path: {}\r\n".format(
                app_elf_file))
            exit(-1)

        # Strip away emulated EEPROM section from hex file before signing
        shell_cmd = [
            gcc_objcopy_eabi_cmd, '-R', '.cy_em_eeprom', '-O', 'ihex',
            app_elf_file, options.build_dir + "/" + options.app_name + ".hex"
        ]
        ret = exec_shell_command(shell_cmd)
        if (ret != 0):
            exit(ret)

        # Store emulated eeprom section in a seperate hex file
        shell_cmd = [
            gcc_objcopy_eabi_cmd, '-j', '.cy_em_eeprom', '-O', 'ihex',
            options.build_dir + "/" + options.app_name + ".elf",
            options.build_dir + "/em_eeprom.hex"
        ]
        ret = exec_shell_command(shell_cmd)
        if (ret != 0):
            exit(ret)

        app_hex_path = options.build_dir + '/' + options.app_name + '.hex'
        CM0_app_src_path = options.cm0_app_path + '/' + options.cm0_app_name + '.hex'
        CM0_app_dst_path = options.build_dir + '/' + options.cm0_app_name + '.hex'

        # CySecureTools Image ID for CM4 Applications is
        # 1) 1 for single-stage,
        # 2) 16 in case of multi-stage,
        # Image ID for CM0 Applications is always 1
        if (options.core == "CM4"):
            if (options.secure_boot_stage == "single"):
                # Sign CM4 image
                tools.sign_image(app_hex_path, 1)
            else:
                # Sign CM4 image
                tools.sign_image(app_hex_path, 16)
                # Make a copy of CM0P app image in build folder
                shutil.copy2(CM0_app_src_path, CM0_app_dst_path)

                # Sign CM0 image
                tools.sign_image(CM0_app_dst_path, 1)

                # Merge CM0, CM4 into a single hex file
                ihex = IntelHex()
                ihex.padding = 0x00
                ihex.loadfile(app_hex_path, 'hex')                 \
                                ihex.merge(IntelHex(CM0_app_dst_path), 'ignore')                 \
                                ihex.write_hex_file(app_hex_path, write_start_addr=False, byte_count=16)
        else:
            tools.sign_image(app_hex_path, 1)

        # Add emulated EEPROM Section back
        flash = IntelHex(app_hex_path)
        eeprom = IntelHex(options.build_dir + "/em_eeprom.hex")
        flash.merge(eeprom)
        flash.write_hex_file(app_hex_path, False)

    exit(0)
Example #29
0
    def sign_image(self,
                   hex_file,
                   image_id,
                   image_type,
                   encrypt_key=None,
                   erased_val=None,
                   boot_record='default'):
        """
        Signs hex file with the key specified in the policy file.
        Converts binary file of the signed image.
        Creates copy of unsigned hex file.
        Encrypts UPGRADE image if the policy file contains encryption key
        :param hex_file: The hex file to sign.
        :param image_id: The ID of the firmware in policy file.
        :param image_type: The image type.
        :param encrypt_key: path to public key file for the image encryption
        :param erased_val: The value that is read back from erased flash
        :param boot_record: Create CBOR encoded boot record TLV.
               The sw_type represents the role of the software component
               (e.g. CoFM for coprocessor firmware). [max. 12 characters]
        :return: Path to the signed files. One file per slot.
        """
        result = []
        slot = self.parser.get_slot(image_id)

        if erased_val:
            self.erased_val = erased_val
            ih_padding = int(erased_val, 0)
            logger.warning(f'Custom value {erased_val} will be used as an '
                           f'erased value for all regions and memory types. '
                           f'Typical correct values for internal and '
                           f'external Flash memory are 0x00 and 0xFF '
                           f'respectively.')
        else:
            default_erased_val = self._default_erased_value(image_type, slot)
            ih_padding = int(default_erased_val, 0)

        if slot is None:
            logger.error(
                f'Image with ID {image_id} not found in \'{self.policy_file}\''
            )
            return None
        unsigned_hex = '{0}_{2}{1}'.format(*os.path.splitext(hex_file) +
                                           ('unsigned', ))
        copy2(hex_file, unsigned_hex)

        boot_ih = IntelHex()
        boot_ih.padding = ih_padding
        boot_ih.loadfile(hex_file, 'hex')
        base_addr = boot_ih.minaddr()
        boot_bin = f'{hex_file}.bin'
        hex2bin(boot_ih, boot_bin)

        encrypted_boot = False
        first_image_result = None  # indicates first image signing success
        for image in slot['resources']:
            if image_type:
                if image['type'] != image_type.upper():
                    continue  # skip generating hex file if sign type defined and not same as current image type
            if image['type'] == ImageType.UPGRADE.name:
                if 'upgrade' not in slot or not slot['upgrade']:
                    continue  # skip generating hex file for UPGRADE slot if it is disabled

            encryption = self.parser.encryption_enabled(slot['id'])
            if encryption:
                if encrypt_key is None:
                    encrypt_key = self.parser.encrypt_key(slot['id'])
                    if encrypt_key is None:
                        raise ValueError('Encryption key not specified')
                    else:
                        if not os.path.isfile(encrypt_key):
                            raise FileNotFoundError(
                                f'Encryption key \'{encrypt_key}\' not found')
            else:
                encrypt_key = None

            if image['type'] == ImageType.BOOT.name:
                if first_image_result is False:
                    continue

                hex_out = self.sign_single_hex(slot,
                                               image['type'],
                                               boot_bin,
                                               hex_file,
                                               start_addr=base_addr,
                                               boot_record=boot_record,
                                               encrypt_key=encrypt_key)
                encrypted_boot = encrypt_key is not None
                first_image_result = hex_out is not None
                os.remove(boot_bin)
            else:
                if first_image_result is False:
                    continue

                output_name = '{0}_{2}{1}'.format(*os.path.splitext(hex_file) +
                                                  ('upgrade', ))

                hex_out = self.sign_single_hex(slot,
                                               image['type'],
                                               unsigned_hex,
                                               output_name,
                                               encrypt_key,
                                               boot_record=boot_record)
                first_image_result = hex_out is not None
                if hex_out:
                    bin_out = '{0}.bin'.format(os.path.splitext(hex_out)[0])

                    if not erased_val:
                        default_erased_val = self._default_erased_value(
                            image_type, slot)
                        ih_padding = int(default_erased_val, 0)

                    upgrade_ih = IntelHex()
                    upgrade_ih.padding = ih_padding
                    upgrade_ih.loadfile(hex_out, 'hex')

                    hex2bin(upgrade_ih, bin_out)
                    bin2hex(bin_out, output_name, offset=int(image['address']))
                    os.remove(bin_out)
            if hex_out:
                result.append(hex_out)

        if encrypted_boot:
            self.replace_image_body(hex_file, unsigned_hex, ih_padding)

        if image_type:
            if ImageType.UPGRADE.name == image_type.upper():
                os.remove(hex_file)
        result = tuple(result) if len(result) > 0 else None

        return result
Example #30
0
def import_file(filename):
    ih = IntelHex()
    ih.loadfile(filename, format='bin')
    return ih