Simple Mbed Cloud client application using features of K64 & K66 including Ethernet and SD Card
Fork of mbed-cloud-example_K64_K66 by
DEPRECATED
This example application is not maintained and not recommended. It uses an old version of Mbed OS, Pelion DM, and Arm toolchain. It doesn't work with Mbed Studio.
Please use: https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-pelion/
combine_bootloader_with_app.py@0:e13a8a944e25, 2018-02-13 (annotated)
- Committer:
- MarceloSalazar
- Date:
- Tue Feb 13 10:07:23 2018 +0000
- Revision:
- 0:e13a8a944e25
First version
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| MarceloSalazar | 0:e13a8a944e25 | 1 | #!/usr/bin/env python |
| MarceloSalazar | 0:e13a8a944e25 | 2 | |
| MarceloSalazar | 0:e13a8a944e25 | 3 | ## ---------------------------------------------------------------------------- |
| MarceloSalazar | 0:e13a8a944e25 | 4 | ## Copyright 2016-2017 ARM Ltd. |
| MarceloSalazar | 0:e13a8a944e25 | 5 | ## |
| MarceloSalazar | 0:e13a8a944e25 | 6 | ## SPDX-License-Identifier: Apache-2.0 |
| MarceloSalazar | 0:e13a8a944e25 | 7 | ## |
| MarceloSalazar | 0:e13a8a944e25 | 8 | ## Licensed under the Apache License, Version 2.0 (the "License"); |
| MarceloSalazar | 0:e13a8a944e25 | 9 | ## you may not use this file except in compliance with the License. |
| MarceloSalazar | 0:e13a8a944e25 | 10 | ## You may obtain a copy of the License at |
| MarceloSalazar | 0:e13a8a944e25 | 11 | ## |
| MarceloSalazar | 0:e13a8a944e25 | 12 | ## http://www.apache.org/licenses/LICENSE-2.0 |
| MarceloSalazar | 0:e13a8a944e25 | 13 | ## |
| MarceloSalazar | 0:e13a8a944e25 | 14 | ## Unless required by applicable law or agreed to in writing, software |
| MarceloSalazar | 0:e13a8a944e25 | 15 | ## distributed under the License is distributed on an "AS IS" BASIS, |
| MarceloSalazar | 0:e13a8a944e25 | 16 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| MarceloSalazar | 0:e13a8a944e25 | 17 | ## See the License for the specific language governing permissions and |
| MarceloSalazar | 0:e13a8a944e25 | 18 | ## limitations under the License. |
| MarceloSalazar | 0:e13a8a944e25 | 19 | ## ---------------------------------------------------------------------------- |
| MarceloSalazar | 0:e13a8a944e25 | 20 | |
| MarceloSalazar | 0:e13a8a944e25 | 21 | from os import path |
| MarceloSalazar | 0:e13a8a944e25 | 22 | import json |
| MarceloSalazar | 0:e13a8a944e25 | 23 | import hashlib, zlib, struct |
| MarceloSalazar | 0:e13a8a944e25 | 24 | import time |
| MarceloSalazar | 0:e13a8a944e25 | 25 | import sys |
| MarceloSalazar | 0:e13a8a944e25 | 26 | |
| MarceloSalazar | 0:e13a8a944e25 | 27 | ''' |
| MarceloSalazar | 0:e13a8a944e25 | 28 | define FIRMWARE_HEADER_MAGIC 0x5a51b3d4UL |
| MarceloSalazar | 0:e13a8a944e25 | 29 | define FIRMWARE_HEADER_VERSION 2 |
| MarceloSalazar | 0:e13a8a944e25 | 30 | define ARM_UC_SHA512_SIZE (512/8) |
| MarceloSalazar | 0:e13a8a944e25 | 31 | define ARM_UC_GUID_SIZE (128/8) |
| MarceloSalazar | 0:e13a8a944e25 | 32 | typedef struct _arm_uc_internal_header_t |
| MarceloSalazar | 0:e13a8a944e25 | 33 | { |
| MarceloSalazar | 0:e13a8a944e25 | 34 | /* Metadata-header specific magic code */ |
| MarceloSalazar | 0:e13a8a944e25 | 35 | uint32_t headerMagic; |
| MarceloSalazar | 0:e13a8a944e25 | 36 | |
| MarceloSalazar | 0:e13a8a944e25 | 37 | /* Revision number for metadata header. */ |
| MarceloSalazar | 0:e13a8a944e25 | 38 | uint32_t headerVersion; |
| MarceloSalazar | 0:e13a8a944e25 | 39 | |
| MarceloSalazar | 0:e13a8a944e25 | 40 | /* Version number accompanying the firmware. Larger numbers imply more |
| MarceloSalazar | 0:e13a8a944e25 | 41 | recent and preferred versions. This is used for determining the |
| MarceloSalazar | 0:e13a8a944e25 | 42 | selection order when multiple versions are available. For downloaded |
| MarceloSalazar | 0:e13a8a944e25 | 43 | firmware the manifest timestamp is used as the firmware version. |
| MarceloSalazar | 0:e13a8a944e25 | 44 | */ |
| MarceloSalazar | 0:e13a8a944e25 | 45 | uint64_t firmwareVersion; |
| MarceloSalazar | 0:e13a8a944e25 | 46 | |
| MarceloSalazar | 0:e13a8a944e25 | 47 | /* Total space (in bytes) occupied by the firmware BLOB. */ |
| MarceloSalazar | 0:e13a8a944e25 | 48 | uint64_t firmwareSize; |
| MarceloSalazar | 0:e13a8a944e25 | 49 | |
| MarceloSalazar | 0:e13a8a944e25 | 50 | /* Firmware hash calculated over the firmware size. Should match the hash |
| MarceloSalazar | 0:e13a8a944e25 | 51 | generated by standard command line tools, e.g., shasum on Linux/Mac. |
| MarceloSalazar | 0:e13a8a944e25 | 52 | */ |
| MarceloSalazar | 0:e13a8a944e25 | 53 | uint8_t firmwareHash[ARM_UC_SHA512_SIZE]; |
| MarceloSalazar | 0:e13a8a944e25 | 54 | |
| MarceloSalazar | 0:e13a8a944e25 | 55 | /* The ID for the update campaign that resulted in the firmware update. |
| MarceloSalazar | 0:e13a8a944e25 | 56 | */ |
| MarceloSalazar | 0:e13a8a944e25 | 57 | uint8_t campaign[ARM_UC_GUID_SIZE]; |
| MarceloSalazar | 0:e13a8a944e25 | 58 | |
| MarceloSalazar | 0:e13a8a944e25 | 59 | /* Size of the firmware signature. Must be 0 if no signature is supplied. */ |
| MarceloSalazar | 0:e13a8a944e25 | 60 | uint32_t firmwareSignatureSize; |
| MarceloSalazar | 0:e13a8a944e25 | 61 | |
| MarceloSalazar | 0:e13a8a944e25 | 62 | /* Header 32 bit CRC. Calculated over the entire header, including the CRC |
| MarceloSalazar | 0:e13a8a944e25 | 63 | field, but with the CRC set to zero. |
| MarceloSalazar | 0:e13a8a944e25 | 64 | */ |
| MarceloSalazar | 0:e13a8a944e25 | 65 | uint32_t headerCRC; |
| MarceloSalazar | 0:e13a8a944e25 | 66 | |
| MarceloSalazar | 0:e13a8a944e25 | 67 | /* Optional firmware signature. Hashing algorithm should be the same as the |
| MarceloSalazar | 0:e13a8a944e25 | 68 | one used for the firmware hash. The firmwareSignatureSize must be set. |
| MarceloSalazar | 0:e13a8a944e25 | 69 | */ |
| MarceloSalazar | 0:e13a8a944e25 | 70 | uint8_t firmwareSignature[0]; |
| MarceloSalazar | 0:e13a8a944e25 | 71 | } arm_uc_internal_header_t; |
| MarceloSalazar | 0:e13a8a944e25 | 72 | ''' |
| MarceloSalazar | 0:e13a8a944e25 | 73 | |
| MarceloSalazar | 0:e13a8a944e25 | 74 | # define defaults to go into the metadata header |
| MarceloSalazar | 0:e13a8a944e25 | 75 | SIZEOF_SHA512 = int(512/8) |
| MarceloSalazar | 0:e13a8a944e25 | 76 | SIZEOF_GUID = int(128/8) |
| MarceloSalazar | 0:e13a8a944e25 | 77 | FIRMWARE_HEADER_MAGIC = 0x5a51b3d4 |
| MarceloSalazar | 0:e13a8a944e25 | 78 | FIRMWARE_HEADER_VERSION = 2 |
| MarceloSalazar | 0:e13a8a944e25 | 79 | header_format = ">2I2Q{}s{}s2I".format(SIZEOF_SHA512, SIZEOF_GUID) |
| MarceloSalazar | 0:e13a8a944e25 | 80 | |
| MarceloSalazar | 0:e13a8a944e25 | 81 | if sys.version_info < (3,): |
| MarceloSalazar | 0:e13a8a944e25 | 82 | def b(x): |
| MarceloSalazar | 0:e13a8a944e25 | 83 | return bytearray(x) |
| MarceloSalazar | 0:e13a8a944e25 | 84 | else: |
| MarceloSalazar | 0:e13a8a944e25 | 85 | def b(x): |
| MarceloSalazar | 0:e13a8a944e25 | 86 | return x |
| MarceloSalazar | 0:e13a8a944e25 | 87 | |
| MarceloSalazar | 0:e13a8a944e25 | 88 | def create_header(app_blob, firmwareVersion): |
| MarceloSalazar | 0:e13a8a944e25 | 89 | # calculate the hash of the application |
| MarceloSalazar | 0:e13a8a944e25 | 90 | firmwareHash = hashlib.sha256(app_blob).digest() |
| MarceloSalazar | 0:e13a8a944e25 | 91 | |
| MarceloSalazar | 0:e13a8a944e25 | 92 | # calculate the total size which is defined as the application size + metadata header |
| MarceloSalazar | 0:e13a8a944e25 | 93 | firmwareSize = len(app_blob) |
| MarceloSalazar | 0:e13a8a944e25 | 94 | |
| MarceloSalazar | 0:e13a8a944e25 | 95 | # set campaign GUID to 0 |
| MarceloSalazar | 0:e13a8a944e25 | 96 | campaign = b'\00' |
| MarceloSalazar | 0:e13a8a944e25 | 97 | |
| MarceloSalazar | 0:e13a8a944e25 | 98 | # signature not supported, set size to 0 |
| MarceloSalazar | 0:e13a8a944e25 | 99 | signatureSize = 0 |
| MarceloSalazar | 0:e13a8a944e25 | 100 | |
| MarceloSalazar | 0:e13a8a944e25 | 101 | print ('imageSize: {}'.format(firmwareSize)) |
| MarceloSalazar | 0:e13a8a944e25 | 102 | print ('imageHash: {}'.format(''.join(['{:0>2x}'.format(c) for c in b(firmwareHash)]))) |
| MarceloSalazar | 0:e13a8a944e25 | 103 | print ('imageversion: {}'.format(firmwareVersion)) |
| MarceloSalazar | 0:e13a8a944e25 | 104 | |
| MarceloSalazar | 0:e13a8a944e25 | 105 | # construct struct for CRC calculation |
| MarceloSalazar | 0:e13a8a944e25 | 106 | headerCRC = 0 |
| MarceloSalazar | 0:e13a8a944e25 | 107 | FirmwareHeader = struct.pack(header_format, |
| MarceloSalazar | 0:e13a8a944e25 | 108 | FIRMWARE_HEADER_MAGIC, |
| MarceloSalazar | 0:e13a8a944e25 | 109 | FIRMWARE_HEADER_VERSION, |
| MarceloSalazar | 0:e13a8a944e25 | 110 | firmwareVersion, |
| MarceloSalazar | 0:e13a8a944e25 | 111 | firmwareSize, |
| MarceloSalazar | 0:e13a8a944e25 | 112 | firmwareHash, |
| MarceloSalazar | 0:e13a8a944e25 | 113 | campaign, |
| MarceloSalazar | 0:e13a8a944e25 | 114 | signatureSize, |
| MarceloSalazar | 0:e13a8a944e25 | 115 | headerCRC) |
| MarceloSalazar | 0:e13a8a944e25 | 116 | |
| MarceloSalazar | 0:e13a8a944e25 | 117 | # calculate checksum over header, including signatureSize but without headerCRC |
| MarceloSalazar | 0:e13a8a944e25 | 118 | headerCRC = zlib.crc32(FirmwareHeader[:-4]) & 0xffffffff |
| MarceloSalazar | 0:e13a8a944e25 | 119 | |
| MarceloSalazar | 0:e13a8a944e25 | 120 | # Pack the data into a binary blob |
| MarceloSalazar | 0:e13a8a944e25 | 121 | FirmwareHeader = struct.pack(header_format, |
| MarceloSalazar | 0:e13a8a944e25 | 122 | FIRMWARE_HEADER_MAGIC, |
| MarceloSalazar | 0:e13a8a944e25 | 123 | FIRMWARE_HEADER_VERSION, |
| MarceloSalazar | 0:e13a8a944e25 | 124 | firmwareVersion, |
| MarceloSalazar | 0:e13a8a944e25 | 125 | firmwareSize, |
| MarceloSalazar | 0:e13a8a944e25 | 126 | firmwareHash, |
| MarceloSalazar | 0:e13a8a944e25 | 127 | campaign, |
| MarceloSalazar | 0:e13a8a944e25 | 128 | signatureSize, |
| MarceloSalazar | 0:e13a8a944e25 | 129 | headerCRC) |
| MarceloSalazar | 0:e13a8a944e25 | 130 | |
| MarceloSalazar | 0:e13a8a944e25 | 131 | return FirmwareHeader |
| MarceloSalazar | 0:e13a8a944e25 | 132 | |
| MarceloSalazar | 0:e13a8a944e25 | 133 | |
| MarceloSalazar | 0:e13a8a944e25 | 134 | def combine(bootloader_blob, app_blob, app_offset, hdr_offset, output, version): |
| MarceloSalazar | 0:e13a8a944e25 | 135 | |
| MarceloSalazar | 0:e13a8a944e25 | 136 | # create header to go with the application binary |
| MarceloSalazar | 0:e13a8a944e25 | 137 | FirmwareHeader = create_header(app_blob, version) |
| MarceloSalazar | 0:e13a8a944e25 | 138 | |
| MarceloSalazar | 0:e13a8a944e25 | 139 | # write the bootloader first |
| MarceloSalazar | 0:e13a8a944e25 | 140 | offset = 0 |
| MarceloSalazar | 0:e13a8a944e25 | 141 | output.write(bootloader_blob) |
| MarceloSalazar | 0:e13a8a944e25 | 142 | offset += len(bootloader_blob) |
| MarceloSalazar | 0:e13a8a944e25 | 143 | |
| MarceloSalazar | 0:e13a8a944e25 | 144 | # write the padding between bootloader and firmware header |
| MarceloSalazar | 0:e13a8a944e25 | 145 | output.write(b'\00' * (hdr_offset - offset)) |
| MarceloSalazar | 0:e13a8a944e25 | 146 | offset += (hdr_offset - offset) |
| MarceloSalazar | 0:e13a8a944e25 | 147 | |
| MarceloSalazar | 0:e13a8a944e25 | 148 | # write firmware header |
| MarceloSalazar | 0:e13a8a944e25 | 149 | output.write(FirmwareHeader) |
| MarceloSalazar | 0:e13a8a944e25 | 150 | offset += len(FirmwareHeader) |
| MarceloSalazar | 0:e13a8a944e25 | 151 | |
| MarceloSalazar | 0:e13a8a944e25 | 152 | # write padding between header and application |
| MarceloSalazar | 0:e13a8a944e25 | 153 | output.write(b'\00' * (app_offset - offset)) |
| MarceloSalazar | 0:e13a8a944e25 | 154 | |
| MarceloSalazar | 0:e13a8a944e25 | 155 | # write the application |
| MarceloSalazar | 0:e13a8a944e25 | 156 | output.write(app_blob) |
| MarceloSalazar | 0:e13a8a944e25 | 157 | |
| MarceloSalazar | 0:e13a8a944e25 | 158 | |
| MarceloSalazar | 0:e13a8a944e25 | 159 | if __name__ == '__main__': |
| MarceloSalazar | 0:e13a8a944e25 | 160 | import argparse |
| MarceloSalazar | 0:e13a8a944e25 | 161 | |
| MarceloSalazar | 0:e13a8a944e25 | 162 | parser = argparse.ArgumentParser( |
| MarceloSalazar | 0:e13a8a944e25 | 163 | description='Combine bootloader with application adding metadata header.') |
| MarceloSalazar | 0:e13a8a944e25 | 164 | |
| MarceloSalazar | 0:e13a8a944e25 | 165 | def offset_arg(s): |
| MarceloSalazar | 0:e13a8a944e25 | 166 | if s.startswith('0x'): |
| MarceloSalazar | 0:e13a8a944e25 | 167 | return int(s, 16) |
| MarceloSalazar | 0:e13a8a944e25 | 168 | else: |
| MarceloSalazar | 0:e13a8a944e25 | 169 | return int(s) |
| MarceloSalazar | 0:e13a8a944e25 | 170 | |
| MarceloSalazar | 0:e13a8a944e25 | 171 | bin_map = { |
| MarceloSalazar | 0:e13a8a944e25 | 172 | 'k64f': { |
| MarceloSalazar | 0:e13a8a944e25 | 173 | 'mem_start': '0x0' |
| MarceloSalazar | 0:e13a8a944e25 | 174 | }, |
| MarceloSalazar | 0:e13a8a944e25 | 175 | 'ublox_evk_odin_w2': { |
| MarceloSalazar | 0:e13a8a944e25 | 176 | 'mem_start': '0x08000000' |
| MarceloSalazar | 0:e13a8a944e25 | 177 | }, |
| MarceloSalazar | 0:e13a8a944e25 | 178 | 'nucleo_f429zi': { |
| MarceloSalazar | 0:e13a8a944e25 | 179 | 'mem_start': '0x08000000' |
| MarceloSalazar | 0:e13a8a944e25 | 180 | } |
| MarceloSalazar | 0:e13a8a944e25 | 181 | } |
| MarceloSalazar | 0:e13a8a944e25 | 182 | |
| MarceloSalazar | 0:e13a8a944e25 | 183 | curdir = path.dirname(path.abspath(__file__)) |
| MarceloSalazar | 0:e13a8a944e25 | 184 | |
| MarceloSalazar | 0:e13a8a944e25 | 185 | def parse_mbed_app_offset(mcu, key): |
| MarceloSalazar | 0:e13a8a944e25 | 186 | mem_start = bin_map[mcu]["mem_start"] |
| MarceloSalazar | 0:e13a8a944e25 | 187 | with open(path.join(curdir, "..", "mbed_app.json")) as fd: |
| MarceloSalazar | 0:e13a8a944e25 | 188 | mbed_json = json.load(fd) |
| MarceloSalazar | 0:e13a8a944e25 | 189 | offset = mbed_json["target_overrides"][mcu.upper()][key] |
| MarceloSalazar | 0:e13a8a944e25 | 190 | return offset_arg(offset) - offset_arg(mem_start) |
| MarceloSalazar | 0:e13a8a944e25 | 191 | |
| MarceloSalazar | 0:e13a8a944e25 | 192 | # specify arguments |
| MarceloSalazar | 0:e13a8a944e25 | 193 | parser.add_argument('-m', '--mcu', type=lambda s : s.lower().replace("-","_"), required=False, |
| MarceloSalazar | 0:e13a8a944e25 | 194 | help='mcu', choices=bin_map.keys()) |
| MarceloSalazar | 0:e13a8a944e25 | 195 | parser.add_argument('-b', '--bootloader', type=argparse.FileType('rb'), required=False, |
| MarceloSalazar | 0:e13a8a944e25 | 196 | help='path to the bootloader binary') |
| MarceloSalazar | 0:e13a8a944e25 | 197 | parser.add_argument('-a', '--app', type=argparse.FileType('rb'), required=True, |
| MarceloSalazar | 0:e13a8a944e25 | 198 | help='path to application binary') |
| MarceloSalazar | 0:e13a8a944e25 | 199 | parser.add_argument('-c', '--app-offset', type=offset_arg, required=False, |
| MarceloSalazar | 0:e13a8a944e25 | 200 | help='offset of the application') |
| MarceloSalazar | 0:e13a8a944e25 | 201 | parser.add_argument('-d', '--header-offset', type=offset_arg, required=False, |
| MarceloSalazar | 0:e13a8a944e25 | 202 | help='offset of the firmware metadata header') |
| MarceloSalazar | 0:e13a8a944e25 | 203 | parser.add_argument('-o', '--output', type=argparse.FileType('wb'), required=True, |
| MarceloSalazar | 0:e13a8a944e25 | 204 | help='output combined file path') |
| MarceloSalazar | 0:e13a8a944e25 | 205 | parser.add_argument('-s', '--set-version', type=int, required=False, |
| MarceloSalazar | 0:e13a8a944e25 | 206 | help='set version number', default=int(time.time())) |
| MarceloSalazar | 0:e13a8a944e25 | 207 | |
| MarceloSalazar | 0:e13a8a944e25 | 208 | # workaround for http://bugs.python.org/issue9694 |
| MarceloSalazar | 0:e13a8a944e25 | 209 | parser._optionals.title = "arguments" |
| MarceloSalazar | 0:e13a8a944e25 | 210 | |
| MarceloSalazar | 0:e13a8a944e25 | 211 | # get and validate arguments |
| MarceloSalazar | 0:e13a8a944e25 | 212 | args = parser.parse_args() |
| MarceloSalazar | 0:e13a8a944e25 | 213 | |
| MarceloSalazar | 0:e13a8a944e25 | 214 | if(not (args.mcu or args.bootloader)): |
| MarceloSalazar | 0:e13a8a944e25 | 215 | print("Please specify bootloader location or MCU") |
| MarceloSalazar | 0:e13a8a944e25 | 216 | exit(-1) |
| MarceloSalazar | 0:e13a8a944e25 | 217 | |
| MarceloSalazar | 0:e13a8a944e25 | 218 | fname = '' |
| MarceloSalazar | 0:e13a8a944e25 | 219 | if args.mcu: |
| MarceloSalazar | 0:e13a8a944e25 | 220 | fname = path.join(curdir, 'mbed-bootloader-' + args.mcu.replace('_', '-')+'.bin') |
| MarceloSalazar | 0:e13a8a944e25 | 221 | if not path.exists(fname): |
| MarceloSalazar | 0:e13a8a944e25 | 222 | print("Specified MCU does not have a binary in this location") |
| MarceloSalazar | 0:e13a8a944e25 | 223 | exit(-1) |
| MarceloSalazar | 0:e13a8a944e25 | 224 | |
| MarceloSalazar | 0:e13a8a944e25 | 225 | # Use specified bootloader or default if none is provided |
| MarceloSalazar | 0:e13a8a944e25 | 226 | bootloader = args.bootloader or open(fname, 'rb') |
| MarceloSalazar | 0:e13a8a944e25 | 227 | |
| MarceloSalazar | 0:e13a8a944e25 | 228 | # read the contents of bootloader and application binaries into buffers |
| MarceloSalazar | 0:e13a8a944e25 | 229 | bootloader_blob = bootloader.read() |
| MarceloSalazar | 0:e13a8a944e25 | 230 | bootloader.close() |
| MarceloSalazar | 0:e13a8a944e25 | 231 | app_blob = args.app.read() |
| MarceloSalazar | 0:e13a8a944e25 | 232 | args.app.close() |
| MarceloSalazar | 0:e13a8a944e25 | 233 | |
| MarceloSalazar | 0:e13a8a944e25 | 234 | # Use specified offsets or default if none are provided |
| MarceloSalazar | 0:e13a8a944e25 | 235 | if(not (args.mcu or args.app_offset)): |
| MarceloSalazar | 0:e13a8a944e25 | 236 | print("Please specify app offset or MCU") |
| MarceloSalazar | 0:e13a8a944e25 | 237 | exit(-1) |
| MarceloSalazar | 0:e13a8a944e25 | 238 | app_offset = args.app_offset or parse_mbed_app_offset(args.mcu, "target.mbed_app_start") |
| MarceloSalazar | 0:e13a8a944e25 | 239 | |
| MarceloSalazar | 0:e13a8a944e25 | 240 | if(not (args.mcu or args.header_offset)): |
| MarceloSalazar | 0:e13a8a944e25 | 241 | print("Please specify header offset or MCU") |
| MarceloSalazar | 0:e13a8a944e25 | 242 | exit(-1) |
| MarceloSalazar | 0:e13a8a944e25 | 243 | header_offset = args.header_offset or parse_mbed_app_offset(args.mcu, "update-client.application-details") |
| MarceloSalazar | 0:e13a8a944e25 | 244 | |
| MarceloSalazar | 0:e13a8a944e25 | 245 | # combine application and bootloader adding metadata info |
| MarceloSalazar | 0:e13a8a944e25 | 246 | combine(bootloader_blob, app_blob, app_offset, header_offset, args.output, args.set_version) |
| MarceloSalazar | 0:e13a8a944e25 | 247 | |
| MarceloSalazar | 0:e13a8a944e25 | 248 | # close output file |
| MarceloSalazar | 0:e13a8a944e25 | 249 | output_fn = path.abspath(args.output.name) |
| MarceloSalazar | 0:e13a8a944e25 | 250 | args.output.close() |
| MarceloSalazar | 0:e13a8a944e25 | 251 | |
| MarceloSalazar | 0:e13a8a944e25 | 252 | # print the output file path |
| MarceloSalazar | 0:e13a8a944e25 | 253 | print('Combined binary:' + output_fn) |
