mbed-os/tools/add_fib.py

186 lines
7.1 KiB
Python

#!/usr/bin/env python
# CMSIS-DAP Interface Firmware
# Copyright (c) 2009-2013 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from __future__ import absolute_import
from __future__ import print_function
import argparse
import itertools
import binascii
import intelhex
import os
FIB_BASE = 0x2000
FLASH_BASE = 0x3000
FW_REV = 0x01000100 #todo: determine if revision can be passed from yotta
def ranges(i):
for _, b in itertools.groupby(enumerate(i), lambda x_y: x_y[1] - x_y[0]):
b = list(b)
yield b[0][1], b[-1][1]
def add_fib_at_start(arginput):
#parser = argparse.ArgumentParser(description='Firmware Information Block generation script')
#parser.add_argument("input", type=str, help="bin file to read from.")
#args = parser.parse_args()
#input_file = args.input + "_orig.bin"
#output_file = args.input #use same name, does not include extension
#file_name_hex = args.input + ".hex"
#file_name_bin = args.input + ".bin"
print("inputfile", arginput)
input_file = arginput + ".bin"
output_file = arginput #use same name, does not include extension
file_name_hex = arginput + "_fib.hex"
file_name_bin = arginput + ".bin"
print("inputfile", input_file)
print("output_file", output_file)
print("file_name_hex", file_name_hex)
print("file_name_bin", file_name_bin)
# Import intelhex if avaialable, otherwise fail
try:
from intelhex import IntelHex
except:
return fail('error: You do not have \'intelhex\' installed. Please run \'pip install intelhex\' then retry.')
# Read in hex file
input_hex_file = intelhex.IntelHex()
input_hex_file.padding = 0x00
input_hex_file.loadbin(input_file, offset=FLASH_BASE)
output_hex_file = intelhex.IntelHex()
output_hex_file.padding = 0x00
# Get the starting and ending address
addresses = input_hex_file.addresses()
addresses.sort()
start_end_pairs = list(ranges(addresses))
regions = len(start_end_pairs)
if regions == 1:
start, end = start_end_pairs[0]
else:
start = min(min(start_end_pairs))
end = max(max(start_end_pairs))
assert start >= FLASH_BASE, ("Error - start 0x%x less than begining of user flash area" %start)
# Compute checksum over the range (don't include data at location of crc)
size = end - start + 1
data = input_hex_file.tobinarray(start=start, size=size)
crc32 = binascii.crc32(data) & 0xFFFFFFFF
fw_rev = FW_REV
checksum = (start + size + crc32 + fw_rev) & 0xFFFFFFFF
print("Writing FIB: base 0x%08X, size 0x%08X, crc32 0x%08X, fw rev 0x%08X, checksum 0x%08X" % (start, size, crc32, fw_rev, checksum))
#expected initial values used by daplink to validate that it is a valid bin file
#added as dummy values in this file because the fib area preceeds the application area
#the bootloader will ignore these dummy values
# 00 is stack pointer (RAM address)
# 04 is Reset vector (FLASH address)
# 08 NMI_Handler (FLASH address)
# 0C HardFault_Handler(FLASH address)
# 10 dummy
dummy_sp = 0x3FFFFC00
dummy_reset_vector = 0x00003625
dummy_nmi_handler = 0x00003761
dummy_hardfault_handler = 0x00003691
dummy_blank = 0x00000000
#expected fib structure
#typedef struct fib{
#uint32_t base; /**< Base offset of firmware, indicating what flash the firmware is in. (will never be 0x11111111) */
#uint32_t size; /**< Size of the firmware */
#uint32_t crc; /**< CRC32 for firmware correctness check */
#uint32_t rev; /**< Revision number */
#uint32_t checksum; /**< Check-sum of information block */
#}fib_t, *fib_pt;
fib_start = FIB_BASE
dummy_fib_size = 20
fib_size = 20
user_code_start = FLASH_BASE
# Write FIB to the file in little endian
output_hex_file[fib_start + 0] = (dummy_sp >> 0) & 0xFF
output_hex_file[fib_start + 1] = (dummy_sp >> 8) & 0xFF
output_hex_file[fib_start + 2] = (dummy_sp >> 16) & 0xFF
output_hex_file[fib_start + 3] = (dummy_sp >> 24) & 0xFF
output_hex_file[fib_start + 4] = (dummy_reset_vector >> 0) & 0xFF
output_hex_file[fib_start + 5] = (dummy_reset_vector >> 8) & 0xFF
output_hex_file[fib_start + 6] = (dummy_reset_vector >> 16) & 0xFF
output_hex_file[fib_start + 7] = (dummy_reset_vector >> 24) & 0xFF
output_hex_file[fib_start + 8] = (dummy_nmi_handler >> 0) & 0xFF
output_hex_file[fib_start + 9] = (dummy_nmi_handler >> 8) & 0xFF
output_hex_file[fib_start + 10] = (dummy_nmi_handler >> 16) & 0xFF
output_hex_file[fib_start + 11] = (dummy_nmi_handler >> 24) & 0xFF
output_hex_file[fib_start + 12] = (dummy_hardfault_handler >> 0) & 0xFF
output_hex_file[fib_start + 13] = (dummy_hardfault_handler >> 8) & 0xFF
output_hex_file[fib_start + 14] = (dummy_hardfault_handler >> 16) & 0xFF
output_hex_file[fib_start + 15] = (dummy_hardfault_handler >> 24) & 0xFF
output_hex_file[fib_start + 16] = (dummy_blank >> 0) & 0xFF
output_hex_file[fib_start + 17] = (dummy_blank >> 8) & 0xFF
output_hex_file[fib_start + 18] = (dummy_blank >> 16) & 0xFF
output_hex_file[fib_start + 19] = (dummy_blank >> 24) & 0xFF
# Write FIB to the file in little endian
output_hex_file[fib_start + 20] = (start >> 0) & 0xFF
output_hex_file[fib_start + 21] = (start >> 8) & 0xFF
output_hex_file[fib_start + 22] = (start >> 16) & 0xFF
output_hex_file[fib_start + 23] = (start >> 24) & 0xFF
output_hex_file[fib_start + 24] = (size >> 0) & 0xFF
output_hex_file[fib_start + 25] = (size >> 8) & 0xFF
output_hex_file[fib_start + 26] = (size >> 16) & 0xFF
output_hex_file[fib_start + 27] = (size >> 24) & 0xFF
output_hex_file[fib_start + 28] = (crc32 >> 0) & 0xFF
output_hex_file[fib_start + 29] = (crc32 >> 8) & 0xFF
output_hex_file[fib_start + 30] = (crc32 >> 16) & 0xFF
output_hex_file[fib_start + 31] = (crc32 >> 24) & 0xFF
output_hex_file[fib_start + 32] = (fw_rev >> 0) & 0xFF
output_hex_file[fib_start + 33] = (fw_rev >> 8) & 0xFF
output_hex_file[fib_start + 34] = (fw_rev >> 16) & 0xFF
output_hex_file[fib_start + 35] = (fw_rev >> 24) & 0xFF
output_hex_file[fib_start + 36] = (checksum >> 0) & 0xFF
output_hex_file[fib_start + 37] = (checksum >> 8) & 0xFF
output_hex_file[fib_start + 38] = (checksum >> 16) & 0xFF
output_hex_file[fib_start + 39] = (checksum >> 24) & 0xFF
#pad the rest of the file
for i in range(fib_start + dummy_fib_size + fib_size, user_code_start):
output_hex_file[i] = 0xFF
#merge two hex files
output_hex_file.merge(input_hex_file, overlap='error')
# Write out file(s)
output_hex_file.tofile(file_name_hex, 'hex')
output_hex_file.tofile(file_name_bin, 'bin')