Example #1
0
def merge_region_list(region_list, destination, padding=b'\xFF'):
    """Merege the region_list into a single image

    Positional Arguments:
    region_list - list of regions, which should contain filenames
    destination - file name to write all regions to
    padding - bytes to fill gapps with
    """
    merged = IntelHex()

    print("Merging Regions:")

    for region in region_list:
        if region.active and not region.filename:
            raise ToolException("Active region has no contents: No file found.")
        if region.filename:
            print("  Filling region %s with %s" % (region.name, region.filename))
            part = intelhex_offset(region.filename, offset=region.start)
            part_size = (part.maxaddr() - part.minaddr()) + 1
            if part_size > region.size:
                raise ToolException("Contents of region %s does not fit"
                                    % region.name)
            merged.merge(part)
            pad_size = region.size - part_size
            if pad_size > 0 and region != region_list[-1]:
                print("  Padding region %s with 0x%x bytes" % (region.name, pad_size))
                merged.puts(merged.maxaddr() + 1, padding * pad_size)

    if not exists(dirname(destination)):
        makedirs(dirname(destination))
    print("Space used after regions merged: 0x%x" %
          (merged.maxaddr() - merged.minaddr() + 1))
    with open(destination, "wb+") as output:
        merged.tofile(output, format='bin')
Example #2
0
def merge_region_list(region_list, destination, padding=b'\xFF'):
    """Merege the region_list into a single image

    Positional Arguments:
    region_list - list of regions, which should contain filenames
    destination - file name to write all regions to
    padding - bytes to fill gapps with
    """
    merged = IntelHex()

    print("Merging Regions:")

    for region in region_list:
        if region.active and not region.filename:
            raise ToolException("Active region has no contents: No file found.")
        if region.filename:
            print("  Filling region %s with %s" % (region.name, region.filename))
            part = intelhex_offset(region.filename, offset=region.start)
            part_size = (part.maxaddr() - part.minaddr()) + 1
            if part_size > region.size:
                raise ToolException("Contents of region %s does not fit"
                                    % region.name)
            merged.merge(part)
            pad_size = region.size - part_size
            if pad_size > 0 and region != region_list[-1]:
                print("  Padding region %s with 0x%x bytes" % (region.name, pad_size))
                merged.puts(merged.maxaddr() + 1, padding * pad_size)

    if not exists(dirname(destination)):
        makedirs(dirname(destination))
    print("Space used after regions merged: 0x%x" %
          (merged.maxaddr() - merged.minaddr() + 1))
    with open(destination, "wb+") as output:
        merged.tofile(output, format='bin')
Example #3
0
def main(args):
    if len(args) == 1:
        img = Image.open(sys.stdin)
    else:
        img = Image.open(args[1])
    
    if img.mode not in ('1', 'P'):
        sys.exit("Expected a 1-bit image, got %s" % img.mode)
    
    if img.size != (8, 8):
        sys.exit("Expected an 8x8 pixel image")
    
    if 'duration' not in img.info:
        sys.exit("Expected an animation")
    
    out = IntelHex()
    out.puts(0x00, struct.pack("BBB", 1, img.info['duration'] / 10, 0))
    
    for idx, frame in enumerate(ImageSequence.Iterator(img)):
        framedata = [0] * 8
        for i, bit in enumerate(frame.getdata()):
            framedata[i % 8] = (framedata[i % 8] << 1) | bit
        out.puts(data_offset + idx * 8, struct.pack('8B', *framedata))
    
    # Write out the frame count
    out[0x02] = idx + 1
    
    if len(args) == 2:
        out.tofile(sys.stdout, format='hex')
    else:
        out.tofile(open(args[2], 'w'), format='hex')
Example #4
0
def dump_state(filename, regs, content_chunks):
    from intelhex import IntelHex
    ih = IntelHex()

    for base_addr, contents in content_chunks.items():
        # print("Adding chunk of size 0x{:x}".format(len(contents)))
        # f.write("0x{:08x} {}\n".format(base_addr, hexlify(contents.rstrip(b'\0')).decode()))
        ih.puts(base_addr, contents)

    with open(filename, "w") as f:
        f.write("""r0=0x{:x}
r1=0x{:x}
r2=0x{:x}
r3=0x{:x}
r4=0x{:x}
r5=0x{:x}
r6=0x{:x}
r7=0x{:x}
r8=0x{:x}
r9=0x{:x}
r10=0x{:x}
r11=0x{:x}
r12=0x{:x}
lr=0x{:x}
pc=0x{:x}
sp=0x{:x}
xpsr=0x{:x}
""".format(*[regs[const] for const in uc_reg_consts]))
        print("Writing ihex dump now...")
        ih.write_hex_file(f)
Example #5
0
def main(args):
    if len(args) == 1:
        img = Image.open(sys.stdin)
    else:
        img = Image.open(args[1])

    if img.mode not in ('1', 'P'):
        sys.exit("Expected a 1-bit image, got %s" % img.mode)

    if img.size != (8, 8):
        sys.exit("Expected an 8x8 pixel image")

    if 'duration' not in img.info:
        sys.exit("Expected an animation")

    out = IntelHex()
    out.puts(0x00, struct.pack("BBB", 1, img.info['duration'] / 10, 0))

    for idx, frame in enumerate(ImageSequence.Iterator(img)):
        framedata = [0] * 8
        for i, bit in enumerate(frame.getdata()):
            framedata[i % 8] = (framedata[i % 8] << 1) | bit
        out.puts(data_offset + idx * 8, struct.pack('8B', *framedata))

    # Write out the frame count
    out[0x02] = idx + 1

    if len(args) == 2:
        out.tofile(sys.stdout, format='hex')
    else:
        out.tofile(open(args[2], 'w'), format='hex')
Example #6
0
    def __init__(self, fw, channel=16, serial_port=None, snr=None):
        '''
           Ininitialises the OTA Flasher class which handles flashing the devboard
           with the needed OTA Server firmware and the update file for the OTA Client.
           The said devboard shall become the OTA Server which shall propagate the
           image on the Zigbee network.

           Keyword arguments:
           fw -- path to the update file for the OTA Client
           channel -- a 802.15.4 channel number, on which the OTA Server shall operate (default 16)
           serial_port -- a serial port of the connected devboard which shall be flashed with OTA Server
           snr -- a JLink serial number of the connected devboard which shall be flashed with OTA Server

           Note: only one parameter out of (serial_port, snr) must be provided, since the superclass
                 constructor shall handle resolving the rest.

        '''
        # Call the superclass constructor
        super().__init__(serial_port, snr)
        # Create a Intel Hex out of the Zigbee Update file
        ih = IntelHex()
        update = open(fw, 'rb').read()
        ih.puts(OTAFlasher.OTA_UPDATE_OFFSET, update)
        self.update_firmware_hex = fw + '.hex'
        ih.write_hex_file(self.update_firmware_hex)
        # Open the serial channel to the devboard and save the 802.15.4 channel
        self.ser = Serial(self.serial_port, 115200)
        self.channel = channel
Example #7
0
 def save(self, path, hex_addr=None):
     """Save an image from a given file"""
     ext = os.path.splitext(path)[1][1:].lower()
     if ext == INTEL_HEX_EXT:
         # input was in binary format, but HEX needs to know the base addr
         if self.base_addr is None and hex_addr is None:
             raise click.UsageError("No address exists in input file "
                                    "neither was it provided by user")
         h = IntelHex()
         if hex_addr is not None:
             self.base_addr = hex_addr
         h.frombytes(bytes=self.payload, offset=self.base_addr)
         if self.pad:
             trailer_size = self._trailer_size(self.align, self.max_sectors,
                                               self.overwrite_only,
                                               self.enckey,
                                               self.save_enctlv,
                                               self.enctlv_len)
             trailer_addr = (self.base_addr + self.slot_size) - trailer_size
             padding = bytes([self.erased_val] *
                             (trailer_size - len(boot_magic))) + boot_magic
             h.puts(trailer_addr, padding)
         h.tofile(path, 'hex')
     else:
         if self.pad:
             self.pad_to(self.slot_size)
         with open(path, 'wb') as f:
             f.write(self.payload)
def read(start, lenght, fname):
    stop=start+lenght
    f=fname
    print "Dumping from %04x to %04x as %s." % (start,stop,f)
    #h = IntelHex16bit(None)
    # FIXME: get mcu state and return it to that state
    

    try:
        h = IntelHex(None)
        i=start
        while i<=stop:
            #data=client.ARMreadMem(i, 48)
            data=client.ARMreadChunk(i, 48, verbose=0)
            print "Dumped %06x."%i
            for dword in data:
                if i<=stop and dword != 0xdeadbeef:
                    h.puts( i, struct.pack("<I", dword) )
                i+=4
        # FIXME: get mcu state and return it to that state
    except:
        print "Unknown error during read. Writing results to output file."
        print "Rename file with last address dumped %06x."%i
        pass
    h.write_hex_file(f)
Example #9
0
    def dumpV2(self, all):
        start_address = 0x3ff2 if all else 0x37f8
        cmd_verif = [0xa6, 0, 0, 0, 0, 0, 0, 0]
        cmd_verif[1] = 5 + 8
        # find block of 8 0xFF at the end of the device memory
        block = [0xff] * 8
        found = False
        data = [d ^ self.scrambleCodeV2[i % 8] for i, d in enumerate(block)]
        for address in range(start_address, -1, -1):
            print('Looking for 0xFF block at address 0x{:04X}'.format(
                address), end='\n')
            cmd_verif[3:5] = address & 0xFF, (address >> 8) & 0xFF
            r, _ = self.cmd_verify_v2(bin_str_of_list(cmd_verif + data))
            if r == 0:
                print('\nFound 0xFF block at address 0x{:04X}'.format(address))
                found = True
                break
        if not found:
            print('\nUnable to find 0xFF block')
            return
        memdump = IntelHex()
        memdump.puts(address, bin_str_of_list(block))

        print('Starting flash dumping')
        for i in reversed(block):
            print('{:02X} '.format(i), end='')
        sys.stdout.flush()

        nTry = 0
        nBytes = 0
        for address in range(address - 1, -1, -1):
            block[1:] = block[:-1]  # shift
            cmd_verif[3:5] = address & 0xFF, (address >> 8) & 0xFF
            found = False
            for i in range(256):
                val = stats[i]
                block[0] = val
                nTry += 1
                data = [d ^ self.scrambleCodeV2[i % 8]
                        for i, d in enumerate(block)]
                r, _ = self.cmd_verify_v2(bin_str_of_list(cmd_verif + data),9)
                if r == 0:  # verification ok, we found the correct byte
                    print('{:02X} '.format(val), end='')
                    sys.stdout.flush()
                    found = True
                    nBytes += 1
                    memdump[address] = val
                    break
            if not found:
                raise ValueError('Unable to find correct '
                                 'byte for address 0x{:04X}'.format(address))

        output_bin = 'out.bin'
        output_hex = 'out.hex'
        print('\nDone, writing output files {} and {}'.format(output_bin,
                                                              output_hex))
        print('Ntry = {} {:.2f}try/bytes'.format(nTry, float(nTry) / nBytes))
        memdump.tobinfile(output_bin)
        memdump.tofile(output_hex, format='hex')
