Example #1
0
def main():
    parser = argparse.ArgumentParser(description='Image CRC tool')
    parser.add_argument("input", type=str, help="Hex file to read from.")
    parser.add_argument("output", type=str,
                        help="Output base file name to write CRC32.")

    args = parser.parse_args()
    input_file = args.input
    output_file_hex = args.output + ".hex"
    output_file_binary = args.output + ".bin"
    output_file_txt = args.output + ".txt"
    output_file_legacy = args.output + "_legacy_0x8000.bin"
    output_file_legacy_5000 = args.output + "_legacy_0x5000.bin"
    output_file_legacy_txt = args.output + "_legacy.txt"

    # Read in hex file
    new_hex_file = intelhex.IntelHex()
    new_hex_file.padding = 0xFF
    new_hex_file.fromfile(input_file, format='hex')

    # Get the starting and ending address
    addresses = new_hex_file.addresses()
    addresses.sort()
    start_end_pairs = list(ranges(addresses))
    regions = len(start_end_pairs)
    assert regions == 1, ("Error - only 1 region allowed in "
                          "hex file %i found." % regions)
    start, end = start_end_pairs[0]

    # Checksum the vector table
    #
    # Note this is only required for NXP devices but
    # it doesn't hurt to checksum all builds

    # Compute a checksum on the first 7 vector nvic vectors
    vector_size = struct.calcsize(VECTOR_FMT)
    vector_data = new_hex_file.tobinarray(start=start, size=vector_size)
    vectors = struct.unpack(VECTOR_FMT, vector_data)
    assert len(vectors) == 7, "Incorrect size of %i" % len(vectors)
    checksum = 0
    for vector in vectors:
        checksum += vector
    checksum = (~checksum + 1) & 0xFFFFFFFF  # Two's compliment

    # Write checksum back to hex
    csum_start = CHECKSUM_OFFSET + start
    csum_data = struct.pack(CHECKSUM_FMT, checksum)
    assert len(csum_data) == 4
    new_hex_file.puts(csum_start, csum_data)

    # CRC the entire image
    #
    # This is required for all builds

    # Compute checksum over the range (don't include data at location of crc)
    size = end - start + 1
    crc_size = size - 4
    data = new_hex_file.tobinarray(start=start, size=crc_size)
    crc32 = binascii.crc32(data) & 0xFFFFFFFF

    # Write CRC to the file in little endian
    new_hex_file[end - 3] = (crc32 >> 0) & 0xFF
    new_hex_file[end - 2] = (crc32 >> 8) & 0xFF
    new_hex_file[end - 1] = (crc32 >> 16) & 0xFF
    new_hex_file[end - 0] = (crc32 >> 24) & 0xFF

    # Write out file(s)
    new_hex_file.tofile(output_file_hex, 'hex')
    new_hex_file.tofile(output_file_binary, 'bin')
    with open(output_file_txt, 'wb') as file_handle:
        file_handle.write("0x%08x\r\n" % crc32)

    # Print info on operation
    print("Start 0x%x, Length 0x%x, CRC32 0x%08x" % (start, size, crc32))

    if start == 0x8000 or start == 0x88000:
        pad_addr = start - 0x3000
        legacy_zero = start + 7 * 4
        legacy_size = 4 * 4
        legacy_hex_file = intelhex.IntelHex(new_hex_file)
        for addr in range(legacy_zero, legacy_zero + legacy_size):
            legacy_hex_file[addr] = 0
        data = legacy_hex_file.tobinarray(start=start, size=crc_size)
        crc32 = binascii.crc32(data) & 0xFFFFFFFF
        # Write CRC to the file in little endian
        legacy_hex_file[end - 3] = (crc32 >> 0) & 0xFF
        legacy_hex_file[end - 2] = (crc32 >> 8) & 0xFF
        legacy_hex_file[end - 1] = (crc32 >> 16) & 0xFF
        legacy_hex_file[end - 0] = (crc32 >> 24) & 0xFF
        legacy_hex_file.tofile(output_file_legacy, 'bin')
        with open(output_file_legacy_txt, 'wb') as file_handle:
            file_handle.write("0x%08x\r\n" % crc32)
        offset_update.create_padded_image(output_file_legacy,
                                          output_file_legacy_5000,
                                          start, pad_addr, 0x40)
    elif start == 0 or start == 0x80000:
        pass
    else:
        assert 0, "Unsupported start address 0x%x" % start
