Mbed Cloud Connect for Ethernet Platforms

Fork of example-Ethernet-mbed-Cloud-connect by ST

Committer:
davwal04@E108444.Emea.Arm.com
Date:
Mon Jun 04 17:03:57 2018 +0100
Branch:
update-1.3.0
Revision:
12:ca4ab5d7e52b
Parent:
6:2d0e0866f2e7
Fixed SOTP address

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 1 #!/usr/bin/env python
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 2
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 3 ## ----------------------------------------------------------------------------
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 4 ## Copyright 2016-2017 ARM Ltd.
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 5 ##
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 6 ## SPDX-License-Identifier: Apache-2.0
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 7 ##
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 8 ## Licensed under the Apache License, Version 2.0 (the "License");
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 9 ## you may not use this file except in compliance with the License.
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 10 ## You may obtain a copy of the License at
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 11 ##
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 12 ## http://www.apache.org/licenses/LICENSE-2.0
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 13 ##
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 14 ## Unless required by applicable law or agreed to in writing, software
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 15 ## distributed under the License is distributed on an "AS IS" BASIS,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 16 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 17 ## See the License for the specific language governing permissions and
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 18 ## limitations under the License.
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 19 ## ----------------------------------------------------------------------------
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 20
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 21 from os import path
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 22 import json
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 23 import hashlib, zlib, struct
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 24 import time
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 25 import sys
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 26 from intelhex import IntelHex
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 27
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 28 '''
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 29 define FIRMWARE_HEADER_MAGIC 0x5a51b3d4UL
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 30 define FIRMWARE_HEADER_VERSION 2
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 31 define ARM_UC_SHA512_SIZE (512/8)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 32 define ARM_UC_GUID_SIZE (128/8)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 33 typedef struct _arm_uc_internal_header_t
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 34 {
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 35 /* Metadata-header specific magic code */
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 36 uint32_t headerMagic;
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 37
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 38 /* Revision number for metadata header. */
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 39 uint32_t headerVersion;
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 40
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 41 /* Version number accompanying the firmware. Larger numbers imply more
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 42 recent and preferred versions. This is used for determining the
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 43 selection order when multiple versions are available. For downloaded
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 44 firmware the manifest timestamp is used as the firmware version.
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 45 */
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 46 uint64_t firmwareVersion;
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 47
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 48 /* Total space (in bytes) occupied by the firmware BLOB. */
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 49 uint64_t firmwareSize;
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 50
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 51 /* Firmware hash calculated over the firmware size. Should match the hash
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 52 generated by standard command line tools, e.g., shasum on Linux/Mac.
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 53 */
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 54 uint8_t firmwareHash[ARM_UC_SHA512_SIZE];
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 55
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 56 /* The ID for the update campaign that resulted in the firmware update.
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 57 */
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 58 uint8_t campaign[ARM_UC_GUID_SIZE];
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 59
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 60 /* Size of the firmware signature. Must be 0 if no signature is supplied. */
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 61 uint32_t firmwareSignatureSize;
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 62
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 63 /* Header 32 bit CRC. Calculated over the entire header, including the CRC
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 64 field, but with the CRC set to zero.
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 65 */
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 66 uint32_t headerCRC;
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 67
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 68 /* Optional firmware signature. Hashing algorithm should be the same as the
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 69 one used for the firmware hash. The firmwareSignatureSize must be set.
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 70 */
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 71 uint8_t firmwareSignature[0];
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 72 } arm_uc_internal_header_t;
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 73 '''
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 74
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 75 # define defaults to go into the metadata header
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 76 SIZEOF_SHA512 = int(512/8)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 77 SIZEOF_GUID = int(128/8)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 78 FIRMWARE_HEADER_MAGIC = 0x5a51b3d4
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 79 FIRMWARE_HEADER_VERSION = 2
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 80 header_format = ">2I2Q{}s{}s2I".format(SIZEOF_SHA512, SIZEOF_GUID)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 81
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 82 if sys.version_info < (3,):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 83 def b(x):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 84 return bytearray(x)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 85 else:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 86 def b(x):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 87 return x
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 88
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 89 def create_header(app_blob, firmwareVersion):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 90 # calculate the hash of the application
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 91 firmwareHash = hashlib.sha256(app_blob).digest()
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 92
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 93 # calculate the total size which is defined as the application size + metadata header
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 94 firmwareSize = len(app_blob)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 95
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 96 # set campaign GUID to 0
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 97 campaign = b'\00'
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 98
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 99 # signature not supported, set size to 0
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 100 signatureSize = 0
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 101
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 102 print ('imageSize: {}'.format(firmwareSize))
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 103 print ('imageHash: {}'.format(''.join(['{:0>2x}'.format(c) for c in b(firmwareHash)])))
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 104 print ('imageversion: {}'.format(firmwareVersion))
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 105
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 106 # construct struct for CRC calculation
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 107 headerCRC = 0
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 108 FirmwareHeader = struct.pack(header_format,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 109 FIRMWARE_HEADER_MAGIC,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 110 FIRMWARE_HEADER_VERSION,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 111 firmwareVersion,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 112 firmwareSize,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 113 firmwareHash,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 114 campaign,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 115 signatureSize,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 116 headerCRC)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 117
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 118 # calculate checksum over header, including signatureSize but without headerCRC
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 119 headerCRC = zlib.crc32(FirmwareHeader[:-4]) & 0xffffffff
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 120
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 121 # Pack the data into a binary blob
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 122 FirmwareHeader = struct.pack(header_format,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 123 FIRMWARE_HEADER_MAGIC,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 124 FIRMWARE_HEADER_VERSION,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 125 firmwareVersion,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 126 firmwareSize,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 127 firmwareHash,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 128 campaign,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 129 signatureSize,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 130 headerCRC)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 131
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 132 return FirmwareHeader
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 133
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 134
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 135 def combine(bootloader_fn, app_fn, app_addr, hdr_addr, bootloader_addr, output_fn, version, no_bootloader):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 136 ih = IntelHex()
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 137
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 138 bootloader_format = bootloader_fn.split('.')[-1]
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 139
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 140 # write the bootloader
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 141 if not no_bootloader:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 142 print("Using bootloader %s" % bootloader_fn)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 143 if bootloader_format == 'hex':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 144 print("Loading bootloader from hex file.")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 145 ih.fromfile(bootloader_fn, format=bootloader_format)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 146 elif bootloader_format == 'bin':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 147 print("Loading bootloader to address 0x%08x." % bootloader_addr)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 148 ih.loadbin(bootloader_fn, offset=bootloader_addr)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 149 else:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 150 print('Bootloader format can only be .bin or .hex')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 151 exit(-1)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 152
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 153 # write firmware header
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 154 app_format=app_fn.split('.')[-1]
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 155 if app_format == 'bin':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 156 with open(app_fn, 'rb') as fd:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 157 app_blob = fd.read()
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 158 elif app_format == 'hex':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 159 application = IntelHex(app_fn)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 160 app_blob = application.tobinstr()
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 161 FirmwareHeader = create_header(app_blob, version)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 162 print("Writing header to address 0x%08x." % hdr_addr)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 163 ih.puts(hdr_addr, FirmwareHeader)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 164
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 165 # write the application
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 166 if app_format == 'bin':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 167 print("Loading application to address 0x%08x." % app_addr)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 168 ih.loadbin(app_fn, offset=app_addr)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 169 elif app_format == 'hex':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 170 print("Loading application from hex file")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 171 ih.fromfile(app_fn, format=app_format)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 172
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 173 # output to file
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 174 ih.tofile(output_fn, format=output_fn.split('.')[-1])
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 175
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 176
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 177 if __name__ == '__main__':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 178 from glob import glob
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 179 import argparse
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 180
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 181 parser = argparse.ArgumentParser(
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 182 description='Combine bootloader with application adding metadata header.')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 183
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 184 def addr_arg(s):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 185 if not isinstance(s, int):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 186 s = eval(s)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 187
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 188 return s
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 189
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 190 bin_map = {
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 191 'k64f': {
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 192 'mem_start': '0x0'
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 193 },
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 194 'ublox_evk_odin_w2': {
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 195 'mem_start': '0x08000000'
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 196 },
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 197 'nucleo_f429zi': {
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 198 'mem_start': '0x08000000'
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 199 }
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 200 }
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 201
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 202 curdir = path.dirname(path.abspath(__file__))
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 203
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 204 def parse_mbed_app_addr(mcu, key):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 205 mem_start = bin_map[mcu]["mem_start"]
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 206 with open(path.join(curdir, "..", "mbed_app.json")) as fd:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 207 mbed_json = json.load(fd)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 208 addr = mbed_json["target_overrides"][mcu.upper()][key]
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 209 return addr_arg(addr)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 210
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 211 # specify arguments
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 212 parser.add_argument('-m', '--mcu', type=lambda s : s.lower().replace("-","_"), required=False,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 213 help='mcu', choices=bin_map.keys())
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 214 parser.add_argument('-b', '--bootloader', type=argparse.FileType('rb'), required=False,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 215 help='path to the bootloader binary')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 216 parser.add_argument('-a', '--app', type=argparse.FileType('rb'), required=True,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 217 help='path to application binary')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 218 parser.add_argument('-c', '--app-addr', type=addr_arg, required=False,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 219 help='address of the application')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 220 parser.add_argument('-d', '--header-addr', type=addr_arg, required=False,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 221 help='address of the firmware metadata header')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 222 parser.add_argument('-o', '--output', type=argparse.FileType('wb'), required=True,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 223 help='output combined file path')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 224 parser.add_argument('-s', '--set-version', type=int, required=False,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 225 help='set version number', default=int(time.time()))
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 226 parser.add_argument('-nb', '--no-bootloader',action='store_true', required=False,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 227 help='Produce output without bootloader. The output only '+
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 228 'contains header + app. requires hex output format')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 229
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 230 # workaround for http://bugs.python.org/issue9694
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 231 parser._optionals.title = "arguments"
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 232
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 233 # get and validate arguments
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 234 args = parser.parse_args()
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 235
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 236 # validate the output format
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 237 f = args.output.name.split('.')[-1]
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 238 if f == 'hex':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 239 output_format = 'hex'
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 240 elif f == 'bin':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 241 output_format = 'bin'
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 242 else:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 243 print('Output format can only be .bin or .hex')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 244 exit(-1)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 245
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 246 # validate no-bootloader option
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 247 if args.no_bootloader and output_format == 'bin':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 248 print('--no-bootloader option requires the output format to be .hex')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 249 exit(-1)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 250
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 251 # validate that we can find a bootloader or no_bootloader is specified
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 252 bootloader = None
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 253 if not args.no_bootloader:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 254 if args.mcu and not args.bootloader:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 255 bl_list = glob("tools/mbed-bootloader-{}-*".format(args.mcu))
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 256 if len(bl_list) == 0:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 257 print("Specified MCU does not have a binary in this location " + \
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 258 "Please specify bootloader location with -b")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 259 exit(-1)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 260 elif len(bl_list) > 1:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 261 print("Specified MCU have more than one binary in this location " + \
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 262 "Please specify bootloader location with -b")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 263 print(bl_list)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 264 exit(-1)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 265 else:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 266 fname = bl_list[0]
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 267 bootloader = open(fname, 'rb')
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 268 elif args.bootloader:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 269 bootloader = args.bootloader
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 270 elif not (args.mcu or args.bootloader):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 271 print("Please specify bootloader location -b or MCU -m")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 272 exit(-1)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 273
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 274 # get the path of bootloader, application and output
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 275 if bootloader:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 276 bootloader_fn = path.abspath(bootloader.name)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 277 bootloader.close()
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 278 else:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 279 bootloader_fn = ''
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 280
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 281 if bootloader_fn.split('.')[-1] != 'hex' and not args.mcu:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 282 print("Please provide a bootloader in hex format or specify MCU -m")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 283 exit(-1)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 284
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 285 app_fn = path.abspath(args.app.name)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 286 args.app.close()
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 287 output_fn = path.abspath(args.output.name)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 288 args.output.close()
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 289
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 290 # Use specified addresses or default if none are provided
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 291 app_format = app_fn.split('.')[-1]
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 292 if(not (args.mcu or args.app_addr or app_format == 'hex')):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 293 print("Please specify app address or MCU")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 294 exit(-1)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 295 if app_format != 'hex':
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 296 app_addr = args.app_addr or parse_mbed_app_addr(args.mcu, "target.mbed_app_start")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 297 else:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 298 app_addr = None
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 299
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 300 if args.mcu:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 301 mem_start = addr_arg(bin_map[args.mcu]["mem_start"])
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 302 else:
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 303 mem_start = 0
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 304
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 305 if(not (args.mcu or args.header_addr)):
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 306 print("Please specify header address or MCU")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 307 exit(-1)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 308 header_addr = args.header_addr or parse_mbed_app_addr(args.mcu, "update-client.application-details")
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 309
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 310 # combine application and bootloader adding metadata info
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 311 combine(bootloader_fn, app_fn, app_addr, header_addr, mem_start,
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 312 output_fn, args.set_version, args.no_bootloader)
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 313
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 314 # print the output file path
davwal04@E108444.Emea.Arm.com 6:2d0e0866f2e7 315 print('Combined binary:' + output_fn)