Example #10
0
def main():
    try:
        os.remove(RESULT)
    except OSError:
        pass

    ihx = IntelHex()
    ihx.fromfile(TARGET, format='hex')
    addr_min, addr_max = ihx.minaddr(), ihx.maxaddr()
    print hex(addr_min), hex(addr_max)

    ihx.tofile(TEST, format='hex')

    d = Disassembler()
    function = ihx.tobinarray()[FUNC_START:]
    blocks = d.parse(function, 0, FUNC_START)

    for b in blocks:
        print '-' * 40
        print repr(b)

    print '-' * 40
    blocks = sum(blocks)

    data = blocks.assemble(FUNC_START, externalize_labels=True)
    print 'Stream:', ' '.join('%02x' % b for b in bytearray(data))

    data_length = len(data)
    print 'Writing %d bytes.' % data_length

    ihx.puts(FUNC_START, data)

    appendix = Block()
    label_nops = Label('look_mah_no_ops')
    appendix += Block(label_nops, nop, nop, nop, nop)

    appendix += Block(Data('\xef\xbe'))
    appendix += Block(Data(0xbeef))
    appendix += Block(Data(label_nops))

    end = ihx.maxaddr() + 1
    data = appendix.assemble(end, externalize_labels=True)

    data_length = len(data)
    print 'Writing %d bytes.' % data_length

    ihx.puts(end, data)

    ihx.tofile(RESULT, format='hex')

    patched = IntelHex()
    patched.fromfile(RESULT, format='hex')

    check = ihx.tobinarray()[FUNC_START:FUNC_START + data_length]
    print 'Stream:', ' '.join('%02x' % b for b in bytearray(data))

    print hex(patched.minaddr()), hex(patched.maxaddr())
Example #11
0
def main():
    try:
        os.remove(RESULT)
    except OSError:
        pass

    ihx = IntelHex()
    ihx.fromfile(TARGET, format='hex')
    addr_min, addr_max = ihx.minaddr(), ihx.maxaddr()
    print hex(addr_min), hex(addr_max)

    ihx.tofile(TEST, format='hex')

    d = Disassembler()
    function = ihx.tobinarray()[FUNC_START:]
    blocks = d.parse(function, 0, FUNC_START)

    for b in blocks:
        print '-' * 40
        print repr(b)

    print '-' * 40
    blocks = sum(blocks)

    data = blocks.assemble(FUNC_START, externalize_labels=True)
    print 'Stream:', ' '.join('%02x' % b for b in bytearray(data))

    data_length = len(data)
    print 'Writing %d bytes.' % data_length

    ihx.puts(FUNC_START, data)

    appendix = Block()
    label_nops = Label('look_mah_no_ops')
    appendix += Block(label_nops, nop, nop, nop, nop)

    appendix += Block(Data('\xef\xbe'))
    appendix += Block(Data(0xbeef))
    appendix += Block(Data(label_nops))

    end = ihx.maxaddr() + 1
    data = appendix.assemble(end, externalize_labels=True)

    data_length = len(data)
    print 'Writing %d bytes.' % data_length

    ihx.puts(end, data)

    ihx.tofile(RESULT, format='hex')

    patched = IntelHex()
    patched.fromfile(RESULT, format='hex')

    check = ihx.tobinarray()[FUNC_START:FUNC_START + data_length]
    print 'Stream:', ' '.join('%02x' % b for b in bytearray(data))

    print hex(patched.minaddr()), hex(patched.maxaddr())
Example #12
0
 def tofile(self, outfile: Union[str, IO]) -> None:
     ih = IntelHex()
     ih.puts(self.base or 0, bytes(self.fw))
     if Firmware._ishex(outfile):
         if not isinstance(outfile, str):
             outfile = io.TextIOWrapper(outfile)
         ih.write_hex_file(outfile)
     else:
         ih.tobinfile(outfile)
Example #13
0
    def post_process(self):
        logging.info("Processing binaries")
        
        # save original dir
        cwd = os.getcwd()

        # change to target dir
        os.chdir(self.target_dir)

        ih = IntelHex('main.hex')
        
        fwid = uuid.UUID('{' + self.settings["FWID"] + '}')
        
        size = ih.maxaddr() - ih.minaddr() + 1
        
        # get os info
        os_project = get_project_builder(self.settings["OS_PROJECT"])

        # create firmware info structure
        fw_info = struct.pack('<I16s128s16s128s16s', 
                                size, 
                                fwid.bytes, 
                                os_project.proj_name, 
                                os_project.version, 
                                self.proj_name,
                                self.version)
        
        # insert fw info into hex
        ih.puts(0x120, fw_info)

        # compute crc
        crc_func = crcmod.predefined.mkCrcFun('crc-aug-ccitt')

        crc = crc_func(ih.tobinstr())

        logging.info("size: %d" % (size))
        logging.info("fwid: %s" % (fwid))
        logging.info("crc: 0x%x" % (crc))
        logging.info("os name: %s" % (os_project.proj_name))
        logging.info("os version: %s" % (os_project.version))
        logging.info("app name: %s" % (self.proj_name))
        logging.info("app version: %s" % (self.version))

        ih.puts(ih.maxaddr() + 1, struct.pack('>H', crc))

        ih.write_hex_file('main.hex')
        ih.tobinfile('firmware.bin')
        
        # get loader info
        loader_project = get_project_builder(self.settings["LOADER_PROJECT"])

        # create loader image
        loader_hex = os.path.join(loader_project.target_dir, "main.hex")
        self.merge_hex('main.hex', loader_hex, 'loader_image.hex')
        
        # change back to original dir
        os.chdir(cwd)
Example #14
0
def create_hex(filename, addr, auto_rst, pad_size):
    file_format = 'hex'
    intel_hex = IntelHex()
    intel_hex.puts(addr, struct.pack(FORMAT, CFG_KEY, FORMAT_LENGTH, auto_rst))
    pad_addr = addr + FORMAT_LENGTH
    pad_byte_count = pad_size - (FORMAT_LENGTH % pad_size)
    pad_data = '\xFF' * pad_byte_count
    intel_hex.puts(pad_addr, pad_data)
    with open(filename, 'wb') as f:
        intel_hex.tofile(f, file_format)
Example #15
0
def create_hex(filename, addr, auto_rst, automation_allowed,
               overflow_detect, detect_incompatible_target, pad_size):
    intel_hex = IntelHex()
    intel_hex.puts(addr, struct.pack(FORMAT, CFG_KEY, FORMAT_LENGTH, auto_rst,
                                     automation_allowed, overflow_detect, detect_incompatible_target))
    pad_addr = addr + FORMAT_LENGTH
    pad_byte_count = pad_size - (FORMAT_LENGTH % pad_size)
    pad_data = '\xFF' * pad_byte_count
    intel_hex.puts(pad_addr, pad_data)
    intel_hex.write_hex_file(filename)
Example #16
0
    def dump(self):
        end_address = 0x3ff0
        # send the key
        b = '\xa6\x04' + struct.pack('BBBB', *scrambleCode)
        self.xcmd(b, 0)
        # find block of 16 0xFF at the end of the device memory
        block = [0xff] * 16
        found = False
        for address in range(end_address, -1, -1):
            print('\rLooking for address 0x{:04X}'.format(address), end='')
            r = self.cmd('\xa7\16' + struct.pack('<H', address) +
                         bin_str_of_list(scramble(block)))
            if r == 0:
                print('\nFound 0xFF block at address 0x{:04X}'.format(address))
                found = True
                break
        if not found:
            print('\nUnable to find 0xFF block')
            return

        memdump = IntelHex()
        memdump.puts(address, bin_str_of_list(block))
  
        print('Starting flash dumping')
        base = [0xa7, 16, 0, 0]
        nTry = 0
        nBytes = 0
        for address in range(address - 1, - 1, -1):
            block[1:] = block[:-1]  # shift
            base[2:4] = address & 0xFF, address >> 8
            found = False
            for i in range(256):
                i = stats[i]
                block[0] = i
                nTry += 1
                r = self.cmd(bin_str_of_list(base + scramble(block)), 4)
                if r == 0:  # verification ok, we found the correct byte
                    print('{:02X} '.format(i), end='')
                    sys.stdout.flush()
                    found = True
                    nBytes += 1
                    memdump[address] = i
                    break
            if not found:
                raise ValueError('Unable to find correct '
                                 'byte for address 0x{:04X}'.format(address))

        output_bin = 'out.bin'
        output_hex = 'out.hex'
        print('\nDone, writing output files {} and {}'.format(output_bin,
                                                              output_hex))
        print('Ntry = {} {:.2f}try/bytes'.format(nTry, float(nTry) / nBytes))
        memdump.tobinfile(output_bin)
        memdump.tofile(output_hex, format='hex')
Example #17
0
    def to_eep_file(self, eep_file_name):
        """Save the configuration to an EEPROM-file."""
        hex_file = IntelHex()

        # Change any existing files instead of overwriting them.
        if os.path.isfile(eep_file_name):
            hex_file.fromfile(eep_file_name, format='hex')

        data = self.to_bytes(crc=True)
        hex_file.puts(Config.START_ADDRESS, data)
        hex_file.write_hex_file(eep_file_name, byte_count=0x20)
Example #18
0
 def tofile(self,
            outfile: Union[str, BinaryIO],
            fmt: Optional[str] = None) -> None:
     if fmt is None and isinstance(
             outfile, str) and outfile.lower().endswith('.hex'):
         fmt = 'hex'
     else:
         fmt = 'bin'
     ih = IntelHex()
     ih.puts(self.base or 0, bytes(self.fw))
     ih.tofile(outfile, fmt)
Example #19
0
def create_hex(filename, addr, auto_rst, automation_allowed, pad_size):
    file_format = 'hex'
    intel_hex = IntelHex()
    intel_hex.puts(addr, struct.pack(FORMAT, CFG_KEY, FORMAT_LENGTH, auto_rst,
                                     automation_allowed))
    pad_addr = addr + FORMAT_LENGTH
    pad_byte_count = pad_size - (FORMAT_LENGTH % pad_size)
    pad_data = '\xFF' * pad_byte_count
    intel_hex.puts(pad_addr, pad_data)
    with open(filename, 'wb') as f:
        intel_hex.tofile(f, file_format)
Example #20
0
def _main():
    """Append credentials to a prebuilt hex file, download it via a J-Link debug probe,
    allow the hex file to run, verify the result code, and then erase the hex file.
    """
    args = _add_and_parse_args()
    nrfjprog_api = None
    nrfjprog_probe = None
    try:
        hex_path = HEX_PATH
        if args.in_file:
            hex_path = args.in_file
        intel_hex = IntelHex(hex_path)
        if intel_hex.maxaddr() >= CRED_PAGE_ADDR:
            if hex_path == HEX_PATH:
                print("error: Prebuilt hex file is too large.")
                _close_and_exit(nrfjprog_api, -3)
            elif (intel_hex.maxaddr() < FW_RESULT_CODE_ADDR or
                  intel_hex.gets(CRED_PAGE_ADDR, 4) != MAGIC_NUMBER_BYTES):
                print("error: Magic number not found in hex file.")
                _close_and_exit(nrfjprog_api, -2)
        else:
            intel_hex.puts(CRED_PAGE_ADDR, MAGIC_NUMBER_BYTES)
            intel_hex.puts(CRED_COUNT_ADDR, struct.pack('B', 0x00))
        if not args.out_file or args.program_app:
            nrfjprog_api, nrfjprog_probe = _connect_to_jlink(args)
        _append_creds(intel_hex, args)
        if args.out_file:
            intel_hex.tofile(args.out_file, "hex")
        else:
            # Create a temporary file to pass to pynrfjprog and then delete it when finished.
            tmp_file = os.path.sep.join((tempfile.mkdtemp(), TMP_FILE_NAME))
            intel_hex.tofile(tmp_file, "hex")
            _write_firmware(nrfjprog_probe, tmp_file)
            time.sleep(args.fw_delay)
            result_code = nrfjprog_probe.read(FW_RESULT_CODE_ADDR)
            if result_code:
                print("error: Firmware result is 0x{:X}".format(result_code))
                _close_and_exit(nrfjprog_api, -4)
            imei_bytes = nrfjprog_probe.read(IMEI_ADDR, IMEI_LEN + 1)
            if (IMEI_LEN != imei_bytes.find(BLANK_FLASH_VALUE) or
                    not imei_bytes[:IMEI_LEN].isdigit()):
                print("error: IMEI does not look valid.")
                _close_and_exit(nrfjprog_api, -5)
            print(imei_bytes[:-1].decode())
            nrfjprog_probe.erase(HighLevel.EraseAction.ERASE_ALL)
            os.remove(tmp_file)
            os.removedirs(os.path.dirname(tmp_file))
        if args.program_app:
            _write_firmware(nrfjprog_probe, args.program_app)

        _close_and_exit(nrfjprog_api, 0)
    except Exception as ex:
        print("error: " + str(ex))
        _close_and_exit(nrfjprog_api, -2)