Example #2
0
def post_compute_crc(input_file, output_file):
    
    output_file_hex = output_file + ".hex"
    output_file_binary = output_file + ".bin"
    output_file_txt = output_file + ".txt"
    output_file_c = output_file + ".c"
    output_file_c_generic = join(dirname(output_file), "bootloader_image.c")
    output_file_legacy = output_file + "_legacy_0x8000.bin"
    output_file_legacy_5000 = output_file + "_legacy_0x5000.bin"
    output_file_legacy_txt = output_file + "_legacy.txt"

    # Read in hex file
    new_hex_file = intelhex.IntelHex()
    new_hex_file.padding = 0xFF
    new_hex_file.fromfile(input_file, format='hex')

    # Get the starting and ending address
    addresses = new_hex_file.addresses()
    addresses.sort()
    start_end_pairs = list(ranges(addresses))
    regions = len(start_end_pairs)
    assert regions == 1, ("Error - only 1 region allowed in "
                          "hex file %i found." % regions)
    start, end = start_end_pairs[0]

    # Checksum the vector table
    #
    # Note this is only required for NXP devices but
    # it doesn't hurt to checksum all builds

    # Compute a checksum on the first 7 vector nvic vectors
    vector_size = struct.calcsize(VECTOR_FMT)
    vector_data = new_hex_file.tobinarray(start=start, size=vector_size)
    vectors = struct.unpack(VECTOR_FMT, vector_data)
    assert len(vectors) == 7, "Incorrect size of %i" % len(vectors)
    checksum = 0
    for vector in vectors:
        checksum += vector
    checksum = (~checksum + 1) & 0xFFFFFFFF  # Two's compliment

    # Write checksum back to hex
    csum_start = CHECKSUM_OFFSET + start
    csum_data = struct.pack(CHECKSUM_FMT, checksum)
    assert len(csum_data) == 4
    new_hex_file.puts(csum_start, csum_data)

    # CRC the entire image
    #
    # This is required for all builds

    # Compute checksum over the range (don't include data at location of crc)
    size = end - start + 1
    crc_size = size - 4
    data = new_hex_file.tobinarray(start=start, size=crc_size)
    crc32 = binascii.crc32(data) & 0xFFFFFFFF

    # Write CRC to the file in little endian
    new_hex_file[end - 3] = (crc32 >> 0) & 0xFF
    new_hex_file[end - 2] = (crc32 >> 8) & 0xFF
    new_hex_file[end - 1] = (crc32 >> 16) & 0xFF
    new_hex_file[end - 0] = (crc32 >> 24) & 0xFF

    # Write out file(s)
    new_hex_file.tofile(output_file_hex, 'hex')
    new_hex_file.tofile(output_file_binary, 'bin')
    with open(output_file_txt, 'w') as file_handle:
        file_handle.write("0x%08x\r\n" % crc32)

    # Write out data as a C array
    data = new_hex_file.tobinarray(start=start, size=size)
    data = list(bytearray(data))
    output_data = ('static const unsigned int image_start = 0x%08x;\n' 
                    'static const unsigned int image_size = 0x%08x;\n'
                    'static const char image_data[0x%08x] = {\n    ' %
                    (start, size, size))
    for i, byte_val in enumerate(data):
        output_data += '0x%02x' % byte_val + ', '
        if ((i + 1) % 0x20) == 0:
            output_data += '\n    '
    output_data += '};\n'
    with open(output_file_c, 'w') as file_handle:
        file_handle.write(output_data)
    with open(output_file_c_generic, 'w') as file_handle:
        file_handle.write(output_data)

    # Print info on operation
    print("Start 0x%x, Length 0x%x, CRC32 0x%08x" % (start, size, crc32))

    if start == 0x8000 or start == 0x88000 or start == 0x0800C000:
        if start == 0x0800C000:
            # Adjust for ST-Link
            pad_addr = start - 0x8000
        else:
            pad_addr = start - 0x3000
        legacy_zero = start + 7 * 4
        legacy_size = 4 * 4
        legacy_hex_file = intelhex.IntelHex(new_hex_file)
        for addr in range(legacy_zero, legacy_zero + legacy_size):
            legacy_hex_file[addr] = 0
        data = legacy_hex_file.tobinarray(start=start, size=crc_size)
        crc32 = binascii.crc32(data) & 0xFFFFFFFF
        # Write CRC to the file in little endian
        legacy_hex_file[end - 3] = (crc32 >> 0) & 0xFF
        legacy_hex_file[end - 2] = (crc32 >> 8) & 0xFF
        legacy_hex_file[end - 1] = (crc32 >> 16) & 0xFF
        legacy_hex_file[end - 0] = (crc32 >> 24) & 0xFF
        legacy_hex_file.tofile(output_file_legacy, 'bin')
        with open(output_file_legacy_txt, 'w') as file_handle:
            file_handle.write("0x%08x\r\n" % crc32)
        offset_update.create_padded_image(output_file_legacy,
                                          output_file_legacy_5000,
                                          start, pad_addr, 0x40)
