Simple Mbed Cloud Client application using features of K64 & K66

Connect to Mbed Cloud!

This example was customized a bit for FRDM-K66 and FRDM-K64F.

It depends on having an SD Card plugged in for storage of credentials. It could be changed later to use a SPI flash or other storage on a shield or wired in.

The app keeps track of how many times switch 2 (SW2) is pressed. The value can be retrieved via a GET request to Mbed Cloud.

Also, it will blink a pattern based on milisecond (ms) timing values that can be sent from Mbed Cloud. The pattern can be sent with a PUT request and the blinking sequence can be triggered by a POST request.

Revision:
1:1ccf36276cd3
Parent:
0:e13a8a944e25
Child:
2:6ed27f413b30
--- a/combine_bootloader_with_app.py	Tue Feb 13 10:07:23 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,253 +0,0 @@
-#!/usr/bin/env python
-
-## ----------------------------------------------------------------------------
-## Copyright 2016-2017 ARM Ltd.
-##
-## SPDX-License-Identifier: Apache-2.0
-##
-## 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 os import path
-import json
-import hashlib, zlib, struct
-import time
-import sys
-
-'''
-define FIRMWARE_HEADER_MAGIC   0x5a51b3d4UL
-define FIRMWARE_HEADER_VERSION 2
-define ARM_UC_SHA512_SIZE     (512/8)
-define ARM_UC_GUID_SIZE       (128/8)
-typedef struct _arm_uc_internal_header_t
-{
-    /* Metadata-header specific magic code */
-    uint32_t headerMagic;
-
-    /* Revision number for metadata header. */
-    uint32_t headerVersion;
-
-    /* Version number accompanying the firmware. Larger numbers imply more
-       recent and preferred versions. This is used for determining the
-       selection order when multiple versions are available. For downloaded
-       firmware the manifest timestamp is used as the firmware version.
-    */
-    uint64_t firmwareVersion;
-
-    /* Total space (in bytes) occupied by the firmware BLOB. */
-    uint64_t firmwareSize;
-
-    /* Firmware hash calculated over the firmware size. Should match the hash
-       generated by standard command line tools, e.g., shasum on Linux/Mac.
-    */
-    uint8_t firmwareHash[ARM_UC_SHA512_SIZE];
-
-    /* The ID for the update campaign that resulted in the firmware update.
-    */
-    uint8_t campaign[ARM_UC_GUID_SIZE];
-
-    /* Size of the firmware signature. Must be 0 if no signature is supplied. */
-    uint32_t firmwareSignatureSize;
-
-    /* Header 32 bit CRC. Calculated over the entire header, including the CRC
-       field, but with the CRC set to zero.
-    */
-    uint32_t headerCRC;
-
-    /* Optional firmware signature. Hashing algorithm should be the same as the
-       one used for the firmware hash. The firmwareSignatureSize must be set.
-    */
-    uint8_t firmwareSignature[0];
-} arm_uc_internal_header_t;
-'''
-
-# define defaults to go into the metadata header
-SIZEOF_SHA512     = int(512/8)
-SIZEOF_GUID       = int(128/8)
-FIRMWARE_HEADER_MAGIC = 0x5a51b3d4
-FIRMWARE_HEADER_VERSION = 2
-header_format = ">2I2Q{}s{}s2I".format(SIZEOF_SHA512, SIZEOF_GUID)
-
-if sys.version_info < (3,):
-    def b(x):
-        return bytearray(x)
-else:
-    def b(x):
-        return x
-
-def create_header(app_blob, firmwareVersion):
-    # calculate the hash of the application
-    firmwareHash = hashlib.sha256(app_blob).digest()
-
-    # calculate the total size which is defined as the application size + metadata header
-    firmwareSize = len(app_blob)
-
-    # set campaign GUID to 0
-    campaign = b'\00'
-
-    # signature not supported, set size to 0
-    signatureSize = 0
-
-    print ('imageSize:    {}'.format(firmwareSize))
-    print ('imageHash:    {}'.format(''.join(['{:0>2x}'.format(c) for c in b(firmwareHash)])))
-    print ('imageversion: {}'.format(firmwareVersion))
-
-    # construct struct for CRC calculation
-    headerCRC = 0
-    FirmwareHeader = struct.pack(header_format,
-                                 FIRMWARE_HEADER_MAGIC,
-                                 FIRMWARE_HEADER_VERSION,
-                                 firmwareVersion,
-                                 firmwareSize,
-                                 firmwareHash,
-                                 campaign,
-                                 signatureSize,
-                                 headerCRC)
-
-    # calculate checksum over header, including signatureSize but without headerCRC
-    headerCRC = zlib.crc32(FirmwareHeader[:-4]) & 0xffffffff
-
-    # Pack the data into a binary blob
-    FirmwareHeader = struct.pack(header_format,
-                                 FIRMWARE_HEADER_MAGIC,
-                                 FIRMWARE_HEADER_VERSION,
-                                 firmwareVersion,
-                                 firmwareSize,
-                                 firmwareHash,
-                                 campaign,
-                                 signatureSize,
-                                 headerCRC)
-
-    return FirmwareHeader
-
-
-def combine(bootloader_blob, app_blob, app_offset, hdr_offset, output, version):
-
-    # create header to go with the application binary
-    FirmwareHeader = create_header(app_blob, version)
-
-    # write the bootloader first
-    offset = 0
-    output.write(bootloader_blob)
-    offset += len(bootloader_blob)
-
-    # write the padding between bootloader and firmware header
-    output.write(b'\00' * (hdr_offset - offset))
-    offset += (hdr_offset - offset)
-
-    # write firmware header
-    output.write(FirmwareHeader)
-    offset += len(FirmwareHeader)
-
-    # write padding between header and application
-    output.write(b'\00' * (app_offset - offset))
-
-    # write the application
-    output.write(app_blob)
-
-
-if __name__ == '__main__':
-    import argparse
-
-    parser = argparse.ArgumentParser(
-        description='Combine bootloader with application adding metadata header.')
-
-    def offset_arg(s):
-        if s.startswith('0x'):
-            return int(s, 16)
-        else:
-            return int(s)
-
-    bin_map = {
-        'k64f': {
-            'mem_start': '0x0'
-        },
-        'ublox_evk_odin_w2': {
-            'mem_start': '0x08000000'
-        },
-        'nucleo_f429zi': {
-            'mem_start': '0x08000000'
-        }
-    }
-
-    curdir = path.dirname(path.abspath(__file__))
-
-    def parse_mbed_app_offset(mcu, key):
-        mem_start = bin_map[mcu]["mem_start"]
-        with open(path.join(curdir, "..", "mbed_app.json")) as fd:
-            mbed_json = json.load(fd)
-            offset = mbed_json["target_overrides"][mcu.upper()][key]
-            return offset_arg(offset) - offset_arg(mem_start)
-
-    # specify arguments
-    parser.add_argument('-m', '--mcu', type=lambda s : s.lower().replace("-","_"), required=False,
-                        help='mcu', choices=bin_map.keys())
-    parser.add_argument('-b', '--bootloader',    type=argparse.FileType('rb'), required=False,
-                        help='path to the bootloader binary')
-    parser.add_argument('-a', '--app',           type=argparse.FileType('rb'), required=True,
-                        help='path to application binary')
-    parser.add_argument('-c', '--app-offset',    type=offset_arg,              required=False,
-                        help='offset of the application')
-    parser.add_argument('-d', '--header-offset', type=offset_arg,              required=False,
-                        help='offset of the firmware metadata header')
-    parser.add_argument('-o', '--output',        type=argparse.FileType('wb'), required=True,
-                        help='output combined file path')
-    parser.add_argument('-s', '--set-version',   type=int,                     required=False,
-                        help='set version number', default=int(time.time()))
-
-    # workaround for http://bugs.python.org/issue9694
-    parser._optionals.title = "arguments"
-
-    # get and validate arguments
-    args = parser.parse_args()
-
-    if(not (args.mcu or args.bootloader)):
-        print("Please specify bootloader location or MCU")
-        exit(-1)
-
-    fname = ''
-    if args.mcu:
-        fname = path.join(curdir, 'mbed-bootloader-' + args.mcu.replace('_', '-')+'.bin')
-        if not path.exists(fname):
-            print("Specified MCU does not have a binary in this location")
-            exit(-1)
-
-    # Use specified bootloader or default if none is provided
-    bootloader = args.bootloader or open(fname, 'rb')
-
-    # read the contents of bootloader and application binaries into buffers
-    bootloader_blob = bootloader.read()
-    bootloader.close()
-    app_blob = args.app.read()
-    args.app.close()
-
-    # Use specified offsets or default if none are provided
-    if(not (args.mcu or args.app_offset)):
-        print("Please specify app offset or MCU")
-        exit(-1)
-    app_offset = args.app_offset or parse_mbed_app_offset(args.mcu, "target.mbed_app_start")
-
-    if(not (args.mcu or args.header_offset)):
-        print("Please specify header offset or MCU")
-        exit(-1)
-    header_offset = args.header_offset or parse_mbed_app_offset(args.mcu, "update-client.application-details")
-
-    # combine application and bootloader adding metadata info
-    combine(bootloader_blob, app_blob, app_offset, header_offset, args.output, args.set_version)
-
-    # close output file
-    output_fn = path.abspath(args.output.name)
-    args.output.close()
-
-    # print the output file path
-    print('Combined binary:' + output_fn)