Example #21
0
    def read(self, address, length, hex_file_path):

        if ((int(length, 16) % 4) != 0):
            print("ERROR: number of bytes must be a multiple of 4")
            return NrfDfuErr.INVALID_PARAMETER

        if (not self._quiet):
            print("Reading %s bytes from address %s" % (length, address))

        open(hex_file_path, 'w+')
        ih = IntelHex(hex_file_path)
        ih.__init__()

        self.api.write_u32(0x2000000C, 0x00000004, True)
        self.api.write_u32(0x20000010, int(address, 16), False)
        self.api.write_u32(0x20000014, int(length, 16), False)

        self.api.write_u32(0x4002A004, 0x00000001, False)

        start_time = time.time()
        event_received = False
        while (event_received == False):
            if ((time.time() - start_time) > 10):
                print ("ERROR: Time out, no event received after 10 sec.")
                return NrfDfuErr.TIME_OUT
            return_value, event_received = self.get_event_status()
            if return_value < 0:
                return return_value

        self.acknowlage_events()

        return_value, modem_response = self.read_be(0x2000000C)

        if (modem_response == "5a000001"):
            print("\n\n ERROR: UNKNOWN COMMAND")
            return NrfDfuErr.DFU_ERROR
        elif (modem_response == "5a000002"):
            print("\n\n ERROR: COMMAND ERROR")
            error_result = self.api.read_u32(0x20000010)
            print("ERROR: Read failed at {}".format(hex(error_result)))
            return NrfDfuErr.DFU_ERROR

        word_count = int(length, 16)//4

        for i in range(0, word_count):
            return_value, lelevel = self.hex_read(0x20000010+(i*4))
            ih.puts(int(address,16)+(i*4), codecs.decode(lelevel, "hex"))

        ih.write_hex_file(hex_file_path)
        if (not self._quiet):
            print ("Reading completed")

        return NrfDfuErr.SUCCESS
Example #22
0
  def to_hex(self, f):
    '''
    Convert the assembled machine code to Intel HEX file format.

    :param f: The HEX data will be written to this destination.
    :type f: filename or file-like object
    '''
    from intelhex import IntelHex
    ih = IntelHex()
    for addr, val in self.accumulator.iteritems():
      addr = int(addr, 16)
      ih.puts(addr, val)
    ih.write_hex_file(f)
Example #23
0
def main(args: argparse.Namespace):
    brtype = args.branch_type
    hexfile = args.hexfile

    # Pad a numeric string with zeros
    brtype = brtype.zfill(BRANCH_TYPE_BYTES * 2)

    # Split string data into bytes (e.g. "AABBCCDD" -> b'\xaa\xbb\xcc\xdd'
    bytes_brtype = bytes.fromhex(brtype)

    '''
    # for debug
    print("bytes_brtype=", end='')
    print(bytes_brtype)
    '''

    ih = IntelHex()

    # Write out user defined data
    global csvFilePath
    csvFilePath = args.user_data
    if csvFilePath is not None:
        # if csvFilePath is given
        if os.path.exists(csvFilePath):
            with open(csvFilePath, 'r') as fp:
                csvList = list(csv.reader(fp))
                if len(csvList) > 0:
                    print("csvList has some contents")
                    flatList = [item for subList in csvList for item in subList]
                    print(flatList)
                    bytes_data = strlist_to_bytes(flatList)
                    if len(bytes_data) > 0:
                        ih.puts(USER_DATA_ADDR, bytes_data)
                else:
                    print(csvFilePath + " is empty")
                    ErrorMsg()
        else:
            print(csvFilePath + " not found. Skip user defined EEPROM data flash.")
            print()
    else:
        print("Skip user defined EEPROM data flash.")
        print()

    # Write out branchType
    ih.puts(SYSTEM_RESERVED_ADDR, bytes_brtype)

    hex_file_name = os.path.join(os.path.dirname(os.path.abspath(__file__)), hexfile)

    ih.dump()
    ih.write_hex_file(hex_file_name)
def combine(bootloader_fn, app_fn, app_addr, hdr_addr, bootloader_addr,
            output_fn, version, no_bootloader):
    # read bootloader
    bootloader_format = bootloader_fn.split('.')[-1]
    bootloader = IntelHex()
    if not no_bootloader:
        if bootloader_format == 'hex':
            bootloader.fromfile(bootloader_fn, bootloader_format)
        elif bootloader_format == 'bin':
            bootloader.loadbin(bootloader_fn, bootloader_addr)
        else:
            print('Bootloader format can only be .bin or .hex')
            exit(-1)

    # read application
    app_format = app_fn.split('.')[-1]
    app = IntelHex()
    if app_format == 'hex':
        app.fromfile(app_fn, app_format)
    elif app_format == 'bin':
        app.loadbin(app_fn, app_addr)
    else:
        print('Application format can only be .bin or .hex')
        exit(-1)

    # create firmware header
    header = IntelHex()
    fw_header = create_header(app.tobinstr(), version)
    header.puts(hdr_addr, fw_header)

    # combine
    output_format = output_fn.split('.')[-1]
    output = IntelHex()
    if not no_bootloader:
        print("Writing bootloader to address 0x%08x-0x%08x." %
              (bootloader.addresses()[0], bootloader.addresses()[-1]))
        output.merge(bootloader, overlap='error')
    print("Writing header to address 0x%08x-0x%08x." %
          (header.addresses()[0], header.addresses()[-1]))
    output.merge(header, overlap='error')
    print("Writing application to address 0x%08x-0x%08x." %
          (app.addresses()[0], app.addresses()[-1]))
    output.merge(app, overlap='error')

    # write output file
    output.tofile(output_fn, format=output_format)
Example #25
0
def merge_region_list(region_list, destination, notify, padding=b'\xFF'):
    """Merge the region_list into a single image

    Positional Arguments:
    region_list - list of regions, which should contain filenames
    destination - file name to write all regions to
    padding - bytes to fill gapps with
    """
    merged = IntelHex()
    _, format = splitext(destination)

    notify.info("Merging Regions")

    for region in region_list:
        if region.active and not region.filename:
            raise ToolException("Active region has no contents: No file found.")
        if isinstance(region.filename, list):
            header_basename, _ = splitext(destination)
            header_filename = header_basename + "_header.hex"
            _fill_header(region_list, region).tofile(header_filename, format='hex')
            region = region._replace(filename=header_filename)
        if region.filename:
            notify.info("  Filling region %s with %s" % (region.name, region.filename))
            part = intelhex_offset(region.filename, offset=region.start)
            part.start_addr = None
            part_size = (part.maxaddr() - part.minaddr()) + 1
            if part_size > region.size:
                raise ToolException("Contents of region %s does not fit"
                                    % region.name)
            merged.merge(part)
            pad_size = region.size - part_size
            if pad_size > 0 and region != region_list[-1]:
                notify.info("  Padding region %s with 0x%x bytes" %
                            (region.name, pad_size))
                if format is ".hex":
                    """The offset will be in the hex file generated when we're done,
                    so we can skip padding here"""
                else:
                    merged.puts(merged.maxaddr() + 1, padding * pad_size)

    if not exists(dirname(destination)):
        makedirs(dirname(destination))
    notify.info("Space used after regions merged: 0x%x" %
                (merged.maxaddr() - merged.minaddr() + 1))
    merged.tofile(destination, format=format.strip("."))
Example #26
0
def combine(bootloader_fn, app_fn, app_addr, hdr_addr, bootloader_addr,
            output_fn, version, no_bootloader):
    ih = IntelHex()

    bootloader_format = bootloader_fn.split('.')[-1]

    # write the bootloader
    if not no_bootloader:
        print("Using bootloader %s" % bootloader_fn)
        if bootloader_format == 'hex':
            print("Loading bootloader from hex file.")
            ih.fromfile(bootloader_fn, format=bootloader_format)
        elif bootloader_format == 'bin':
            print("Loading bootloader to address 0x%08x." % bootloader_addr)
            ih.loadbin(bootloader_fn, offset=bootloader_addr)
        else:
            print('Bootloader format can only be .bin or .hex')
            exit(-1)

    # write firmware header
    app_format = app_fn.split('.')[-1]
    if app_format == 'bin':
        with open(app_fn, 'rb') as fd:
            app_blob = fd.read()
    elif app_format == 'hex':
        application = IntelHex(app_fn)
        app_blob = application.tobinstr()
    FirmwareHeader = create_header(app_blob, version)
    print("Writing header to address 0x%08x." % hdr_addr)
    ih.puts(hdr_addr, FirmwareHeader)

    # write the application
    if app_format == 'bin':
        print("Loading application to address 0x%08x." % app_addr)
        ih.loadbin(app_fn, offset=app_addr)
    elif app_format == 'hex':
        print("Loading application from hex file")
        ih.fromfile(app_fn, format=app_format)

    # output to file
    ih.tofile(output_fn, format=output_fn.split('.')[-1])
Example #27
0
    def dump(self,fn,start=0,stop=0xffffffff):
        """Dump an intel hex file from code memory."""
        
        print "Dumping from %04x to %04x as %s." % (start,stop,f);
        # FIXME: get mcu state and return it to that state
        self.halt()

        h = IntelHex(None);
        i=start;
        while i<=stop:
            data=self.ARMreadChunk(i, 48, verbose=0);
            print "Dumped %06x."%i;
            for dword in data:
                if i<=stop and dword != 0xdeadbeef:
                    h.puts( i, struct.pack("<I", dword) )
                i+=4;
        # FIXME: get mcu state and return it to that state
        self.resume()
        h.write_hex_file(fn);

        print "Dump not implemented.";
Example #28
0
    def dump(self, fn, start=0, stop=0xFFFFFFFF):
        """Dump an intel hex file from code memory."""

        print "Dumping from %04x to %04x as %s." % (start, stop, f)
        # FIXME: get mcu state and return it to that state
        self.halt()

        h = IntelHex(None)
        i = start
        while i <= stop:
            data = self.ARMreadChunk(i, 48, verbose=0)
            print "Dumped %06x." % i
            for dword in data:
                if i <= stop and dword != 0xDEADBEEF:
                    h.puts(i, struct.pack("<I", dword))
                i += 4
        # FIXME: get mcu state and return it to that state
        self.resume()
        h.write_hex_file(fn)

        print "Dump not implemented."