Example #3
0
def post_build_script(input_file,
                      output_file,
                      board_id=None,
                      family_id=None,
                      bin_offset=None,
                      flash_algo_file=None,
                      target_ram_start=None,
                      target_ram_end=None,
                      flash_blob_entry="0x20000000"):
    output_format_file = '-'.join(
        filter(None, (output_file, board_id, family_id, bin_offset)))
    print(output_format_file)
    output_file_hex = output_format_file + ".hex"
    output_file_binary = output_format_file + ".bin"
    output_file_txt = output_format_file + ".txt"
    output_file_c = output_format_file + ".c"
    output_file_c_generic = join(dirname(output_file), "bootloader_image.c")
    output_file_legacy = output_format_file + "_legacy_0x8000.bin"
    output_file_legacy_5000 = output_format_file + "_legacy_0x5000.bin"
    output_file_legacy_txt = output_format_file + "_legacy.txt"

    # Read in hex file
    new_hex_file = intelhex.IntelHex()
    new_hex_file.padding = 0xFF

    if input_file.lower().endswith('.bin'):
        if bin_offset is not None:
            new_hex_file.loadbin(input_file, offset=int(bin_offset, 16))
        else:
            new_hex_file.loadbin(input_file)
    else:  #always assume hex format
        new_hex_file.fromfile(input_file, format='hex')

    # Get the starting and ending address
    addresses = new_hex_file.addresses()
    addresses.sort()
    start_end_pairs = list(ranges(addresses))
    regions = len(start_end_pairs)
    assert regions == 1, ("Error - only 1 region allowed in "
                          "hex file %i found." % regions)
    start, end = start_end_pairs[0]

    pack_flash_algo = None
    if flash_algo_file is not None:
        with open(flash_algo_file, "rb") as file_handle:
            pack_flash_algo = PackFlashAlgo(file_handle.read())

    # Checksum the vector table
    #
    # Note this is only required for NXP devices but
    # it doesn't hurt to checksum all builds

    # Compute a checksum on the first 7 vector nvic vectors
    vector_size = struct.calcsize(VECTOR_FMT)
    vector_data = new_hex_file.tobinarray(start=start, size=vector_size)
    vectors = struct.unpack(VECTOR_FMT, vector_data)
    assert len(vectors) == 7, "Incorrect size of %i" % len(vectors)
    checksum = 0
    for vector in vectors:
        checksum += vector
    checksum = (~checksum + 1) & 0xFFFFFFFF  # Two's compliment
    # Write checksum back to hex
    csum_start = CHECKSUM_OFFSET + start
    csum_data = struct.pack(CHECKSUM_FMT, checksum)
    assert len(csum_data) == 4
    new_hex_file.puts(csum_start, csum_data)

    print("board_id", board_id)
    print("family_id", family_id)
    print("bin_offset", bin_offset)
    if board_id is not None or family_id is not None:
        target_info_addr = new_hex_file.gets(start + TARGET_INFO_OFFSET, 4)
        target_addr_unpack = struct.unpack("<1I", target_info_addr)[0]
        print("board_info offset: ", hex(target_addr_unpack - start))
        #family_id is in integer hex
        if family_id is not None:
            new_hex_file.puts(target_addr_unpack + 2,
                              struct.pack('<1H', int(family_id, 16)))
        #board_id is in string hex
        if board_id is not None:
            new_hex_file.puts(target_addr_unpack + 4,
                              struct.pack('4s', "%.04X" % int(board_id, 16)))
        if pack_flash_algo is not None:
            blob_header = (0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040,
                           0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2)
            stack_size = 0x200
            region_info_fmt = '5I'
            region_info_total = 10
            target_cfg_fmt = '3I' + region_info_fmt * region_info_total * 2 + 'IHBB'
            sector_info_fmt = '2I'
            sector_info_len = len(pack_flash_algo.sector_sizes)
            program_target_fmt = '14I'
            flash_blob_entry = int(flash_blob_entry, 16)
            blob_pad_size = (
                (len(pack_flash_algo.algo_data) + ALLIGN_PADS - 1) //
                ALLIGN_PADS * ALLIGN_PADS) - len(pack_flash_algo.algo_data)
            blob_header_size = len(blob_header) * 4
            total_struct_size = blob_header_size + len(
                pack_flash_algo.algo_data
            ) + blob_pad_size + sector_info_len * struct.calcsize(
                sector_info_fmt) + struct.calcsize(
                    program_target_fmt) + struct.calcsize(target_cfg_fmt)
            flash_blob_addr = end + 1 - 4 - total_struct_size  #make room for crc
            print("flash_blob offset:", hex(flash_blob_addr - start))
            new_hex_file.puts(
                flash_blob_addr,
                struct.pack('<' + 'I' * len(blob_header), *blob_header))
            new_hex_file.puts(
                flash_blob_addr + blob_header_size,
                pack_flash_algo.algo_data + "\x00" * blob_pad_size)
            sector_info_addr = flash_blob_addr + blob_header_size + len(
                pack_flash_algo.algo_data) + blob_pad_size
            sector_info_arr = []
            for flash_start, flash_size in pack_flash_algo.sector_sizes:
                sector_info_arr.append(flash_start +
                                       pack_flash_algo.flash_start)
                sector_info_arr.append(flash_size)
            print("sector_info offset:", hex(sector_info_addr - start))
            new_hex_file.puts(
                sector_info_addr,
                struct.pack('<' + 'I' * len(sector_info_arr),
                            *sector_info_arr))
            program_target_addr = sector_info_addr + len(sector_info_arr) * 4
            stack_pointer = (flash_blob_entry + blob_header_size +
                             pack_flash_algo.rw_start + pack_flash_algo.rw_size
                             + stack_size + 0x100 - 1) // 0x100 * 0x100
            print("program_target offset:", hex(program_target_addr - start))
            new_hex_file.puts(
                program_target_addr,
                struct.pack(
                    '<' + program_target_fmt,
                    pack_flash_algo.symbols['Init'] + blob_header_size +
                    flash_blob_entry,
                    pack_flash_algo.symbols['UnInit'] + blob_header_size +
                    flash_blob_entry,
                    pack_flash_algo.symbols['EraseChip'] + blob_header_size +
                    flash_blob_entry if
                    pack_flash_algo.symbols['EraseChip'] != 0xffffffff else 0,
                    pack_flash_algo.symbols['EraseSector'] + blob_header_size +
                    flash_blob_entry,
                    pack_flash_algo.symbols['ProgramPage'] + blob_header_size +
                    flash_blob_entry,
                    pack_flash_algo.symbols['Verify'] + blob_header_size +
                    flash_blob_entry
                    if pack_flash_algo.symbols['Verify'] != 0xffffffff else 0,
                    flash_blob_entry + 1,  #BKPT : start of blob + 1
                    flash_blob_entry + blob_header_size + pack_flash_algo.
                    rw_start,  #RSB  : blob start + header + rw data offset
                    stack_pointer,  #RSP  : stack pointer
                    flash_blob_entry + 0x00000A00,  #mem buffer location
                    flash_blob_entry,  #location to write prog_blob in target RAM
                    blob_header_size + len(pack_flash_algo.algo_data) +
                    blob_pad_size,  #prog_blob size
                    flash_blob_addr,  #address of prog_blob
                    pack_flash_algo.
                    page_size  #ram_to_flash_bytes_to_be_written
                ))
            target_cfg_addr = program_target_addr + struct.calcsize(
                program_target_fmt)
            print("target_cfg offset:", hex(target_cfg_addr - start))
            if target_ram_start is None or target_ram_end is None:
                raise Exception(
                    "target_ram_start and target_ram_end should be defined!")
            first_flash_region = (pack_flash_algo.flash_start,
                                  pack_flash_algo.flash_start +
                                  pack_flash_algo.flash_size, 1, 0,
                                  program_target_addr)
            first_ram_region = (int(target_ram_start,
                                    16), int(target_ram_end, 16), 0, 0, 0)
            emypty_region = (0, 0, 0, 0, 0) * (region_info_total - 1)
            all_regions = first_flash_region + emypty_region + first_ram_region + emypty_region
            target_flags = (
                0, 0, 0, 0)  #realtime board ID, family ID and erase reset flag
            regions_flags = all_regions + target_flags
            new_hex_file.puts(
                target_cfg_addr,
                struct.pack(
                    '<' + target_cfg_fmt,
                    0x1,  #script generated
                    sector_info_addr,  # Sector start and length list
                    sector_info_len,  #Sector start and length list total
                    *regions_flags))
            board_info_flag = 1 if pack_flash_algo.symbols[
                'EraseSector'] != 0xffffffff else 0  #kEnablePageErase
            new_hex_file.puts(
                target_addr_unpack + 12, struct.pack('<1I', board_info_flag)
            )  #always enable page erase EraseSector is a required symbol in flash algo
            new_hex_file.puts(target_addr_unpack + 16,
                              struct.pack('<1I', target_cfg_addr))

    # CRC the entire image
    #
    # This is required for all builds

    # Compute checksum over the range (don't include data at location of crc)
    size = end - start + 1
    crc_size = size - 4
    data = new_hex_file.tobinarray(start=start, size=crc_size)
    crc32 = binascii.crc32(data) & 0xFFFFFFFF

    # Write CRC to the file in little endian
    new_hex_file[end - 3] = (crc32 >> 0) & 0xFF
    new_hex_file[end - 2] = (crc32 >> 8) & 0xFF
    new_hex_file[end - 1] = (crc32 >> 16) & 0xFF
    new_hex_file[end - 0] = (crc32 >> 24) & 0xFF

    # Write out file(s)
    new_hex_file.tofile(output_file_hex, 'hex')
    new_hex_file.tofile(output_file_binary, 'bin')
    with open(output_file_txt, 'w') as file_handle:
        file_handle.write("0x%08x\r\n" % crc32)

    # Write out data as a C array
    data = new_hex_file.tobinarray(start=start, size=size)
    data = list(bytearray(data))
    output_data = ('static const unsigned int image_start = 0x%08x;\n'
                   'static const unsigned int image_size = 0x%08x;\n'
                   'static const char image_data[0x%08x] = {\n    ' %
                   (start, size, size))
    for i, byte_val in enumerate(data):
        output_data += '0x%02x' % byte_val + ', '
        if ((i + 1) % 0x20) == 0:
            output_data += '\n    '
    output_data += '};\n'
    with open(output_file_c, 'w') as file_handle:
        file_handle.write(output_data)
    with open(output_file_c_generic, 'w') as file_handle:
        file_handle.write(output_data)

    # Print info on operation
    print("Start 0x%x, Length 0x%x, CRC32 0x%08x" % (start, size, crc32))

    if start == 0x8000 or start == 0x10000 or start == 0x88000 or start == 0x0800C000:
        if start == 0x0800C000:
            # Adjust for ST-Link
            pad_addr = start - 0x8000
        else:
            pad_addr = start - 0x3000
        legacy_zero = start + 7 * 4
        legacy_size = 4 * 4
        legacy_hex_file = intelhex.IntelHex(new_hex_file)
        for addr in range(legacy_zero, legacy_zero + legacy_size):
            legacy_hex_file[addr] = 0
        data = legacy_hex_file.tobinarray(start=start, size=crc_size)
        crc32 = binascii.crc32(data) & 0xFFFFFFFF
        # Write CRC to the file in little endian
        legacy_hex_file[end - 3] = (crc32 >> 0) & 0xFF
        legacy_hex_file[end - 2] = (crc32 >> 8) & 0xFF
        legacy_hex_file[end - 1] = (crc32 >> 16) & 0xFF
        legacy_hex_file[end - 0] = (crc32 >> 24) & 0xFF
        legacy_hex_file.tofile(output_file_legacy, 'bin')
        with open(output_file_legacy_txt, 'w') as file_handle:
            file_handle.write("0x%08x\r\n" % crc32)
        offset_update.create_padded_image(output_file_legacy,
                                          output_file_legacy_5000, start,
                                          pad_addr, 0x40)
