Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.
Upstream: https://github.com/ARMmbed/DAPLink
tools/post_build_script.py@0:01f31e923fe2, 2020-04-07 (annotated)
- Committer:
- Pawel Zarembski
- Date:
- Tue Apr 07 12:55:42 2020 +0200
- Revision:
- 0:01f31e923fe2
hani: DAPLink with reset workaround
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Pawel Zarembski |
0:01f31e923fe2 | 1 | # |
Pawel Zarembski |
0:01f31e923fe2 | 2 | # DAPLink Interface Firmware |
Pawel Zarembski |
0:01f31e923fe2 | 3 | # Copyright (c) 2009-2019, ARM Limited, All Rights Reserved |
Pawel Zarembski |
0:01f31e923fe2 | 4 | # SPDX-License-Identifier: Apache-2.0 |
Pawel Zarembski |
0:01f31e923fe2 | 5 | # |
Pawel Zarembski |
0:01f31e923fe2 | 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
Pawel Zarembski |
0:01f31e923fe2 | 7 | # not use this file except in compliance with the License. |
Pawel Zarembski |
0:01f31e923fe2 | 8 | # You may obtain a copy of the License at |
Pawel Zarembski |
0:01f31e923fe2 | 9 | # |
Pawel Zarembski |
0:01f31e923fe2 | 10 | # http://www.apache.org/licenses/LICENSE-2.0 |
Pawel Zarembski |
0:01f31e923fe2 | 11 | # |
Pawel Zarembski |
0:01f31e923fe2 | 12 | # Unless required by applicable law or agreed to in writing, software |
Pawel Zarembski |
0:01f31e923fe2 | 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
Pawel Zarembski |
0:01f31e923fe2 | 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Pawel Zarembski |
0:01f31e923fe2 | 15 | # See the License for the specific language governing permissions and |
Pawel Zarembski |
0:01f31e923fe2 | 16 | # limitations under the License. |
Pawel Zarembski |
0:01f31e923fe2 | 17 | # |
Pawel Zarembski |
0:01f31e923fe2 | 18 | |
Pawel Zarembski |
0:01f31e923fe2 | 19 | from __future__ import absolute_import |
Pawel Zarembski |
0:01f31e923fe2 | 20 | from __future__ import print_function |
Pawel Zarembski |
0:01f31e923fe2 | 21 | |
Pawel Zarembski |
0:01f31e923fe2 | 22 | import argparse |
Pawel Zarembski |
0:01f31e923fe2 | 23 | import itertools |
Pawel Zarembski |
0:01f31e923fe2 | 24 | import binascii |
Pawel Zarembski |
0:01f31e923fe2 | 25 | import struct |
Pawel Zarembski |
0:01f31e923fe2 | 26 | import intelhex |
Pawel Zarembski |
0:01f31e923fe2 | 27 | import offset_update |
Pawel Zarembski |
0:01f31e923fe2 | 28 | from os.path import dirname, join |
Pawel Zarembski |
0:01f31e923fe2 | 29 | from flash_algo import PackFlashAlgo |
Pawel Zarembski |
0:01f31e923fe2 | 30 | |
Pawel Zarembski |
0:01f31e923fe2 | 31 | VECTOR_FMT = "<7I" |
Pawel Zarembski |
0:01f31e923fe2 | 32 | CHECKSUM_FMT = "<1I" |
Pawel Zarembski |
0:01f31e923fe2 | 33 | CHECKSUM_OFFSET = 0x1C |
Pawel Zarembski |
0:01f31e923fe2 | 34 | TARGET_INFO_OFFSET = 13*4 |
Pawel Zarembski |
0:01f31e923fe2 | 35 | ALIGN_PADS = 4 |
Pawel Zarembski |
0:01f31e923fe2 | 36 | |
Pawel Zarembski |
0:01f31e923fe2 | 37 | def ranges(i): |
Pawel Zarembski |
0:01f31e923fe2 | 38 | for _, b in itertools.groupby(enumerate(i), lambda x_y: x_y[1] - x_y[0]): |
Pawel Zarembski |
0:01f31e923fe2 | 39 | b = list(b) |
Pawel Zarembski |
0:01f31e923fe2 | 40 | yield b[0][1], b[-1][1] |
Pawel Zarembski |
0:01f31e923fe2 | 41 | |
Pawel Zarembski |
0:01f31e923fe2 | 42 | 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"): |
Pawel Zarembski |
0:01f31e923fe2 | 43 | output_format_file = '-'.join(filter(None, (output_file, board_id, family_id, bin_offset))) |
Pawel Zarembski |
0:01f31e923fe2 | 44 | print(output_format_file) |
Pawel Zarembski |
0:01f31e923fe2 | 45 | output_file_hex = output_format_file + ".hex" |
Pawel Zarembski |
0:01f31e923fe2 | 46 | output_file_binary = output_format_file + ".bin" |
Pawel Zarembski |
0:01f31e923fe2 | 47 | output_file_txt = output_format_file + ".txt" |
Pawel Zarembski |
0:01f31e923fe2 | 48 | output_file_c = output_format_file + ".c" |
Pawel Zarembski |
0:01f31e923fe2 | 49 | output_file_c_generic = join(dirname(output_file), "bootloader_image.c") |
Pawel Zarembski |
0:01f31e923fe2 | 50 | output_file_legacy = output_format_file + "_legacy_0x8000.bin" |
Pawel Zarembski |
0:01f31e923fe2 | 51 | output_file_legacy_5000 = output_format_file + "_legacy_0x5000.bin" |
Pawel Zarembski |
0:01f31e923fe2 | 52 | output_file_legacy_txt = output_format_file + "_legacy.txt" |
Pawel Zarembski |
0:01f31e923fe2 | 53 | |
Pawel Zarembski |
0:01f31e923fe2 | 54 | # Read in hex file |
Pawel Zarembski |
0:01f31e923fe2 | 55 | new_hex_file = intelhex.IntelHex() |
Pawel Zarembski |
0:01f31e923fe2 | 56 | new_hex_file.padding = 0xFF |
Pawel Zarembski |
0:01f31e923fe2 | 57 | |
Pawel Zarembski |
0:01f31e923fe2 | 58 | if input_file.lower().endswith('.bin'): |
Pawel Zarembski |
0:01f31e923fe2 | 59 | if bin_offset is not None: |
Pawel Zarembski |
0:01f31e923fe2 | 60 | new_hex_file.loadbin(input_file, offset=int(bin_offset, 16)) |
Pawel Zarembski |
0:01f31e923fe2 | 61 | else: |
Pawel Zarembski |
0:01f31e923fe2 | 62 | new_hex_file.loadbin(input_file) |
Pawel Zarembski |
0:01f31e923fe2 | 63 | else: #always assume hex format |
Pawel Zarembski |
0:01f31e923fe2 | 64 | new_hex_file.fromfile(input_file, format='hex') |
Pawel Zarembski |
0:01f31e923fe2 | 65 | |
Pawel Zarembski |
0:01f31e923fe2 | 66 | |
Pawel Zarembski |
0:01f31e923fe2 | 67 | # Get the starting and ending address |
Pawel Zarembski |
0:01f31e923fe2 | 68 | addresses = new_hex_file.addresses() |
Pawel Zarembski |
0:01f31e923fe2 | 69 | addresses.sort() |
Pawel Zarembski |
0:01f31e923fe2 | 70 | start_end_pairs = list(ranges(addresses)) |
Pawel Zarembski |
0:01f31e923fe2 | 71 | regions = len(start_end_pairs) |
Pawel Zarembski |
0:01f31e923fe2 | 72 | assert regions == 1, ("Error - only 1 region allowed in " |
Pawel Zarembski |
0:01f31e923fe2 | 73 | "hex file %i found." % regions) |
Pawel Zarembski |
0:01f31e923fe2 | 74 | start, end = start_end_pairs[0] |
Pawel Zarembski |
0:01f31e923fe2 | 75 | |
Pawel Zarembski |
0:01f31e923fe2 | 76 | pack_flash_algo = None |
Pawel Zarembski |
0:01f31e923fe2 | 77 | if flash_algo_file is not None: |
Pawel Zarembski |
0:01f31e923fe2 | 78 | with open(flash_algo_file, "rb") as file_handle: |
Pawel Zarembski |
0:01f31e923fe2 | 79 | pack_flash_algo = PackFlashAlgo(file_handle.read()) |
Pawel Zarembski |
0:01f31e923fe2 | 80 | |
Pawel Zarembski |
0:01f31e923fe2 | 81 | # Checksum the vector table |
Pawel Zarembski |
0:01f31e923fe2 | 82 | # |
Pawel Zarembski |
0:01f31e923fe2 | 83 | # Note this is only required for NXP devices but |
Pawel Zarembski |
0:01f31e923fe2 | 84 | # it doesn't hurt to checksum all builds |
Pawel Zarembski |
0:01f31e923fe2 | 85 | |
Pawel Zarembski |
0:01f31e923fe2 | 86 | # Compute a checksum on the first 7 vector nvic vectors |
Pawel Zarembski |
0:01f31e923fe2 | 87 | vector_size = struct.calcsize(VECTOR_FMT) |
Pawel Zarembski |
0:01f31e923fe2 | 88 | vector_data = new_hex_file.tobinarray(start=start, size=vector_size) |
Pawel Zarembski |
0:01f31e923fe2 | 89 | vectors = struct.unpack(VECTOR_FMT, vector_data) |
Pawel Zarembski |
0:01f31e923fe2 | 90 | assert len(vectors) == 7, "Incorrect size of %i" % len(vectors) |
Pawel Zarembski |
0:01f31e923fe2 | 91 | checksum = 0 |
Pawel Zarembski |
0:01f31e923fe2 | 92 | for vector in vectors: |
Pawel Zarembski |
0:01f31e923fe2 | 93 | checksum += vector |
Pawel Zarembski |
0:01f31e923fe2 | 94 | checksum = (~checksum + 1) & 0xFFFFFFFF # Two's compliment |
Pawel Zarembski |
0:01f31e923fe2 | 95 | # Write checksum back to hex |
Pawel Zarembski |
0:01f31e923fe2 | 96 | csum_start = CHECKSUM_OFFSET + start |
Pawel Zarembski |
0:01f31e923fe2 | 97 | csum_data = struct.pack(CHECKSUM_FMT, checksum) |
Pawel Zarembski |
0:01f31e923fe2 | 98 | assert len(csum_data) == 4 |
Pawel Zarembski |
0:01f31e923fe2 | 99 | new_hex_file.puts(csum_start, csum_data) |
Pawel Zarembski |
0:01f31e923fe2 | 100 | |
Pawel Zarembski |
0:01f31e923fe2 | 101 | print("board_id", board_id) |
Pawel Zarembski |
0:01f31e923fe2 | 102 | print("family_id", family_id) |
Pawel Zarembski |
0:01f31e923fe2 | 103 | print("bin_offset", bin_offset) |
Pawel Zarembski |
0:01f31e923fe2 | 104 | if board_id is not None or family_id is not None: |
Pawel Zarembski |
0:01f31e923fe2 | 105 | target_info_addr = new_hex_file.gets(start + TARGET_INFO_OFFSET, 4) |
Pawel Zarembski |
0:01f31e923fe2 | 106 | target_addr_unpack = struct.unpack("<1I",target_info_addr)[0] |
Pawel Zarembski |
0:01f31e923fe2 | 107 | print("board_info offset: ",hex(target_addr_unpack - start)) |
Pawel Zarembski |
0:01f31e923fe2 | 108 | #family_id is in integer hex |
Pawel Zarembski |
0:01f31e923fe2 | 109 | if family_id is not None: |
Pawel Zarembski |
0:01f31e923fe2 | 110 | new_hex_file.puts(target_addr_unpack + 2,struct.pack('<1H',int(family_id, 16))) |
Pawel Zarembski |
0:01f31e923fe2 | 111 | #board_id is in string hex |
Pawel Zarembski |
0:01f31e923fe2 | 112 | if board_id is not None: |
Pawel Zarembski |
0:01f31e923fe2 | 113 | new_hex_file.puts(target_addr_unpack + 4,struct.pack('4s',"%.04X" % int(board_id, 16))) |
Pawel Zarembski |
0:01f31e923fe2 | 114 | if pack_flash_algo is not None: |
Pawel Zarembski |
0:01f31e923fe2 | 115 | blob_header = (0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2) |
Pawel Zarembski |
0:01f31e923fe2 | 116 | stack_size = 0x200 |
Pawel Zarembski |
0:01f31e923fe2 | 117 | region_info_fmt = '5I' |
Pawel Zarembski |
0:01f31e923fe2 | 118 | region_info_total = 10 |
Pawel Zarembski |
0:01f31e923fe2 | 119 | target_cfg_fmt = '3I'+ region_info_fmt*region_info_total*2 + 'IHBB' |
Pawel Zarembski |
0:01f31e923fe2 | 120 | sector_info_fmt = '2I' |
Pawel Zarembski |
0:01f31e923fe2 | 121 | sector_info_len = len(pack_flash_algo.sector_sizes) |
Pawel Zarembski |
0:01f31e923fe2 | 122 | program_target_fmt = '14I' |
Pawel Zarembski |
0:01f31e923fe2 | 123 | flash_blob_entry = int(flash_blob_entry, 16) |
Pawel Zarembski |
0:01f31e923fe2 | 124 | blob_pad_size = ((len(pack_flash_algo.algo_data) + ALIGN_PADS -1) // ALIGN_PADS * ALIGN_PADS) - len(pack_flash_algo.algo_data) |
Pawel Zarembski |
0:01f31e923fe2 | 125 | blob_header_size = len(blob_header) * 4 |
Pawel Zarembski |
0:01f31e923fe2 | 126 | 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) |
Pawel Zarembski |
0:01f31e923fe2 | 127 | flash_blob_addr = end + 1 - 4 - total_struct_size #make room for crc |
Pawel Zarembski |
0:01f31e923fe2 | 128 | print("flash_blob offset:", hex(flash_blob_addr - start)) |
Pawel Zarembski |
0:01f31e923fe2 | 129 | new_hex_file.puts(flash_blob_addr, struct.pack('<'+'I'*len(blob_header), *blob_header)) |
Pawel Zarembski |
0:01f31e923fe2 | 130 | new_hex_file.puts(flash_blob_addr + blob_header_size, pack_flash_algo.algo_data + "\x00" * blob_pad_size) |
Pawel Zarembski |
0:01f31e923fe2 | 131 | sector_info_addr = flash_blob_addr+blob_header_size + len(pack_flash_algo.algo_data) + blob_pad_size |
Pawel Zarembski |
0:01f31e923fe2 | 132 | sector_info_arr = [] |
Pawel Zarembski |
0:01f31e923fe2 | 133 | for flash_start, flash_size in pack_flash_algo.sector_sizes: |
Pawel Zarembski |
0:01f31e923fe2 | 134 | sector_info_arr.append(flash_start + pack_flash_algo.flash_start) |
Pawel Zarembski |
0:01f31e923fe2 | 135 | sector_info_arr.append(flash_size) |
Pawel Zarembski |
0:01f31e923fe2 | 136 | print("sector_info offset:", hex(sector_info_addr - start)) |
Pawel Zarembski |
0:01f31e923fe2 | 137 | new_hex_file.puts(sector_info_addr,struct.pack('<' + 'I'*len(sector_info_arr), *sector_info_arr)) |
Pawel Zarembski |
0:01f31e923fe2 | 138 | program_target_addr = sector_info_addr + len(sector_info_arr)*4 |
Pawel Zarembski |
0:01f31e923fe2 | 139 | stack_pointer = (flash_blob_entry + blob_header_size + pack_flash_algo.rw_start + pack_flash_algo.rw_size + stack_size + 0x100 - 1) // 0x100 * 0x100 |
Pawel Zarembski |
0:01f31e923fe2 | 140 | print("program_target offset:", hex(program_target_addr - start)) |
Pawel Zarembski |
0:01f31e923fe2 | 141 | new_hex_file.puts(program_target_addr,struct.pack('<' + program_target_fmt, |
Pawel Zarembski |
0:01f31e923fe2 | 142 | pack_flash_algo.symbols['Init'] + blob_header_size + flash_blob_entry, |
Pawel Zarembski |
0:01f31e923fe2 | 143 | pack_flash_algo.symbols['UnInit'] + blob_header_size + flash_blob_entry, |
Pawel Zarembski |
0:01f31e923fe2 | 144 | pack_flash_algo.symbols['EraseChip'] + blob_header_size + flash_blob_entry if pack_flash_algo.symbols['EraseChip'] != 0xffffffff else 0, |
Pawel Zarembski |
0:01f31e923fe2 | 145 | pack_flash_algo.symbols['EraseSector'] + blob_header_size + flash_blob_entry, |
Pawel Zarembski |
0:01f31e923fe2 | 146 | pack_flash_algo.symbols['ProgramPage'] + blob_header_size + flash_blob_entry, |
Pawel Zarembski |
0:01f31e923fe2 | 147 | pack_flash_algo.symbols['Verify'] + blob_header_size + flash_blob_entry if pack_flash_algo.symbols['Verify'] != 0xffffffff else 0, |
Pawel Zarembski |
0:01f31e923fe2 | 148 | flash_blob_entry + 1, #BKPT : start of blob + 1 |
Pawel Zarembski |
0:01f31e923fe2 | 149 | flash_blob_entry + blob_header_size + pack_flash_algo.rw_start, #RSB : blob start + header + rw data offset |
Pawel Zarembski |
0:01f31e923fe2 | 150 | stack_pointer, #RSP : stack pointer |
Pawel Zarembski |
0:01f31e923fe2 | 151 | flash_blob_entry + 0x00000A00, #mem buffer location |
Pawel Zarembski |
0:01f31e923fe2 | 152 | flash_blob_entry, #location to write prog_blob in target RAM |
Pawel Zarembski |
0:01f31e923fe2 | 153 | blob_header_size + len(pack_flash_algo.algo_data) + blob_pad_size, #prog_blob size |
Pawel Zarembski |
0:01f31e923fe2 | 154 | flash_blob_addr, #address of prog_blob |
Pawel Zarembski |
0:01f31e923fe2 | 155 | pack_flash_algo.page_size #ram_to_flash_bytes_to_be_written |
Pawel Zarembski |
0:01f31e923fe2 | 156 | )) |
Pawel Zarembski |
0:01f31e923fe2 | 157 | target_cfg_addr = program_target_addr + struct.calcsize(program_target_fmt) |
Pawel Zarembski |
0:01f31e923fe2 | 158 | print("target_cfg offset:", hex(target_cfg_addr - start)) |
Pawel Zarembski |
0:01f31e923fe2 | 159 | if target_ram_start is None or target_ram_end is None: |
Pawel Zarembski |
0:01f31e923fe2 | 160 | raise Exception("target_ram_start and target_ram_end should be defined!") |
Pawel Zarembski |
0:01f31e923fe2 | 161 | first_flash_region = (pack_flash_algo.flash_start, pack_flash_algo.flash_start + pack_flash_algo.flash_size, 1, 0, program_target_addr) |
Pawel Zarembski |
0:01f31e923fe2 | 162 | first_ram_region = (int(target_ram_start, 16), int(target_ram_end, 16), 0, 0, 0) |
Pawel Zarembski |
0:01f31e923fe2 | 163 | emypty_region = (0, 0, 0, 0, 0) * (region_info_total -1) |
Pawel Zarembski |
0:01f31e923fe2 | 164 | all_regions = first_flash_region + emypty_region + first_ram_region + emypty_region |
Pawel Zarembski |
0:01f31e923fe2 | 165 | target_flags = ( 0, 0, 0, 0) #realtime board ID, family ID and erase reset flag |
Pawel Zarembski |
0:01f31e923fe2 | 166 | regions_flags = all_regions + target_flags |
Pawel Zarembski |
0:01f31e923fe2 | 167 | new_hex_file.puts(target_cfg_addr, struct.pack('<' + target_cfg_fmt, |
Pawel Zarembski |
0:01f31e923fe2 | 168 | 0x1, #script generated |
Pawel Zarembski |
0:01f31e923fe2 | 169 | sector_info_addr, # Sector start and length list |
Pawel Zarembski |
0:01f31e923fe2 | 170 | sector_info_len, #Sector start and length list total |
Pawel Zarembski |
0:01f31e923fe2 | 171 | *regions_flags |
Pawel Zarembski |
0:01f31e923fe2 | 172 | )) |
Pawel Zarembski |
0:01f31e923fe2 | 173 | board_info_flag = 1 if pack_flash_algo.symbols['EraseSector'] != 0xffffffff else 0 #kEnablePageErase |
Pawel Zarembski |
0:01f31e923fe2 | 174 | 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 |
Pawel Zarembski |
0:01f31e923fe2 | 175 | new_hex_file.puts(target_addr_unpack + 16,struct.pack('<1I', target_cfg_addr)) |
Pawel Zarembski |
0:01f31e923fe2 | 176 | |
Pawel Zarembski |
0:01f31e923fe2 | 177 | # CRC the entire image |
Pawel Zarembski |
0:01f31e923fe2 | 178 | # |
Pawel Zarembski |
0:01f31e923fe2 | 179 | # This is required for all builds |
Pawel Zarembski |
0:01f31e923fe2 | 180 | |
Pawel Zarembski |
0:01f31e923fe2 | 181 | # Compute checksum over the range (don't include data at location of crc) |
Pawel Zarembski |
0:01f31e923fe2 | 182 | size = end - start + 1 |
Pawel Zarembski |
0:01f31e923fe2 | 183 | crc_size = size - 4 |
Pawel Zarembski |
0:01f31e923fe2 | 184 | data = new_hex_file.tobinarray(start=start, size=crc_size) |
Pawel Zarembski |
0:01f31e923fe2 | 185 | crc32 = binascii.crc32(data) & 0xFFFFFFFF |
Pawel Zarembski |
0:01f31e923fe2 | 186 | |
Pawel Zarembski |
0:01f31e923fe2 | 187 | # Write CRC to the file in little endian |
Pawel Zarembski |
0:01f31e923fe2 | 188 | new_hex_file[end - 3] = (crc32 >> 0) & 0xFF |
Pawel Zarembski |
0:01f31e923fe2 | 189 | new_hex_file[end - 2] = (crc32 >> 8) & 0xFF |
Pawel Zarembski |
0:01f31e923fe2 | 190 | new_hex_file[end - 1] = (crc32 >> 16) & 0xFF |
Pawel Zarembski |
0:01f31e923fe2 | 191 | new_hex_file[end - 0] = (crc32 >> 24) & 0xFF |
Pawel Zarembski |
0:01f31e923fe2 | 192 | |
Pawel Zarembski |
0:01f31e923fe2 | 193 | # Write out file(s) |
Pawel Zarembski |
0:01f31e923fe2 | 194 | new_hex_file.tofile(output_file_hex, 'hex') |
Pawel Zarembski |
0:01f31e923fe2 | 195 | new_hex_file.tofile(output_file_binary, 'bin') |
Pawel Zarembski |
0:01f31e923fe2 | 196 | with open(output_file_txt, 'w') as file_handle: |
Pawel Zarembski |
0:01f31e923fe2 | 197 | file_handle.write("0x%08x\r\n" % crc32) |
Pawel Zarembski |
0:01f31e923fe2 | 198 | |
Pawel Zarembski |
0:01f31e923fe2 | 199 | # Write out data as a C array |
Pawel Zarembski |
0:01f31e923fe2 | 200 | data = new_hex_file.tobinarray(start=start, size=size) |
Pawel Zarembski |
0:01f31e923fe2 | 201 | data = list(bytearray(data)) |
Pawel Zarembski |
0:01f31e923fe2 | 202 | output_data = ('static const unsigned int image_start = 0x%08x;\n' |
Pawel Zarembski |
0:01f31e923fe2 | 203 | 'static const unsigned int image_size = 0x%08x;\n' |
Pawel Zarembski |
0:01f31e923fe2 | 204 | 'static const char image_data[0x%08x] = {\n ' % |
Pawel Zarembski |
0:01f31e923fe2 | 205 | (start, size, size)) |
Pawel Zarembski |
0:01f31e923fe2 | 206 | for i, byte_val in enumerate(data): |
Pawel Zarembski |
0:01f31e923fe2 | 207 | output_data += '0x%02x' % byte_val + ', ' |
Pawel Zarembski |
0:01f31e923fe2 | 208 | if ((i + 1) % 0x20) == 0: |
Pawel Zarembski |
0:01f31e923fe2 | 209 | output_data += '\n ' |
Pawel Zarembski |
0:01f31e923fe2 | 210 | output_data += '};\n' |
Pawel Zarembski |
0:01f31e923fe2 | 211 | with open(output_file_c, 'w') as file_handle: |
Pawel Zarembski |
0:01f31e923fe2 | 212 | file_handle.write(output_data) |
Pawel Zarembski |
0:01f31e923fe2 | 213 | with open(output_file_c_generic, 'w') as file_handle: |
Pawel Zarembski |
0:01f31e923fe2 | 214 | file_handle.write(output_data) |
Pawel Zarembski |
0:01f31e923fe2 | 215 | |
Pawel Zarembski |
0:01f31e923fe2 | 216 | # Print info on operation |
Pawel Zarembski |
0:01f31e923fe2 | 217 | print("Start 0x%x, Length 0x%x, CRC32 0x%08x" % (start, size, crc32)) |
Pawel Zarembski |
0:01f31e923fe2 | 218 | |
Pawel Zarembski |
0:01f31e923fe2 | 219 | if start == 0x8000 or start == 0x10000 or start == 0x88000 or start == 0x0800C000: |
Pawel Zarembski |
0:01f31e923fe2 | 220 | if start == 0x0800C000: |
Pawel Zarembski |
0:01f31e923fe2 | 221 | # Adjust for ST-Link |
Pawel Zarembski |
0:01f31e923fe2 | 222 | pad_addr = start - 0x8000 |
Pawel Zarembski |
0:01f31e923fe2 | 223 | else: |
Pawel Zarembski |
0:01f31e923fe2 | 224 | pad_addr = start - 0x3000 |
Pawel Zarembski |
0:01f31e923fe2 | 225 | legacy_zero = start + 7 * 4 |
Pawel Zarembski |
0:01f31e923fe2 | 226 | legacy_size = 4 * 4 |
Pawel Zarembski |
0:01f31e923fe2 | 227 | legacy_hex_file = intelhex.IntelHex(new_hex_file) |
Pawel Zarembski |
0:01f31e923fe2 | 228 | for addr in range(legacy_zero, legacy_zero + legacy_size): |
Pawel Zarembski |
0:01f31e923fe2 | 229 | legacy_hex_file[addr] = 0 |
Pawel Zarembski |
0:01f31e923fe2 | 230 | data = legacy_hex_file.tobinarray(start=start, size=crc_size) |
Pawel Zarembski |
0:01f31e923fe2 | 231 | crc32 = binascii.crc32(data) & 0xFFFFFFFF |
Pawel Zarembski |
0:01f31e923fe2 | 232 | # Write CRC to the file in little endian |
Pawel Zarembski |
0:01f31e923fe2 | 233 | legacy_hex_file[end - 3] = (crc32 >> 0) & 0xFF |
Pawel Zarembski |
0:01f31e923fe2 | 234 | legacy_hex_file[end - 2] = (crc32 >> 8) & 0xFF |
Pawel Zarembski |
0:01f31e923fe2 | 235 | legacy_hex_file[end - 1] = (crc32 >> 16) & 0xFF |
Pawel Zarembski |
0:01f31e923fe2 | 236 | legacy_hex_file[end - 0] = (crc32 >> 24) & 0xFF |
Pawel Zarembski |
0:01f31e923fe2 | 237 | legacy_hex_file.tofile(output_file_legacy, 'bin') |
Pawel Zarembski |
0:01f31e923fe2 | 238 | with open(output_file_legacy_txt, 'w') as file_handle: |
Pawel Zarembski |
0:01f31e923fe2 | 239 | file_handle.write("0x%08x\r\n" % crc32) |
Pawel Zarembski |
0:01f31e923fe2 | 240 | offset_update.create_padded_image(output_file_legacy, |
Pawel Zarembski |
0:01f31e923fe2 | 241 | output_file_legacy_5000, |
Pawel Zarembski |
0:01f31e923fe2 | 242 | start, pad_addr, 0x40) |
Pawel Zarembski |
0:01f31e923fe2 | 243 | |
Pawel Zarembski |
0:01f31e923fe2 | 244 | if __name__ == '__main__': |
Pawel Zarembski |
0:01f31e923fe2 | 245 | parser = argparse.ArgumentParser(description='Post build tool for Board ID, Family ID, Target flash algo and CRC generation') |
Pawel Zarembski |
0:01f31e923fe2 | 246 | parser.add_argument("input", type=str, help="Hex or bin file to read from.") |
Pawel Zarembski |
0:01f31e923fe2 | 247 | parser.add_argument("output", type=str, |
Pawel Zarembski |
0:01f31e923fe2 | 248 | help="Output base file name to write crc, board_id and family_id.") |
Pawel Zarembski |
0:01f31e923fe2 | 249 | parser.add_argument("--board-id", type=str, |
Pawel Zarembski |
0:01f31e923fe2 | 250 | help="board id to for the target in hex") |
Pawel Zarembski |
0:01f31e923fe2 | 251 | parser.add_argument("--family-id", type=str, |
Pawel Zarembski |
0:01f31e923fe2 | 252 | help="family id to for the target in hex") |
Pawel Zarembski |
0:01f31e923fe2 | 253 | parser.add_argument("--bin-offset", type=str, |
Pawel Zarembski |
0:01f31e923fe2 | 254 | help="binary offset in hex can be supplied if input is bin") |
Pawel Zarembski |
0:01f31e923fe2 | 255 | parser.add_argument("--flash-algo-file", type=str, |
Pawel Zarembski |
0:01f31e923fe2 | 256 | help="Elf, axf, or flm to extract flash algo from") |
Pawel Zarembski |
0:01f31e923fe2 | 257 | parser.add_argument("--target-ram-start", type=str, |
Pawel Zarembski |
0:01f31e923fe2 | 258 | help="Lowest address of target RAM for flash algo in hex") |
Pawel Zarembski |
0:01f31e923fe2 | 259 | parser.add_argument("--target-ram-end", type=str, |
Pawel Zarembski |
0:01f31e923fe2 | 260 | help="Highest address of target RAM for flash algo in hex") |
Pawel Zarembski |
0:01f31e923fe2 | 261 | parser.add_argument("--flash-blob-entry", type=str, default="0x20000000", |
Pawel Zarembski |
0:01f31e923fe2 | 262 | help="Entry point of flash algo in the target") |
Pawel Zarembski |
0:01f31e923fe2 | 263 | args = parser.parse_args() |
Pawel Zarembski |
0:01f31e923fe2 | 264 | post_build_script(args.input, args.output, args.board_id, args.family_id, args.bin_offset, args.flash_algo_file, args.target_ram_start, args.target_ram_end, args.flash_blob_entry) |