Example #29
0
    def dump(self,fn,start=0,stop=0xffffffff):
        """Dump an intel hex file from code memory."""
        
        print "Dumping from %04x to %04x as %s." % (start,stop,f);
        # FIXME: get mcu state and return it to that state
        self.halt()
        print "halted, starting the dump"

        h = IntelHex(None);
        i=start;
        while i<=stop:
            data=self.ARMreadChunk(i, 48, verbose=0);
            print "Dumped %06x."%i;
            for dword in data:
                if i<=stop and dword != 0xdeadbeef:
                    h.puts( i, struct.pack("<I", dword) )
                i+=4;
        # FIXME: get mcu state and return it to that state
        self.resume()
        h.write_hex_file(fn);

        print "Dump not implemented.";
Example #30
0
def provisionDevice(
    model
):  # create New Device Account , create backupHex file, Flash the device
    FactoryDevHex = IntelHex("BootAppConfig.hex")
    keySectionApp = IntelHex()  # contain key  section of hex file
    #update key section
    #keys A4T4 is stored for "AT" in eeprom
    if (not fbLoginSucess()):
        printE("Login to provision")
        return
    #register new device and load SN
    maxSn = fbReadDb("FirmwareMeta/" + model + "/MaxSn")
    fbWriteDb("FirmwareMeta/" + model + "/MaxSn", maxSn + 1)

    DevSn = base36encode(maxSn, 6)
    userid = model + DevSn  # 8 bytes
    passkey = get_random_password_string(8)  #pass key 8 bytes

    #get model key From Server, makeure for any new device modle key is generated manually
    ModelKey = fbReadDb("FirmwareMeta/" + model +
                        "/ModelKey")  # "MODEL"+model+"0" #8 bytes

    fbWriteDb("FirmwareMeta/" + model + "/DevSnKeys/" + userid, passkey)
    #mearge hex file with keys and generate device hex file

    keysection = userid + passkey + ModelKey + passkey  # last passkey is just filler
    eepKeySection = insertByteAfterOne(
        bytes(passkey + ModelKey, 'utf-8'), 0
    )  # this keys are also loaded into EEP so that user need not have to to FDR
    keysectionFlash = insertByteAfterOne(bytes(
        keysection, 'utf-8'), 0x34)  # 34 in msb signify flash constant
    keySectionApp.puts(KEY_START_ADD * FLASH_WORD_SIZE, keysectionFlash)
    keySectionApp.puts(EEP_KEY_START_ADD * FLASH_WORD_SIZE, eepKeySection)
    FactoryDevHex.merge(keySectionApp)
    FactoryDevHex.write_hex_file("Factory" + model + DevSn + ".hex",
                                 False)  # don't write start address

    currentDevPath = "Factory" + model + DevSn + ".hex"
    return currentDevPath
Example #31
0
    def install_app(self, app_manifest: AppManifest):
        hex_file = IntelHex(app_manifest.get_binary())
        code_length = hex_file.maxaddr() - hex_file.minaddr() + 1
        data_length = app_manifest.data_size

        code_length -= data_length
        assert code_length % 64 == 0  # code length must be aligned

        flags = app_manifest.get_application_flags()  # not handled yet

        params = app_manifest.serialize_parameters()
        main_address = hex_file.start_addr["EIP"] - hex_file.minaddr()

        data = struct.pack(">IIIII", code_length, data_length, len(params),
                           flags, main_address)
        self.apdu_secure_exchange(LedgerSecureIns.CREATE_APP, data)

        hex_file.puts(hex_file.maxaddr() + 1, params)

        for segment in hex_file.segments():
            self._load_segment(hex_file, segment)
        self.apdu_secure_exchange(LedgerSecureIns.COMMIT)
Example #32
0
if modf(chan)[0] != 0.0:
	print "Illegal freq/spacing combo"
	sys.exit(2)

chan = int(chan)

# First create the data without the checksum, note that we specify
# little-endianness for multi-byte values.

t = pack('<BBBHB8x', band, demphasis, spacing, chan, volume)

# Calculate and append a crc-16 checksum
crc16 = Crc('crc-16')
crc16.update(t)

t = t + pack('<H', crc16.crcValue)

#
# Simply create a hex file with the concatenation of two tuning structures (t)
# and optionally one manufacturing structure, then write the result.
#
eeprom = t + t

if manuf:
	eeprom = eeprom + manuf_record(sn, ts, campaign)

hexfile = IntelHex()
hexfile.puts(0, eeprom)
hexfile.write_hex_file(outfile)
Example #33
0
    flash_base = 0x18000000
    cap_delay = 2
    spi_clk = 0
    cfg_info = 0xffffffbf
    image_crypt = 0xffffffff
    sbl_code_start = flash_base+0x1000
    sbl_code_length = len(sbl_data)
    crc_rslt = zlib.crc32(sbl_data)
    crc_bytes = struct.pack("I",crc_rslt)
    sbl_data = sbl_data + crc_bytes
    info_head = struct.pack('LLHHLLLLLL',test_word0,test_word1,cap_delay,spi_clk,cfg_info,image_crypt,0xffffffff,0xffffffff,sbl_code_start,sbl_code_length)
else:
    flash_base = 0x00800000
    code_offset = 0x1000
    sbl_code_length = len(sbl_data)
    sbl_code_start = flash_base+code_offset
    sbl_code_exec_addr = 0x400100
    feature_mask = 0xffffffff
    info_head = struct.pack('LLLLLL',test_word0,test_word1,code_offset,sbl_code_length,sbl_code_exec_addr,feature_mask)
    

mac_addr_base = flash_base + 0x30
mac_addr = bytes([0xff,0xff,0xff,0xff,0xff,0xff]) # ff:ff:ff:ff:ff:ff is not a valid address

ih = IntelHex()
ih.puts(flash_base,info_head)
ih.puts(mac_addr_base,mac_addr)
ih.puts(sbl_code_start,sbl_data)
ih.write_hex_file(sys.argv[3])

Example #34
0
    if vargs.range is not None:
        if vargs.range[0] is not None: startAddr = vargs.range[0]
        if vargs.range[1] is not None: endAddr = vargs.range[1]

    # Make sure the last address is divisible by 16
    remainder = endAddr % OAD_BLOCK_SIZE
    if remainder:
        print(
            "Last address was 0x%0X. Expanded to 0x%0X to be divisible by OAD block size"
            % (endAddr, endAddr + (OAD_BLOCK_SIZE - remainder)))
        endAddr += OAD_BLOCK_SIZE - remainder

    #if specified, the script will pad the image with the pad value
    fillHex = IntelHex()
    fillHex.puts(startAddr, struct.pack('B', vargs.fill) * (endAddr))
    mergedHex.merge(fillHex, 'ignore')
    mergedHex = mergedHex[
        startAddr:endAddr]  # +1 since the last address is not inclusive
    mergedHex.padding = vargs.fill

    #if we are calculating metadata
    #Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these
    #All onchip OAD images need metdata placement
    if not (vargs.oadtype == 'offchip' and
            (vargs.imgtype == 'production' or vargs.imgtype == 'np')):
        # Place metadata, onchip production image expects header at 0x600
        if vargs.oadtype == 'onchip' and vargs.imgtype == 'production':
            residentHdr = OadHdr._make(
                struct.unpack(
                    OAD_HDR_FMT,
Example #35
0
def _fill_header(region_list, current_region):
    """Fill an application header region

    This is done it three steps:
     * Fill the whole region with zeros
     * Fill const, timestamp and size entries with their data
     * Fill the digests using this header as the header region
    """
    region_dict = {r.name: r for r in region_list}
    header = IntelHex()
    header.puts(current_region.start, b'\x00' * current_region.size)
    start = current_region.start
    for member in current_region.filename:
        _, type, subtype, data = member
        if type == "const":
            fmt = {
                "8le": ">B",
                "16le": "<H",
                "32le": "<L",
                "64le": "<Q",
                "8be": "<B",
                "16be": ">H",
                "32be": ">L",
                "64be": ">Q"
            }[subtype]
            header.puts(start, struct.pack(fmt, integer(data, 0)))
        elif type == "timestamp":
            fmt = {
                "32le": "<L",
                "64le": "<Q",
                "32be": ">L",
                "64be": ">Q"
            }[subtype]
            header.puts(start, struct.pack(fmt, int(time())))
        elif type == "size":
            fmt = {
                "32le": "<L",
                "64le": "<Q",
                "32be": ">L",
                "64be": ">Q"
            }[subtype]
            size = sum(_real_region_size(region_dict[r]) for r in data)
            header.puts(start, struct.pack(fmt, size))
        elif type == "digest":
            if data == "header":
                ih = header[:start]
            else:
                ih = intelhex_offset(region_dict[data].filename,
                                     offset=region_dict[data].start)
            if subtype.startswith("CRCITT32"):
                fmt = {"CRCITT32be": ">L", "CRCITT32le": "<L"}[subtype]
                crc_val = zlib.crc32(ih.tobinarray()) & 0xffffffff
                header.puts(start, struct.pack(fmt, crc_val))
            elif subtype.startswith("SHA"):
                if subtype == "SHA256":
                    hash = hashlib.sha256()
                elif subtype == "SHA512":
                    hash = hashlib.sha512()
                hash.update(ih.tobinarray())
                header.puts(start, hash.digest())
        start += Config.header_member_size(member)
    return header
Example #36
0
def get_hex(f, b, d, cs):

    #
    # All the following to be able to be set with getopt.
    # These defaults will do for testing purposes.
    #
    outfile = sys.stdout

    # manufacturing data
    #
    manuf = False
    sn = ""
    ts = ""
    campaign = ""
    eyecatcher = 'The Public Radio'

    # tuning info defaults
    #
    freq = 0.0
    band = 0  # US 87.5 - 108
    demphasis = 0  # US 75uS
    spacing = 0  # US 200KHz
    volume = 0x0f  # max (0 dBFS)

    #
    # Create a manufacturing record.
    #
    def manuf_record(sn, ts, campaign):
        ww = int(date.today().strftime('%V'))
        yy = int(date.today().strftime('%g'))
        return pack('17sBB2s13s17s', sn[:16], ww, yy, ts[:2], campaign[:12],
                    eyecatcher)

    #
    # calculate channel # based on freq, band & channel spacing.
    # Note that we force the floating point arithmetic to round
    # to a reasonable number of digits in order to avoid daft problems.

    freq = float(f)
    band = int(b)
    demphasis = int(d)
    spacing = int(cs)

    base = {0: 87.5, 1: 76, 2: 76}
    step = {0: 5, 1: 10, 2: 20}

    try:
        chan = round((freq - base[band]) * step[spacing], 4)
    except:
        chan = round((freq - base[0]) * step[0], 4)

    if modf(chan)[0] != 0.0:
        chan = 0

    chan = int(chan)

    # First create the data without the checksum, note that we specify
    # little-endianness for multi-byte values.

    t = pack('<BBBHB8x', band, demphasis, spacing, chan, volume)

    # Calculate and append a crc-16 checksum
    crc16 = crcmod.predefined.Crc('crc-16')
    crc16.update(t)

    t = t + pack('<H', crc16.crcValue)

    #
    # Simply create a hex file with the concatenation of two tuning structures (t)
    # and optionally one manufacturing structure, then write the result.
    #
    eeprom = t + t

    if manuf:
        eeprom = eeprom + manuf_record(sn, ts, campaign)

    outfile = tempfile.NamedTemporaryFile(prefix='eeprom.',
                                          suffix='.hex',
                                          delete=False)
    hexfile = IntelHex()
    hexfile.puts(0, eeprom)
    hexfile.write_hex_file(outfile)
    outfile.close()
    return outfile
elif sel == "B":                                # take B_!RST low
    i2c2.write_byte(0x70, 0x4)                  # steer mux
    iob = i2c0.read_byte_data(0x22, 0x14)
    i2c0.write_byte_data(0x22, 0x14, iob&~0x10)

print(icsp_cmd(ser, b'L'))                      # take MCLR low (icsp)
print(icsp_cmd(ser, b'#', 9))                   # reset checksum
# print(icsp_cmd(ser, b'%', 5))                 # reset stats
print(icsp_cmd(ser, b'^'))                      # enter LVP

print("dumping program memory ...")

data = icsp_read_data(ser, 0x4000)
for a in range(0x0000, 0x4000):
    val = data[a]
    ih.puts(a*2, struct.pack("<h", val))

icsp_cmd(ser, b'[X0=]', 0)                      # switch to config mem

print("dumping config memory ...")

data = icsp_read_data(ser, 0x11)
for a in range(0x8000, 0x8011):
    val = data[a - 0x8000]
    ih.puts(a*2, struct.pack("<h", val))

print(icsp_cmd(ser, b'#', 9))                   # retrieve checksum
print(icsp_cmd(ser, b'Z'))                      # tristate MCLK (icsp)

if sel == "A":                                  # bring A_!RST high again
    i2c0.write_byte_data(0x23, 0x14, ioa|0x10)
Example #38
0
        endAddr = ((endAddr + INT_FL_PG_SIZE) & ~(INT_FL_PG_SIZE-1))
        print ('endAddr round', hex(endAddr))

    if vargs.range is not None:
        if vargs.range[0] is not None: startAddr = vargs.range[0]
        if vargs.range[1] is not None: endAddr = vargs.range[1]

    # Make sure the last address is divisible by 16
    remainder = endAddr % OAD_BLOCK_SIZE
    if remainder:
        print("Last address was 0x%0X. Expanded to 0x%0X to be divisible by OAD block size" % (endAddr, endAddr+(OAD_BLOCK_SIZE-remainder)) )
        endAddr += OAD_BLOCK_SIZE - remainder

    #if specified, the script will pad the image with the pad value
    fillHex = IntelHex()
    fillHex.puts(startAddr, struct.pack('B', vargs.fill) * (endAddr))
    mergedHex.merge(fillHex, 'ignore')
    mergedHex = mergedHex[startAddr:endAddr] # +1 since the last address is not inclusive
    mergedHex.padding = vargs.fill


    #if we are calculating metadata
    #Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these
    #All onchip OAD images need metdata placement
    if not(vargs.oadtype == 'offchip' and (vargs.imgtype == 'production' or vargs.imgtype == 'np')):
        # Place metadata, onchip production image expects header at 0x600
        if vargs.oadtype == 'onchip' and vargs.imgtype == 'production':
            residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN, INT_FL_OAD_IMG_A_META_BEGIN+15)))
        else:
            residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(startAddr, startAddr+15)))
        metaAddr = vargs.meta