Example #4
0
def post_build_script(input_file,
                      output_file,
                      board_id=None,
                      family_id=None,
                      bin_offset=None):
    output_format_file = '-'.join(
        filter(None, (output_file, board_id, family_id, bin_offset)))
    print(output_format_file)
    output_file_hex = output_format_file + ".hex"
    output_file_binary = output_format_file + ".bin"
    output_file_txt = output_format_file + ".txt"
    output_file_c = output_format_file + ".c"
    output_file_c_generic = join(dirname(output_file), "bootloader_image.c")
    output_file_legacy = output_format_file + "_legacy_0x8000.bin"
    output_file_legacy_5000 = output_format_file + "_legacy_0x5000.bin"
    output_file_legacy_txt = output_format_file + "_legacy.txt"

    # Read in hex file
    new_hex_file = intelhex.IntelHex()
    new_hex_file.padding = 0xFF

    if input_file.lower().endswith('.bin'):
        if bin_offset is not None:
            new_hex_file.loadbin(input_file, offset=int(bin_offset, 16))
        else:
            new_hex_file.loadbin(input_file)
    else:  #always assume hex format
        new_hex_file.fromfile(input_file, format='hex')

    # Get the starting and ending address
    addresses = new_hex_file.addresses()
    addresses.sort()
    start_end_pairs = list(ranges(addresses))
    regions = len(start_end_pairs)
    assert regions == 1, ("Error - only 1 region allowed in "
                          "hex file %i found." % regions)
    start, end = start_end_pairs[0]

    # Checksum the vector table
    #
    # Note this is only required for NXP devices but
    # it doesn't hurt to checksum all builds

    # Compute a checksum on the first 7 vector nvic vectors
    vector_size = struct.calcsize(VECTOR_FMT)
    vector_data = new_hex_file.tobinarray(start=start, size=vector_size)
    vectors = struct.unpack(VECTOR_FMT, vector_data)
    assert len(vectors) == 7, "Incorrect size of %i" % len(vectors)
    checksum = 0
    for vector in vectors:
        checksum += vector
    checksum = (~checksum + 1) & 0xFFFFFFFF  # Two's compliment
    # Write checksum back to hex
    csum_start = CHECKSUM_OFFSET + start
    csum_data = struct.pack(CHECKSUM_FMT, checksum)
    assert len(csum_data) == 4
    new_hex_file.puts(csum_start, csum_data)

    print("board_id", board_id)
    print("family_id", family_id)
    print("bin_offset", bin_offset)
    if board_id is not None or family_id is not None:
        target_info_addr = new_hex_file.gets(start + TARGET_INFO_OFFSET, 4)
        target_addr_unpack = struct.unpack("<1I", target_info_addr)[0]
        print("board_info addr: ", hex(target_addr_unpack - start))
        #family_id is in integer hex
        if family_id is not None:
            new_hex_file.puts(target_addr_unpack + 2,
                              struct.pack('<1H', int(family_id, 16)))
        #board_id is in string hex
        if board_id is not None:
            new_hex_file.puts(target_addr_unpack + 4,
                              struct.pack('4s', "%.04X" % int(board_id, 16)))

    # CRC the entire image
    #
    # This is required for all builds

    # Compute checksum over the range (don't include data at location of crc)
    size = end - start + 1
    crc_size = size - 4
    data = new_hex_file.tobinarray(start=start, size=crc_size)
    crc32 = binascii.crc32(data) & 0xFFFFFFFF

    # Write CRC to the file in little endian
    new_hex_file[end - 3] = (crc32 >> 0) & 0xFF
    new_hex_file[end - 2] = (crc32 >> 8) & 0xFF
    new_hex_file[end - 1] = (crc32 >> 16) & 0xFF
    new_hex_file[end - 0] = (crc32 >> 24) & 0xFF

    # Write out file(s)
    new_hex_file.tofile(output_file_hex, 'hex')
    new_hex_file.tofile(output_file_binary, 'bin')
    with open(output_file_txt, 'w') as file_handle:
        file_handle.write("0x%08x\r\n" % crc32)

    # Write out data as a C array
    data = new_hex_file.tobinarray(start=start, size=size)
    data = list(bytearray(data))
    output_data = ('static const unsigned int image_start = 0x%08x;\n'
                   'static const unsigned int image_size = 0x%08x;\n'
                   'static const char image_data[0x%08x] = {\n    ' %
                   (start, size, size))
    for i, byte_val in enumerate(data):
        output_data += '0x%02x' % byte_val + ', '
        if ((i + 1) % 0x20) == 0:
            output_data += '\n    '
    output_data += '};\n'
    with open(output_file_c, 'w') as file_handle:
        file_handle.write(output_data)
    with open(output_file_c_generic, 'w') as file_handle:
        file_handle.write(output_data)

    # Print info on operation
    print("Start 0x%x, Length 0x%x, CRC32 0x%08x" % (start, size, crc32))

    if start == 0x8000 or start == 0x10000 or start == 0x88000 or start == 0x0800C000:
        if start == 0x0800C000:
            # Adjust for ST-Link
            pad_addr = start - 0x8000
        else:
            pad_addr = start - 0x3000
        legacy_zero = start + 7 * 4
        legacy_size = 4 * 4
        legacy_hex_file = intelhex.IntelHex(new_hex_file)
        for addr in range(legacy_zero, legacy_zero + legacy_size):
            legacy_hex_file[addr] = 0
        data = legacy_hex_file.tobinarray(start=start, size=crc_size)
        crc32 = binascii.crc32(data) & 0xFFFFFFFF
        # Write CRC to the file in little endian
        legacy_hex_file[end - 3] = (crc32 >> 0) & 0xFF
        legacy_hex_file[end - 2] = (crc32 >> 8) & 0xFF
        legacy_hex_file[end - 1] = (crc32 >> 16) & 0xFF
        legacy_hex_file[end - 0] = (crc32 >> 24) & 0xFF
        legacy_hex_file.tofile(output_file_legacy, 'bin')
        with open(output_file_legacy_txt, 'w') as file_handle:
            file_handle.write("0x%08x\r\n" % crc32)
        offset_update.create_padded_image(output_file_legacy,
                                          output_file_legacy_5000, start,
                                          pad_addr, 0x40)