Example #39
0
def arm9_cli_handler(client, argv):
    if(argv[1]=="info"):
        client.halt()
        print >>sys.stderr, client.ARMidentstr()
        print >>sys.stderr,"Debug Status:\t%s" % client.statusstr()
        print >>sys.stderr,"CPSR: (%s) %s\n"%(client.ARMget_regCPSRstr())
        client.resume()


    if(argv[1]=="dump"):
        f = sys.argv[2]
        start=0x00000000
        stop=0xFFFFFFFF
        if(len(sys.argv)>3):
            start=int(sys.argv[3],16)
        if(len(sys.argv)>4):
            stop=int(sys.argv[4],16)
        
        print "Dumping from %04x to %04x as %s." % (start,stop,f)
        #h = IntelHex16bit(None)
        # FIXME: get mcu state and return it to that state
        client.halt()

        try:
            h = IntelHex(None)
            i=start
            while i<=stop:
                #data=client.ARMreadMem(i, 48)
                data=client.ARMreadChunk(i, 48, verbose=0)
                print "Dumped %06x."%i
                for dword in data:
                    if i<=stop and dword != 0xdeadbeef:
                        h.puts( i, struct.pack("<I", dword) )
                    i+=4
            # FIXME: get mcu state and return it to that state
        except:
            print "Unknown error during read. Writing results to output file."
            print "Rename file with last address dumped %06x."%i
            pass

        client.resume()
        h.write_hex_file(f)

    '''
    if(sys.argv[1]=="erase"):
        print "Erasing main flash memory."
        client.ARMmasserase()

    if(sys.argv[1]=="eraseinfo"):
        print "Erasing info memory."
        client.ARMinfoerase()

        
    '''
    if(sys.argv[1]=="ivt"):
        client.halt()
        client.ARMprintChunk(0x0,0x20)
        client.resume()

    if(sys.argv[1]=="regs"):
        client.halt()
        for i in range(0,16):
            print "r%i=%04x" % (i,client.ARMget_register(i))
        client.resume()

    if(sys.argv[1]=="flash"):
        f=sys.argv[2]
        start=0
        stop=0x10000
        if(len(sys.argv)>3):
            start=int(sys.argv[3],16)
        if(len(sys.argv)>4):
            stop=int(sys.argv[4],16)
        
        client.halt()
        h = IntelHex16bit(f)
        
        #Should this be default?
        #Makes flashing multiple images inconvenient.
        #client.ARMmasserase()
        
        count=0; #Bytes in commit.
        first=0
        vals=[]
        last=0;  #Last address committed.
        for i in h._buf.keys():
            if((count>0x40 or last+2!=i) and count>0 and i&1==0):
                #print "%i, %x, %x" % (len(vals), last, i)
                client.ARMpokeflashblock(first,vals)
                count=0
                first=0
                last=0
                vals=[]
            if(i>=start and i<stop  and i&1==0):
                val=h[i>>1]
                if(count==0):
                    first=i
                last=i
                count+=2
                vals+=[val&0xff,(val&0xff00)>>8]
                if(i%0x100==0):
                    print "%04x" % i
        if count>0: #last commit, ivt
            client.ARMpokeflashblock(first,vals)
        client.resume()

    if(sys.argv[1]=="verify"):
        f=sys.argv[2]
        start=0
        stop=0xFFFF
        if(len(sys.argv)>3):
            start=int(sys.argv[3],16)
        if(len(sys.argv)>4):
            stop=int(sys.argv[4],16)
        
        client.halt()
        h = IntelHex16bit(f)
        for i in h._buf.keys():
            if(i>=start and i<stop and i&1==0):
                peek=client.peek(i)
                if(h[i>>1]!=peek):
                    print "ERROR at %04x, found %04x not %04x"%(i,peek,h[i>>1])
                if(i%0x100==0):
                    print "%04x" % i
        client.resume()


    if(sys.argv[1]=="peek"):
        start = 0x0000
        if(len(sys.argv)>2):
            start=int(sys.argv[2],16)

        stop = start+4
        if(len(sys.argv)>3):
            stop=int(sys.argv[3],16)

        print "Peeking from %04x to %04x." % (start,stop)
        client.halt()
        for dword in client.ARMreadChunk(start, (stop-start)/4, verbose=0):
            print "%.4x: %.8x" % (start, dword)
            start += 4
        client.resume()

    if(sys.argv[1]=="poke"):
        start=0x0000
        val=0x00
        if(len(sys.argv)>2):
            start=int(sys.argv[2],16)
        if(len(sys.argv)>3):
            val=int(sys.argv[3],16)
        
        print "Poking %06x to become %04x." % (start,val)
        client.halt()
        #???while client.ARMreadMem(start)[0]&(~val)>0:
        client.ARMwriteChunk(start, [val])
        print "Poked to %.8x" % client.ARMreadMem(start)[0]
        client.resume()


    if(sys.argv[1]=="reset"):
        #Set PC to RESET vector's value.
        
        #client.ARMsetPC(0x00000000)
        #client.ARMset_regCPSR(0)
        #client.ARMreleasecpu()
        client.ARMresettarget(1000)
Example #40
0
import sys
from intelhex import IntelHex

WRITEBACK = True
if len(sys.argv) > 1:
    WRITEBACK = False
    ser = int(sys.argv[1])
else:
    try:
        ser = int(file(".serial", "rb").read(), 16) + 1
    except IOError:
        ser = 0

print >>sys.stderr, ("[--- new serial number: %.4x ---]" % ser)

if WRITEBACK:
    file(".serial", "wb").write("%.13x" % ser)

sertxt = ""
sertmp = "%.13x" % ser
for c in sertmp:
    sertxt += "%s\x00" % c

ihc = IntelHex("CCBootloader/CCBootloader-rfcat-chronosdongle.hex")
ihd = IntelHex("CCBootloader/CCBootloader-rfcat-donsdongle.hex")
ihc.puts(0x13E0, "@las\x1c\x03" + sertxt)
ihd.puts(0x13E0, "@las\x1c\x03" + sertxt)
ihc.write_hex_file("CCBootloader/CCBootloader-rfcat-chronosdongle-serial.hex")
ihd.write_hex_file("CCBootloader/CCBootloader-rfcat-donsdongle-serial.hex")
Example #41
0
class Flash():

  def __init__(self, link, flash_type, sbp_version):
    """
    Object representing either of the two flashes (STM/M25) on the Piksi,
    including methods to erase, program, and read.

    Parameters
    ----------
    link : sbp.client.handler.Handler
      Handler to send messages to Piksi over and register callbacks with.
    flash_type : string
      Which Piksi flash to interact with ("M25" or "STM").
    sbp_version : (int, int)
      SBP protocol version, used to select messages to send.

    Returns
    -------
    out : Flash instance
    """
    self._n_queued_ops = 0
    self.nqo_lock = Lock()
    self.stopped = False
    self.status = ''
    self.link = link
    self.flash_type = flash_type
    self.sbp_version = sbp_version
    # IntelHex object to store read flash data in that was read from device.
    self._read_callback_ihx = IntelHex()
    self.link.add_callback(self._done_callback, SBP_MSG_FLASH_DONE)
    self.link.add_callback(self._read_callback, SBP_MSG_FLASH_READ_DEVICE)
    self.ihx_elapsed_ops = 0 # N operations finished in self.write_ihx
    if self.flash_type == "STM":
      self.flash_type_byte = 0
      self.addr_sector_map = stm_addr_sector_map
      # Add STM-specific functions.
      self.__dict__['lock_sector'] = \
          new.instancemethod(_stm_lock_sector, self, Flash)
      self.__dict__['unlock_sector'] = \
          new.instancemethod(_stm_unlock_sector, self, Flash)
      self.n_sectors = STM_N_SECTORS
      self.restricted_sectors = STM_RESTRICTED_SECTORS
    elif self.flash_type == "M25":
      self.flash_type_byte = 1
      self.addr_sector_map = m25_addr_sector_map
      # Add M25-specific functions.
      self.__dict__['write_status'] = \
          new.instancemethod(_m25_write_status, self, Flash)
      self.n_sectors = M25_N_SECTORS
      self.restricted_sectors = M25_RESTRICTED_SECTORS
    else:
      raise ValueError("flash_type must be \"STM\" or \"M25\", got \"%s\"" \
                       % flash_type)

  def __enter__(self):
    return self

  def __exit__(self, type, value, traceback):
    """ Calls self.stop() before instance is deleted. """
    if not self.stopped:
      self.stop()

  def ihx_n_ops(self, ihx, erase=True):
    """
    Find the number of sent SBP messages (erase, program, read) self.write_ihx
    will require to write a particular intelhex.IntelHex for this instance's
    flash type.

    Parameters
    ----------
    ihx : intelhex.Intelhex
      intelhex.IntelHex to be written.
    erase : bool
      Include number of erase operations required in total.

    Returns
    -------
    out : int
      Number of sent SBP messages (erase, program, read) self.write_ihx will
      require to write ihx.
    """
    return ihx_n_ops(ihx, self.addr_sector_map, erase)

  def inc_n_queued_ops(self):
    """
    Increment the count of queued flash operation SBP messages in the STM's
    flash in a thread safe way.
    """
    self.nqo_lock.acquire()
    self._n_queued_ops += 1
    self.nqo_lock.release()

  def dec_n_queued_ops(self):
    """
    Decrement the count of queued flash operation SBP messages in the STM's
    flash in a thread safe way.
    """
    self.nqo_lock.acquire()
    self._n_queued_ops -= 1
    self.nqo_lock.release()

  def get_n_queued_ops(self):
    """
    Get the current count of queued flash operation SBP messages.

    Returns
    -------
    out : int
      Get the current count of queued flash operation SBP messages.
    """
    return self._n_queued_ops

  def stop(self):
    """ Remove instance callbacks from sbp.client.handler.Handler. """
    self.stopped = True
    self.link.remove_callback(self._done_callback, SBP_MSG_FLASH_DONE)
    self.link.remove_callback(self._read_callback, SBP_MSG_FLASH_READ_DEVICE)

  def __str__(self):
    """ Return flashing status. """
    return self.status

  def erase_sector(self, sector, warn=True):
    """
    Erase a sector of the flash.

    Parameters
    ----------
    sector : int
      Sector to be erased.
    warn : bool
      Warn if sector is restricted and should most likely not be erased.
    """
    if warn and sector in self.restricted_sectors:
      text = 'Attempting to erase %s flash restricted sector %d' % \
             (self.flash_type, sector)
      raise Warning(text)
    msg_buf = struct.pack("BB", self.flash_type_byte, sector)
    self.inc_n_queued_ops()
    self.link.send(SBP_MSG_FLASH_ERASE, msg_buf)
    while self.get_n_queued_ops() > 0:
      time.sleep(0.001)

  def program(self, address, data):
    """
    Program a set of addresses of the flash.

    Parameters
    ----------
    address : int
      Starting address of set of addresses to program with data.
    data : string
      String of bytes to program to flash starting at address.
    """
    msg_buf = struct.pack("B", self.flash_type_byte)
    msg_buf += struct.pack("<I", address)
    msg_buf += struct.pack("B", len(data))
    self.inc_n_queued_ops()
    # < 0.45 of SBP protocol, reuse single flash message.
    if self.sbp_version < (0, 45):
      self.link.send(SBP_MSG_FLASH_DONE, msg_buf + data)
    else:
      self.link.send(SBP_MSG_FLASH_PROGRAM, msg_buf + data)

  def read(self, address, length):
    """
    Read a set of addresses of the flash.

    Parameters
    ----------
    address : int
      Starting address of length addresses to read.
    length : int
      Number of addresses to read.
    """
    msg_buf = struct.pack("B", self.flash_type_byte)
    msg_buf += struct.pack("<I", address)
    msg_buf += struct.pack("B", length)
    self.inc_n_queued_ops()
    # < 0.45 of SBP protocol, reuse single read message.
    if self.sbp_version < (0, 45):
      self.link.send(SBP_MSG_FLASH_READ_DEVICE, msg_buf)
    else:
      self.link.send(SBP_MSG_FLASH_READ_HOST, msg_buf)

  def _done_callback(self, sbp_msg):
    """
    Handles flash done message sent from device.

    Parameters
    ----------
    data : string
      Binary data sent from device.
    """
    ret = ord(sbp_msg.payload)

    if (ret != 0):
      print "Flash operation returned error (%d)" % ret

    self.dec_n_queued_ops()
    assert self.get_n_queued_ops() >= 0, \
      "Number of queued flash operations is negative"

  def _read_callback(self, sbp_msg):
    """
    Handles flash read message sent from device.

    Parameters
    ----------
    data : string
      Binary data sent from device.
    """
    # 4 bytes addr, 1 byte length, length bytes data
    address = struct.unpack('<I', sbp_msg.payload[0:4])[0]
    length = struct.unpack('B', sbp_msg.payload[4])[0]

    self._read_callback_ihx.puts(address, sbp_msg.payload[5:])

    self.dec_n_queued_ops()
    assert self.get_n_queued_ops() >= 0, \
      "Number of queued flash operations is negative"

  def write_ihx(self, ihx, stream=None, mod_print=0, elapsed_ops_cb=None, erase=True):
    """
    Perform all operations to write an intelhex.IntelHex to the flash
    and verify.

    Parameters
    ----------
    ihx : intelhex.IntelHex
      intelhex.IntelHex to write to the flash.
    stream : stream
      Object implementing write and flush methods to write status updates to.
    mod_print : int
      How many loops to run through before writing to stream.
    elapsed_ops_cb : function
      Callback to execute every mod_print loops.
    erase : bool
      Erase sectors before writing.
    """
    self.ihx_elapsed_ops = 0
    self.print_count = 0

    start_time = time.time()

    ihx_addrs = ihx_ranges(ihx)

    # Erase sectors
    if erase:
      for sector in sectors_used(ihx_addrs, self.addr_sector_map):
        self.status = self.flash_type + " Flash: Erasing sector %d" % sector
        if stream:
          stream.write('\r' + self.status)
          stream.flush()
        self.erase_sector(sector)
        self.ihx_elapsed_ops += 1
        if elapsed_ops_cb != None:
          elapsed_ops_cb(self.ihx_elapsed_ops)
      if stream:
        stream.write('\n')

    # Write data to flash and read back to later validate. STM's lowest address
    # is used by bootloader to check that the application is valid, so program
    # from high to low to ensure this address is programmed last.
    for start, end in reversed(ihx_addrs):
      for addr in reversed(range(start, end, ADDRS_PER_OP)):
        self.status = self.flash_type + " Flash: Programming address" + \
                                        " 0x%08X" % addr
        if mod_print == 0 or mod_print != 0 and self.print_count % mod_print == 0:
          if stream:
            stream.write('\r' + self.status)
            stream.flush()
          self.print_count = 1
          if elapsed_ops_cb != None:
            elapsed_ops_cb(self.ihx_elapsed_ops)
        else:
          self.print_count += 1

        binary = ihx.tobinstr(start=addr, size=ADDRS_PER_OP)

        # Program ADDRS_PER_OP addresses
        while self.get_n_queued_ops() >= MAX_QUEUED_OPS:
          time.sleep(0.001)
        self.program(addr, binary)
        self.ihx_elapsed_ops += 1

        # Read ADDRS_PER_OP addresses
        while self.get_n_queued_ops() >= MAX_QUEUED_OPS:
          time.sleep(0.001)
        self.read(addr, ADDRS_PER_OP)
        self.ihx_elapsed_ops += 1

    # Verify that data written to flash matches data read from flash.
    while self.get_n_queued_ops() > 0:
      time.sleep(0.001)
    for start, end in reversed(ihx_addrs):
      if self._read_callback_ihx.gets(start, end-start+1) != \
          ihx.gets(start, end-start+1):
        for i in range(start, end):
          r = self._read_callback_ihx.gets(i,1)
          p = ihx.gets(i,1)
          if r != p:
            raise Exception('Data read from flash != Data programmed to flash'
              ('Addr: %x, Programmed: %x, Read: %x' % (i,r,p)).upper())

    self.status = self.flash_type + " Flash: Successfully programmed and " + \
                                    "verified, total time = %d seconds" % \
                                    int(time.time()-start_time)
    if stream:
      stream.write('\n\r' + self.status + '\n')
    memory_map = board.target.getMemoryMap()
    ram_regions = [region for region in memory_map if region.type == 'ram']
    ram_region = ram_regions[0]
    rom_region = memory_map.getBootMemory()
    target_type = board.getTargetType()

    print "[3/6] Board recognized as %s. Downloading ROM..." % target_type

    addr = rom_region.start
    size = rom_region.length
    data = board.target.readBlockMemoryUnaligned8(addr, size)
    data = bytearray(data)
    with open("crashdump/rom.bin", 'wb') as f:
        f.write(data)
    ih = IntelHex()
    ih.puts(addr, data)
    ih.tofile("crashdump/rom.hex", format='hex')

    print "[4/6] Dumped ROM. Downloading RAM..."

    addr = ram_region.start
    size = ram_region.length
    data = board.target.readBlockMemoryUnaligned8(addr, size)
    data = bytearray(data)
    with open("crashdump/ram.bin", 'wb') as f:
        f.write(data)
    ih = IntelHex()
    ih.puts(addr, data)
    ih.tofile("crashdump/ram.hex", format='hex')

    print "[5/6] Dumped RAM. Creating uVision project..."
Example #43
0
class Flash():
    def __init__(self, link, flash_type, sbp_version, max_queued_ops=1):
        """
    Object representing either of the two flashes (STM/M25) on the Piksi,
    including methods to erase, program, and read.

    Parameters
    ----------
    link : sbp.client.handler.Handler
      Handler to send messages to Piksi over and register callbacks with.
    flash_type : string
      Which Piksi flash to interact with ("M25" or "STM").
    sbp_version : (int, int)
      SBP protocol version, used to select messages to send.
    max_queued_ops : int
      Maximum number of Flash read/program operations to queue in device flash.
      (0.5 * ADDRS_PER_OP + SBP packet overhead) * max_queued_ops is how much
      of the device UART RX buffer will be filled by the program/read callback
      messages. A higher value will significantly speed up flashing, but can
      result in RX buffer overflows in other UARTs if the device is receiving
      data on other UARTs.

    Returns
    -------
    out : Flash instance
    """
        self._n_queued_ops = 0
        self.max_queued_ops = max_queued_ops
        self.nqo_lock = Lock()
        self.stopped = False
        self.status = ''
        self.link = link
        self.flash_type = flash_type
        self.sbp_version = sbp_version
        # IntelHex object to store read flash data in that was read from device.
        self._read_callback_ihx = IntelHex()
        self.link.add_callback(self._done_callback, SBP_MSG_FLASH_DONE)
        self.link.add_callback(self._read_callback, SBP_MSG_FLASH_READ_RESP)
        self.ihx_elapsed_ops = 0  # N operations finished in self.write_ihx
        if self.flash_type == "STM":
            self.flash_type_byte = 0
            self.addr_sector_map = stm_addr_sector_map
            # Add STM-specific functions.
            self.__dict__['lock_sector'] = \
                new.instancemethod(_stm_lock_sector, self, Flash)
            self.__dict__['unlock_sector'] = \
                new.instancemethod(_stm_unlock_sector, self, Flash)
            self.n_sectors = STM_N_SECTORS
            self.restricted_sectors = STM_RESTRICTED_SECTORS
        elif self.flash_type == "M25":
            self.flash_type_byte = 1
            self.addr_sector_map = m25_addr_sector_map
            # Add M25-specific functions.
            self.__dict__['write_status'] = \
                new.instancemethod(_m25_write_status, self, Flash)
            self.n_sectors = M25_N_SECTORS
            self.restricted_sectors = M25_RESTRICTED_SECTORS
        else:
            raise ValueError("flash_type must be \"STM\" or \"M25\", got \"%s\"" \
                             % flash_type)

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        """ Calls self.stop() before instance is deleted. """
        if not self.stopped:
            self.stop()

    def ihx_n_ops(self, ihx, erase=True):
        """
    Find the number of sent SBP messages (erase, program, read) self.write_ihx
    will require to write a particular intelhex.IntelHex for this instance's
    flash type.

    Parameters
    ----------
    ihx : intelhex.Intelhex
      intelhex.IntelHex to be written.
    erase : bool
      Include number of erase operations required in total.

    Returns
    -------
    out : int
      Number of sent SBP messages (erase, program, read) self.write_ihx will
      require to write ihx.
    """
        return ihx_n_ops(ihx, self.addr_sector_map, erase)

    def inc_n_queued_ops(self):
        """
    Increment the count of queued flash operation SBP messages in the STM's
    flash in a thread safe way.
    """
        self.nqo_lock.acquire()
        self._n_queued_ops += 1
        self.nqo_lock.release()

    def dec_n_queued_ops(self):
        """
    Decrement the count of queued flash operation SBP messages in the STM's
    flash in a thread safe way.
    """
        self.nqo_lock.acquire()
        self._n_queued_ops -= 1
        self.nqo_lock.release()

    def get_n_queued_ops(self):
        """
    Get the current count of queued flash operation SBP messages.

    Returns
    -------
    out : int
      Get the current count of queued flash operation SBP messages.
    """
        return self._n_queued_ops

    def stop(self):
        """ Remove instance callbacks from sbp.client.handler.Handler. """
        self.stopped = True
        self.link.remove_callback(self._done_callback, SBP_MSG_FLASH_DONE)
        self.link.remove_callback(self._read_callback, SBP_MSG_FLASH_READ_RESP)

    def __str__(self):
        """ Return flashing status. """
        return self.status

    def erase_sector(self, sector, warn=True):
        """
    Erase a sector of the flash.

    Parameters
    ----------
    sector : int
      Sector to be erased.
    warn : bool
      Warn if sector is restricted and should most likely not be erased.
    """
        if warn and sector in self.restricted_sectors:
            text = 'Attempting to erase %s flash restricted sector %d' % \
                   (self.flash_type, sector)
            raise Warning(text)
        msg_buf = struct.pack("BB", self.flash_type_byte, sector)
        self.inc_n_queued_ops()
        self.link(MsgFlashErase(target=self.flash_type_byte,
                                sector_num=sector))
        while self.get_n_queued_ops() > 0:
            time.sleep(0.001)

    def program(self, address, data):
        """
    Program a set of addresses of the flash.

    Parameters
    ----------
    address : int
      Starting address of set of addresses to program with data.
    data : string
      String of bytes to program to flash starting at address.
    """
        msg_buf = struct.pack("B", self.flash_type_byte)
        msg_buf += struct.pack("<I", address)
        msg_buf += struct.pack("B", len(data))
        self.inc_n_queued_ops()
        # < 0.45 of SBP protocol, reuse single flash message.
        if self.sbp_version < (0, 45):
            self.link(SBP(SBP_MSG_FLASH_DONE, payload=msg_buf + data))
        else:
            self.link(
                MsgFlashProgram(target=self.flash_type_byte,
                                addr_start=address,
                                addr_len=len(data),
                                data=data))

    def read(self, address, length, block=False):
        """
    Read a set of addresses of the flash.

    Parameters
    ----------
    address : int
      Starting address of length addresses to read.
    length : int
      Number of addresses to read.
    block : bool
      Block until addresses are read and return them.

    Returns
    =======
    out : str
      String of bytes (big endian) read from address.
    """
        msg_buf = struct.pack("B", self.flash_type_byte)
        msg_buf += struct.pack("<I", address)
        msg_buf += struct.pack("B", length)
        self.inc_n_queued_ops()
        # < 0.45 of SBP protocol, reuse single read message.
        if self.sbp_version < (0, 45):
            self.link(SBP(SBP_MSG_FLASH_READ_RESP, payload=msg_buf))
        else:
            self.link(
                MsgFlashReadReq(target=self.flash_type_byte,
                                addr_start=address,
                                addr_len=length))
        if block:
            while self.get_n_queued_ops() > 0:
                time.sleep(0.001)
            return self._read_callback_ihx.gets(address, length)

    def _done_callback(self, sbp_msg, **metadata):
        """
    Handles flash done message sent from device.

    Parameters
    ----------
    data : string
      Binary data sent from device.
    """
        ret = ord(sbp_msg.payload)

        if (ret != 0):
            print(("Flash operation returned error (%d)" % ret))

        self.dec_n_queued_ops()
        assert self.get_n_queued_ops() >= 0, \
          "Number of queued flash operations is negative"

    def _read_callback(self, sbp_msg, **metadata):
        """
    Handles flash read message sent from device.

    Parameters
    ----------
    data : string
      Binary data sent from device.
    """
        # 4 bytes addr, 1 byte length, length bytes data
        address = struct.unpack('<I', sbp_msg.payload[0:4])[0]
        length = struct.unpack('B', sbp_msg.payload[4])[0]

        self._read_callback_ihx.puts(address, sbp_msg.payload[5:])

        self.dec_n_queued_ops()
        assert self.get_n_queued_ops() >= 0, \
          "Number of queued flash operations is negative"

    def write_ihx(self,
                  ihx,
                  stream=None,
                  mod_print=0,
                  elapsed_ops_cb=None,
                  erase=True):
        """
    Perform all operations to write an intelhex.IntelHex to the flash
    and verify.

    Parameters
    ----------
    ihx : intelhex.IntelHex
      intelhex.IntelHex to write to the flash.
    stream : stream
      Object implementing write and flush methods to write status updates to.
    mod_print : int
      How many loops to run through before writing to stream.
    elapsed_ops_cb : function
      Callback to execute every mod_print loops.
    erase : bool
      Erase sectors before writing.
    """
        self.ihx_elapsed_ops = 0
        self.print_count = 0

        start_time = time.time()

        ihx_addrs = ihx_ranges(ihx)

        # Erase sectors
        if erase:
            for sector in sectors_used(ihx_addrs, self.addr_sector_map):
                self.status = self.flash_type + " Flash: Erasing sector %d" % sector
                if stream:
                    stream.write('\r' + self.status)
                    stream.flush()
                self.erase_sector(sector)
                self.ihx_elapsed_ops += 1
                if elapsed_ops_cb != None:
                    elapsed_ops_cb(self.ihx_elapsed_ops)
            if stream:
                stream.write('\n')

        # Write data to flash and read back to later validate. STM's lowest address
        # is used by bootloader to check that the application is valid, so program
        # from high to low to ensure this address is programmed last.
        for start, end in reversed(ihx_addrs):
            for addr in reversed(list(range(start, end, ADDRS_PER_OP))):
                self.status = self.flash_type + " Flash: Programming address" + \
                                                " 0x%08X" % addr
                if mod_print == 0 or mod_print != 0 and self.print_count % mod_print == 0:
                    if stream:
                        stream.write('\r' + self.status)
                        stream.flush()
                    self.print_count = 1
                    if elapsed_ops_cb != None:
                        elapsed_ops_cb(self.ihx_elapsed_ops)
                else:
                    self.print_count += 1

                binary = ihx.tobinstr(start=addr, size=ADDRS_PER_OP)

                # Program ADDRS_PER_OP addresses
                while self.get_n_queued_ops() >= self.max_queued_ops:
                    time.sleep(0.001)
                self.program(addr, binary)
                self.ihx_elapsed_ops += 1

                # Read ADDRS_PER_OP addresses
                while self.get_n_queued_ops() >= self.max_queued_ops:
                    time.sleep(0.001)
                self.read(addr, ADDRS_PER_OP)
                self.ihx_elapsed_ops += 1

        # Verify that data written to flash matches data read from flash.
        while self.get_n_queued_ops() > 0:
            time.sleep(0.001)
        for start, end in reversed(ihx_addrs):
            if self._read_callback_ihx.gets(start, end-start+1) != \
                ihx.gets(start, end-start+1):
                for i in range(start, end):
                    r = self._read_callback_ihx.gets(i, 1)
                    p = ihx.gets(i, 1)
                    if r != p:
                        raise Exception(
                            'Data read from flash != Data programmed to flash' (
                                'Addr: %x, Programmed: %x, Read: %x' %
                                (i, r, p)).upper())

        self.status = self.flash_type + " Flash: Successfully programmed and " + \
                                        "verified, total time = %d seconds" % \
                                        int(time.time()-start_time)
        if stream:
            stream.write('\n\r' + self.status + '\n')
    iob = i2c0.read_byte_data(0x22, 0x14)
    i2c0.write_byte_data(0x22, 0x14, iob&~0x10)

# if ver == "0.36":
#    print("mux = 0x%02x" % i2c2.read_byte(0x30))

print(icsp_cmd(ser, b'L'))                      # take MCLR low (icsp)
print(icsp_cmd(ser, b'#', 9))                   # reset checksum
print(icsp_enter_lvp(ser))                      # enter LVP

print("dumping program memory ...")

data = icsp_read_data(ser, 0x4000)
for a in range(0x0000, 0x4000):
    val = data[a]
    ih.puts(a*2, struct.pack("<h", val))

icsp_cmd(ser, b'[X0=]', 0)                      # switch to config mem

print("dumping config memory ...")

data = icsp_read_data(ser, 0x11)
for a in range(0x8000, 0x8011):
    val = data[a - 0x8000]
    ih.puts(a*2, struct.pack("<h", val))

print(icsp_cmd(ser, b'#', 9))                   # retrieve checksum
print(icsp_cmd(ser, b'Z'))                      # tristate MCLK (icsp)

if ver == "0.36":
    print("mux = 0x%02x" % i2c2.read_byte(0x30))
Example #45
0
def get_hex(f, b, d, cs):

	#
	# All the following to be able to be set with getopt.
	# These defaults will do for testing purposes.
	#
	outfile=sys.stdout


	# manufacturing data
	#
	manuf=False
	sn=""
	ts=""
	campaign=""
	eyecatcher='The Public Radio'

	# tuning info defaults
	#
	freq=0.0
	band=0			# US 87.5 - 108
	demphasis=0		# US 75uS
	spacing=0		# US 200KHz
	volume=0x0f		# max (0 dBFS)

	#
	# Create a manufacturing record.
	#
	def manuf_record(sn, ts, campaign):
		ww = int(date.today().strftime('%V'))
		yy = int(date.today().strftime('%g'))
		return pack('17sBB2s13s17s', sn[:16], ww, yy, ts[:2], campaign[:12], eyecatcher)


	#
	# calculate channel # based on freq, band & channel spacing.
	# Note that we force the floating point arithmetic to round
	# to a reasonable number of digits in order to avoid daft problems.

	freq = float(f)
	band = int(b)
	demphasis =	int(d)
	spacing= int(cs)

	base = {0: 87.5, 1: 76, 2: 76}
	step = {0: 5, 1: 10, 2: 20}

	try:
		chan = round((freq - base[band]) * step[spacing], 4)
	except:
		chan = round((freq - base[0]) * step[0], 4)

	if modf(chan)[0] != 0.0:
		chan = 0


	chan = int(chan)

	# First create the data without the checksum, note that we specify
	# little-endianness for multi-byte values.

	t = pack('<BBBHB8x', band, demphasis, spacing, chan, volume)

	# Calculate and append a crc-16 checksum
	crc16 = crcmod.predefined.Crc('crc-16')
	crc16.update(t)

	t = t + pack('<H', crc16.crcValue)

	#
	# Simply create a hex file with the concatenation of two tuning structures (t)
	# and optionally one manufacturing structure, then write the result.
	#
	eeprom = t + t

	if manuf:
		eeprom = eeprom + manuf_record(sn, ts, campaign)

	outfile = tempfile.NamedTemporaryFile(prefix='eeprom.', suffix='.hex', delete=False)
	hexfile = IntelHex()
	hexfile.puts(0, eeprom)
	hexfile.write_hex_file(outfile)
	outfile.close()
	return outfile
Example #46
0
# Sanity checks, very important
if ih.maxaddr() < 0x1004 or ih.maxaddr() > 32767:
    print "Insane hexfile: min=0x%x max=0x%x" % (ih.minaddr(), ih.maxaddr())
    sys.exit(2)
print "Length: %d / 28672" % (ih.maxaddr() - 4096 + 1)
print "Free: %d" % (28672 - (ih.maxaddr() - 4096 + 1))

# Hack to force tobinstr() to write data from addres 0. IntelHex will 
# only write data from the first location with initialized data, skipping
# over any uninitialized data beforehand. This initializes address 0,
# forcing IntelHex to do what I want.
ih[0]=ih[0]

sumdata = (ih.tobinstr())[0x1004:]
sumdata += '\xff' * (0x6ffc - len(sumdata))
cksum = binascii.crc32(sumdata) & 0xffffffff
print "Checksum: 0x%08x" % cksum
ih.puts(0x1000, struct.pack('<L', cksum))

# Rather than using IntelHex.tobinfile(), i'm writing to a file this way
# to ensure that the file ends up at exactly 32768 bytes.
binfw = ih.tobinstr()
binfw += '\xff' * (0x8000 - len(binfw))
out.write(binfw)
out.close()

# Testing only.
a=IntelHex()
a.loadbin(sys.argv[2])
a.write_hex_file(sys.argv[2] + '.hex')
Example #47
0
if not os.path.exists(sys.argv[2]):
	sys.exit("Unable open build %s" % sys.argv[2])
build_filename = sys.argv[1]
prog_filename = sys.argv[2]

# open the build and prog
# note open build via StringIO so we can add to it
build = IntelHex(StringIO.StringIO(open(build_filename, "r").read()))
prog = IntelHex(prog_filename)

# merge program into build
prog_header_addr = prog.minaddr()
prog.start_addr = build.start_addr # we need this to make the merge work smoothly
build.merge(prog)

# add pointer to program header to the bootstrap
header_tbl_addr = 0x08000204
header_tbl_len = 2 #@todo get this from 0x0800200 as uint32_t
header_tbl_format = "<LL"
header_tbl = list(struct.unpack(header_tbl_format, build.gets(header_tbl_addr, header_tbl_len * 4)))
k = 0
while header_tbl[k] != 0xffffffff:
	if k > header_tbl_len:
		sys.exit("bootstrap program table full [you have too many programs]!");
	k += 1
header_tbl[k] = prog_header_addr
build.puts(header_tbl_addr, struct.pack(header_tbl_format, *header_tbl))

# done
build.write_hex_file(build_filename)
Example #48
0
def merge_region_list(region_list,
                      destination,
                      notify,
                      config,
                      padding=b'\xFF'):
    """Merge the region_list into a single image

    Positional Arguments:
    region_list - list of regions, which should contain filenames
    destination - file name to write all regions to
    padding - bytes to fill gaps with
    """
    merged = IntelHex()
    _, format = splitext(destination)
    notify.info("Merging Regions")
    # Merged file list: Keep track of binary/hex files that we have already
    # merged. e.g In some cases, bootloader may be split into multiple parts,
    # but all internally referring to the same bootloader file.
    merged_list = []

    for region in region_list:
        if region.active and not region.filename:
            raise ToolException(
                "Active region has no contents: No file found.")
        if isinstance(region.filename, list):
            header_basename, _ = splitext(destination)
            header_filename = header_basename + "_header.hex"
            _fill_header(region_list, region).tofile(header_filename,
                                                     format='hex')
            region = region._replace(filename=header_filename)
        if region.filename and (region.filename not in merged_list):
            notify.info("  Filling region %s with %s" %
                        (region.name, region.filename))
            part = intelhex_offset(region.filename, offset=region.start)
            part.start_addr = None
            # Normally, we assume that part.maxddr() can be beyond
            # end of rom. If the size is restricted with config, don't
            # allow this.
            if config.target.restrict_size is not None:
                part_size = (part.maxaddr() - part.minaddr()) + 1
                if part_size > region.size:
                    raise ToolException("Contents of region %s does not fit" %
                                        region.name)
            merged_list.append(region.filename)
            merged.merge(part)
        elif region.filename in merged_list:
            notify.info("  Skipping %s as it is merged previously" %
                        (region.name))

    # Hex file can have gaps, so no padding needed. While other formats may
    # need padding. Iterate through segments and pad the gaps.
    if format != ".hex":
        # begin patching from the end of the first segment
        _, begin = merged.segments()[0]
        for start, stop in merged.segments()[1:]:
            pad_size = start - begin
            merged.puts(begin, padding * pad_size)
            begin = stop + 1

    if not exists(dirname(destination)):
        makedirs(dirname(destination))
    notify.info("Space used after regions merged: 0x%x" %
                (merged.maxaddr() - merged.minaddr() + 1))
    merged.tofile(destination, format=format.strip("."))
Example #49
0
      name = self._name_of_address_thunk(address)
    return name, address

  def _adjust(self, op, args, addr):
    return (ibv(args[0] - addr - 1),)


if __name__ == '__main__':
  aa = AVRAssembly()
  aa.assemble_file('asm.py')

##  print ; print ; print
##  pprint.pprint(dict(aa.context))
##  print ; print ; print
##  pprint.pprint(dict(aa.data))
##  print ; print ; print
##  pprint.pprint(aa.pass2())
  data = aa.pass2()
  print ; print ; print
  pprint.pprint(data)
  from intelhex import IntelHex
  ih = IntelHex()
  for addr, val in data.iteritems():
    addr = int(addr, 16)
    if isinstance(val, str):
      ih.puts(addr, val)
    else:
      print 'non-str', addr, repr(val)
##  ih.dump(tofile=open('pavr.hex', 'w'))
  ih.dump()
Example #50
0
def arm9_cli_handler(client, argv):
    if (argv[1] == "info"):
        client.halt()
        print >> sys.stderr, client.ARMidentstr()
        print >> sys.stderr, "Debug Status:\t%s" % client.statusstr()
        print >> sys.stderr, "CPSR: (%s) %s\n" % (client.ARMget_regCPSRstr())
        client.resume()

    if (argv[1] == "dump"):
        f = sys.argv[2]
        start = 0x00000000
        stop = 0xFFFFFFFF
        if (len(sys.argv) > 3):
            start = int(sys.argv[3], 16)
        if (len(sys.argv) > 4):
            stop = int(sys.argv[4], 16)

        print "Dumping from %04x to %04x as %s." % (start, stop, f)
        #h = IntelHex16bit(None)
        # FIXME: get mcu state and return it to that state
        client.halt()

        try:
            h = IntelHex(None)
            i = start
            while i <= stop:
                #data=client.ARMreadMem(i, 48)
                data = client.ARMreadChunk(i, 48, verbose=0)
                print "Dumped %06x." % i
                for dword in data:
                    if i <= stop and dword != 0xdeadbeef:
                        h.puts(i, struct.pack("<I", dword))
                    i += 4
            # FIXME: get mcu state and return it to that state
        except:
            print "Unknown error during read. Writing results to output file."
            print "Rename file with last address dumped %06x." % i
            pass

        client.resume()
        h.write_hex_file(f)
    '''
    if(sys.argv[1]=="erase"):
        print "Erasing main flash memory."
        client.ARMmasserase()

    if(sys.argv[1]=="eraseinfo"):
        print "Erasing info memory."
        client.ARMinfoerase()

        
    '''
    if (sys.argv[1] == "ivt"):
        client.halt()
        client.ARMprintChunk(0x0, 0x20)
        client.resume()

    if (sys.argv[1] == "regs"):
        client.halt()
        for i in range(0, 16):
            print "r%i=%04x" % (i, client.ARMget_register(i))
        client.resume()

    if (sys.argv[1] == "flash"):
        f = sys.argv[2]
        start = 0
        stop = 0x10000
        if (len(sys.argv) > 3):
            start = int(sys.argv[3], 16)
        if (len(sys.argv) > 4):
            stop = int(sys.argv[4], 16)

        client.halt()
        h = IntelHex16bit(f)

        #Should this be default?
        #Makes flashing multiple images inconvenient.
        #client.ARMmasserase()

        count = 0
        #Bytes in commit.
        first = 0
        vals = []
        last = 0
        #Last address committed.
        for i in h._buf.keys():
            if ((count > 0x40 or last + 2 != i) and count > 0 and i & 1 == 0):
                #print "%i, %x, %x" % (len(vals), last, i)
                client.ARMpokeflashblock(first, vals)
                count = 0
                first = 0
                last = 0
                vals = []
            if (i >= start and i < stop and i & 1 == 0):
                val = h[i >> 1]
                if (count == 0):
                    first = i
                last = i
                count += 2
                vals += [val & 0xff, (val & 0xff00) >> 8]
                if (i % 0x100 == 0):
                    print "%04x" % i
        if count > 0:  #last commit, ivt
            client.ARMpokeflashblock(first, vals)
        client.resume()

    if (sys.argv[1] == "verify"):
        f = sys.argv[2]
        start = 0
        stop = 0xFFFF
        if (len(sys.argv) > 3):
            start = int(sys.argv[3], 16)
        if (len(sys.argv) > 4):
            stop = int(sys.argv[4], 16)

        client.halt()
        h = IntelHex16bit(f)
        for i in h._buf.keys():
            if (i >= start and i < stop and i & 1 == 0):
                peek = client.peek(i)
                if (h[i >> 1] != peek):
                    print "ERROR at %04x, found %04x not %04x" % (i, peek,
                                                                  h[i >> 1])
                if (i % 0x100 == 0):
                    print "%04x" % i
        client.resume()

    if (sys.argv[1] == "peek"):
        start = 0x0000
        if (len(sys.argv) > 2):
            start = int(sys.argv[2], 16)

        stop = start + 4
        if (len(sys.argv) > 3):
            stop = int(sys.argv[3], 16)

        print "Peeking from %04x to %04x." % (start, stop)
        client.halt()
        for dword in client.ARMreadChunk(start, (stop - start) / 4, verbose=0):
            print "%.4x: %.8x" % (start, dword)
            start += 4
        client.resume()

    if (sys.argv[1] == "poke"):
        start = 0x0000
        val = 0x00
        if (len(sys.argv) > 2):
            start = int(sys.argv[2], 16)
        if (len(sys.argv) > 3):
            val = int(sys.argv[3], 16)

        print "Poking %06x to become %04x." % (start, val)
        client.halt()
        #???while client.ARMreadMem(start)[0]&(~val)>0:
        client.ARMwriteChunk(start, [val])
        print "Poked to %.8x" % client.ARMreadMem(start)[0]
        client.resume()

    if (sys.argv[1] == "reset"):
        #Set PC to RESET vector's value.

        #client.ARMsetPC(0x00000000)
        #client.ARMset_regCPSR(0)
        #client.ARMreleasecpu()
        client.ARMresettarget(1000)
Example #51
0
 def getihex(self):
     ihex = IntelHex()
     ihex.puts(self.fw_info.tsb_start, self.tobinstr())
     return ihex