From 8c1774b5827e88f07c83e023d40a8b5f42104024 Mon Sep 17 00:00:00 2001 From: Teemu Takaluoma Date: Mon, 11 Jun 2018 08:53:46 +0300 Subject: [PATCH] mbed-cloud-client-example 1.3.3 --- CHANGELOG.md | 35 +++++---- main.cpp | 33 +++++++- mbed-cloud-client.lib | 2 +- mbed-os.lib | 2 +- profiles/debug_size.json | 30 ++++++-- profiles/size.json | 19 ++++- source/application_init.cpp | 147 +++++++++++++++++++++++++++++++----- source/application_init.h | 5 ++ source/memory_tests.cpp | 28 ++++++- source/memory_tests.h | 2 + source/simplem2mclient.h | 22 +++++- 11 files changed, 271 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1aa50e3..5a8f06c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,33 +1,38 @@ # Changelog for Mbed Cloud Client Reference Example +## Release 1.3.3 (11.06.2018) +* Updated to Mbed OS 5.8.5. +* The example application prints information about the validity of the stored Cloud credentials (including Connect and Update certificates). +* Added a start-up delay of two seconds as a workaround for the SD driver initialization [issue](https://github.com/ARMmbed/sd-driver/issues/93). +* Fixed the heap corruption that took place with `print_m2mobject_stats()` when building the code with the MBED_HEAP_STATS_ENABLED flag. +* Added the `-DMBED_STACK_STATS_ENABLED` flag. It enables printing information on the application thread stack usage. + ## Release 1.3.2 (22.05.2018) -* Update easy-connect to v1.2.9 -* Update to Mbed OS 5.8.4 -* Configuration partition_mode is added, which is enabled by default. This is supposed to be used with storage for data e.g. SD card. -* Linux: Update Mbedtls to 2.7.1 in pal-platform. -* Linux: Fix for CMake generation and generic cleanup in pal-platform. +* Updated easy-connect to v1.2.9 +* Updated to Mbed OS 5.8.4 +* Added the `partition_mode` configuration. It is enabled by default and supposed to be used with a data storage, such as an SD card. +* Linux: Updated Mbedtls to 2.7.1 in pal-platform. +* Linux: Fixed CMake generation and performed generic cleanup in pal-platform scripts. #### Platform Adaptation Layer (PAL) -* Linux: Converted all timers to use signal-based timer (SIGEV_SIGNAL) instead of (SIGEV_THREAD). +* Linux: Converted all timers to use signal-based timer (`SIGEV_SIGNAL`) instead of (`SIGEV_THREAD`). * This fixes the Valgrind warnings for possible memory leaks caused by LIBC's internal timer helper thread. **Note**: If the client application is creating a pthread before instantiating MbedCloudClient, it needs to block the PAL_TIMER_SIGNAL from it. Otherwise the thread may get an exception caused by the default signal handler with a message such as "Process terminating with default action - of signal 34 (SIGRT2)". For a suggested way to handle this please see `mcc_platform_init()` in - https://github.com/ARMmbed/mbed-cloud-client-example/blob/master/source/platform/Linux/common_setup.c. + of signal 34 (`SIGRT2`)". For a suggested way to handle this please see `mcc_platform_init()` in [here](https://github.com/ARMmbed/mbed-cloud-client-example/blob/master/source/platform/Linux/common_setup.c). ## Release 1.3.1.1 (27.04.2018) * No changes. ## Release 1.3.1 (19.04.2018) -* Convert LED blinking callback from a blocking loop to event based tasklet. -* Update to Mbed OS 5.8.1. -* Rewrite platform-specific code to have common implementation which can be shared between other Cloud applications (source/platform/). - * enable multipartition support for application. - * enable LittleFS support. - * enable autoformat/autopartition for storage (controllable via compile-time flags). +* Converted LED blinking callback from a blocking loop to event based tasklet. +* Updated to Mbed OS 5.8.1. +* Rewrote platform-specific code to have common implementation which can be shared between other Cloud applications (source/platform/). + * enabled multipartition support for application. + * enabled LittleFS support. + * enabled autoformat/autopartition for storage (controllable via compile-time flags). ## Release 1.3.0 (27.3.2018) Initial public release. - diff --git a/main.cpp b/main.cpp index 9e3e416..45b3488 100644 --- a/main.cpp +++ b/main.cpp @@ -111,9 +111,36 @@ void factory_reset(void *) void main_application(void) { + // https://github.com/ARMmbed/sd-driver/issues/93 (IOTMORF-2327) + // SD-driver initialization can fails with bd->init() -5005. This wait will + // allow the board more time to initialize. +#ifdef TARGET_LIKE_MBED + wait(2); +#endif mcc_platform_sw_build_info(); // run_application() will first initialize the program and then call main_application() + if (mcc_platform_storage_init() != 0) { + printf("Failed to initialize storage\n" ); + return; + } + + if(mcc_platform_init() != 0) { + printf("ERROR - platform_init() failed!\n"); + return; + } + + // Print some statistics of the object sizes and their heap memory consumption. + // NOTE: This *must* be done before creating MbedCloudClient, as the statistic calculation + // creates and deletes M2MSecurity and M2MDevice singleton objects, which are also used by + // the MbedCloudClient. +#ifdef MBED_HEAP_STATS_ENABLED + print_m2mobject_stats(); +#endif + + // SimpleClient is used for registering and unregistering resources to a server. + SimpleM2MClient mbedClient; + // application_init() runs the following initializations: // 1. trace initialization // 2. platform initialization @@ -124,9 +151,6 @@ void main_application(void) return; } - // SimpleClient is used for registering and unregistering resources to a server. - SimpleM2MClient mbedClient; - // Save pointer to mbedClient so that other functions can access it. client = &mbedClient; @@ -134,6 +158,9 @@ void main_application(void) printf("Client initialized\r\n"); print_heap_stats(); #endif +#ifdef MBED_STACK_STATS_ENABLED + print_stack_statistics(); +#endif // Create resource for button count. Path of this resource will be: 3200/0/5501. button_res = mbedClient.add_cloud_resource(3200, 0, 5501, "button_resource", M2MResourceInstance::INTEGER, diff --git a/mbed-cloud-client.lib b/mbed-cloud-client.lib index 52db209..c7a42df 100644 --- a/mbed-cloud-client.lib +++ b/mbed-cloud-client.lib @@ -1 +1 @@ -https://github.com/ARMmbed/mbed-cloud-client/#d37a136be84216afb90f1bd3b00b1ac9d33d52a1 +https://github.com/ARMmbed/mbed-cloud-client/#3137b3d7c8da10bae38749a9384e5e5c77a55012 diff --git a/mbed-os.lib b/mbed-os.lib index 1ab4804..2a15740 100644 --- a/mbed-os.lib +++ b/mbed-os.lib @@ -1 +1 @@ -https://github.com/ARMmbed/mbed-os/#ae6c7c60f91c89cbf755a2f3c8ec9c66635849fd +https://github.com/ARMmbed/mbed-os/#367dbdf5145f4d6aa3e483c147fe7bda1ce23a36 diff --git a/profiles/debug_size.json b/profiles/debug_size.json index b5d9028..d062f8e 100644 --- a/profiles/debug_size.json +++ b/profiles/debug_size.json @@ -5,28 +5,43 @@ "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", "-ffunction-sections", "-fdata-sections", "-funsigned-char", "-MMD", "-fno-delete-null-pointer-checks", - "-fomit-frame-pointer", "-O1", "-g"], + "-fomit-frame-pointer", "-O1", "-g3", "-DMBED_DEBUG", + "-DMBED_TRAP_ERRORS_ENABLED=1"], "asm": ["-x", "assembler-with-cpp"], "c": ["-std=gnu99"], "cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"], "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", - "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", - "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit"] + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit", + "-Wl,-n"] + }, + "ARMC6": { + "common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-g", "-O1", + "-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions", + "-DMULADDC_CANNOT_USE_R7", "-fdata-sections", + "-fno-exceptions", "-MMD"], + "asm": [], + "c": ["-D__ASSERT_MSG", "-std=gnu99"], + "cxx": ["-fno-rtti", "-std=gnu++98"], + "ld": ["--verbose", "--remove", "--legacyalign", "--no_strict_wchar_size", + "--no_strict_enum_size"] }, "ARM": { "common": ["-c", "--gnu", "-Ospace", "--split_sections", "--apcs=interwork", "--brief_diagnostics", "--restrict", - "--multibyte_chars", "-O1", "-g"], + "--multibyte_chars", "-O1", "-g", "-DMBED_DEBUG", + "-DMBED_TRAP_ERRORS_ENABLED=1"], "asm": [], "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], "cxx": ["--cpp", "--no_rtti", "--no_vla"], - "ld": [] + "ld": ["--show_full_path"] }, "uARM": { "common": ["-c", "--gnu", "-Ospace", "--split_sections", "--apcs=interwork", "--brief_diagnostics", "--restrict", "--multibyte_chars", "-O1", "-D__MICROLIB", "-g", - "--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD"], + "--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD", "-DMBED_DEBUG", + "-DMBED_TRAP_ERRORS_ENABLED=1"], "asm": [], "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], "cxx": ["--cpp", "--no_rtti", "--no_vla"], @@ -35,7 +50,8 @@ "IAR": { "common": [ "--no_wrap_diagnostics", "-e", - "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Ol", "-r"], + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Ol", "-r", "-DMBED_DEBUG", + "-DMBED_TRAP_ERRORS_ENABLED=1", "--enable_restrict"], "asm": [], "c": ["--vla"], "cxx": ["--guard_calls", "--no_static_destruction"], diff --git a/profiles/size.json b/profiles/size.json index 45e9a30..fa5d0da 100644 --- a/profiles/size.json +++ b/profiles/size.json @@ -10,8 +10,19 @@ "c": ["-std=gnu99"], "cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"], "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", - "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", - "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit"] + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit", + "-Wl,-n"] + }, + "ARMC6": { + "common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Os", + "-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions", + "-DMULADDC_CANNOT_USE_R7", "-fdata-sections", + "-fno-exceptions", "-MMD"], + "asm": [], + "c": ["-D__ASSERT_MSG", "-std=gnu99"], + "cxx": ["-fno-rtti", "-std=gnu++98"], + "ld": ["--legacyalign", "--no_strict_wchar_size", "--no_strict_enum_size"] }, "ARM": { "common": ["-c", "--gnu", "-Ospace", "--split_sections", @@ -20,7 +31,7 @@ "asm": [], "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], "cxx": ["--cpp", "--no_rtti", "--no_vla"], - "ld": [] + "ld": ["--show_full_path"] }, "uARM": { "common": ["-c", "--gnu", "-Ospace", "--split_sections", @@ -35,7 +46,7 @@ "IAR": { "common": [ "--no_wrap_diagnostics", "-e", - "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Ohz"], + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Ohz", "--enable_restrict"], "asm": [], "c": ["--vla"], "cxx": ["--guard_calls", "--no_static_destruction"], diff --git a/source/application_init.cpp b/source/application_init.cpp index 054ebc5..7e7e365 100644 --- a/source/application_init.cpp +++ b/source/application_init.cpp @@ -1,5 +1,5 @@ // ---------------------------------------------------------------------------- -// Copyright 2016-2017 ARM Ltd. +// Copyright 2016-2018 ARM Ltd. // // SPDX-License-Identifier: Apache-2.0 // @@ -22,11 +22,128 @@ #include "factory_configurator_client.h" #include "common_setup.h" #include "common_button_and_led.h" -#ifdef MBED_HEAP_STATS_ENABLED +#if defined (MBED_HEAP_STATS_ENABLED) || (MBED_STACK_STATS_ENABLED) #include "memory_tests.h" #endif #include "application_init.h" +void print_fcc_status(int fcc_status) +{ + const char *error; + switch(fcc_status) { + case FCC_STATUS_SUCCESS: + return; + case FCC_STATUS_ERROR : + error = "Operation ended with an unspecified error."; + break; + case FCC_STATUS_MEMORY_OUT: + error = "An out-of-memory condition occurred."; + break; + case FCC_STATUS_INVALID_PARAMETER: + error = "A parameter provided to the function was invalid."; + break; + case FCC_STATUS_STORE_ERROR: + error = "Storage internal error."; + break; + case FCC_STATUS_INTERNAL_ITEM_ALREADY_EXIST: + error = "Current item already exists in storage."; + break; + case FCC_STATUS_CA_ERROR: + error = "CA Certificate already exist in storage (currently only bootstrap CA)"; + break; + case FCC_STATUS_ROT_ERROR: + error = "ROT already exist in storage"; + break; + case FCC_STATUS_ENTROPY_ERROR: + error = "Entropy already exist in storage"; + break; + case FCC_STATUS_FACTORY_DISABLED_ERROR: + error = "FCC flow was disabled - denial of service error."; + break; + case FCC_STATUS_INVALID_CERTIFICATE: + error = "Invalid certificate found."; + break; + case FCC_STATUS_INVALID_CERT_ATTRIBUTE: + error = "Operation failed to get an attribute."; + break; + case FCC_STATUS_INVALID_CA_CERT_SIGNATURE: + error = "Invalid ca signature."; + break; + case FCC_STATUS_EXPIRED_CERTIFICATE: + error = "LWM2M or Update certificate is expired."; + break; + case FCC_STATUS_INVALID_LWM2M_CN_ATTR: + error = "Invalid CN field of certificate."; + break; + case FCC_STATUS_KCM_ERROR: + error = "KCM basic functionality failed."; + break; + case FCC_STATUS_KCM_STORAGE_ERROR: + error = "KCM failed to read, write or get size of item from/to storage."; + break; + case FCC_STATUS_KCM_FILE_EXIST_ERROR: + error = "KCM tried to create existing storage item."; + break; + case FCC_STATUS_KCM_CRYPTO_ERROR: + error = "KCM returned error upon cryptographic check of an certificate or key."; + break; + case FCC_STATUS_NOT_INITIALIZED: + error = "FCC failed or did not initialized."; + break; + case FCC_STATUS_BUNDLE_ERROR: + error = "Protocol layer general error."; + break; + case FCC_STATUS_BUNDLE_RESPONSE_ERROR: + error = "Protocol layer failed to create response buffer."; + break; + case FCC_STATUS_BUNDLE_UNSUPPORTED_GROUP: + error = "Protocol layer detected unsupported group was found in a message."; + break; + case FCC_STATUS_BUNDLE_INVALID_GROUP: + error = "Protocol layer detected invalid group in a message."; + break; + case FCC_STATUS_BUNDLE_INVALID_SCHEME: + error = "The scheme version of a message in the protocol layer is wrong."; + break; + case FCC_STATUS_ITEM_NOT_EXIST: + error = "Current item wasn't found in the storage"; + break; + case FCC_STATUS_EMPTY_ITEM: + error = "Current item's size is 0"; + break; + case FCC_STATUS_WRONG_ITEM_DATA_SIZE: + error = "Current item's size is different then expected"; + break; + case FCC_STATUS_URI_WRONG_FORMAT: + error = "Current URI is different than expected."; + break; + case FCC_STATUS_FIRST_TO_CLAIM_NOT_ALLOWED: + error = "Can't use first to claim without bootstrap or with account ID"; + break; + case FCC_STATUS_BOOTSTRAP_MODE_ERROR: + error = "Wrong value of bootstrapUse mode."; + break; + case FCC_STATUS_OUTPUT_INFO_ERROR: + error = "The process failed in output info creation."; + break; + case FCC_STATUS_WARNING_CREATE_ERROR: + error = "The process failed in output info creation."; + break; + case FCC_STATUS_UTC_OFFSET_WRONG_FORMAT: + error = "Current UTC is wrong."; + break; + case FCC_STATUS_CERTIFICATE_PUBLIC_KEY_CORRELATION_ERROR: + error = "Certificate's public key failed do not matches to corresponding private key"; + break; + case FCC_STATUS_BUNDLE_INVALID_KEEP_ALIVE_SESSION_STATUS: + error = "The message status is invalid."; + break; + default: + error = "UNKNOWN"; + } + printf("\nFactory Configurator Client [ERROR]: %s\r\n\n", error); +} + static bool application_init_mbed_trace(void) { // Create mutex for tracing to avoid broken lines in logs @@ -57,15 +174,18 @@ static bool application_init_verify_cloud_configuration() } #endif status = fcc_verify_device_configured_4mbed_cloud(); + print_fcc_status(status); if (status != FCC_STATUS_SUCCESS) { - printf("Invalid or missing provisioning data!\n"); return 1; - } + } return 0; } static bool application_init_fcc(void) { +#ifdef MBED_STACK_STATS_ENABLED + print_stack_statistics(); +#endif int status = mcc_platform_fcc_init(); if(status != FCC_STATUS_SUCCESS) { printf("fcc_init failed with status %d! - exit\n", status); @@ -104,27 +224,20 @@ bool application_init(void) return false; } - if (mcc_platform_storage_init() != 0) { - printf("Failed to initialize storage\n" ); - return false; - } - - if(mcc_platform_init() != 0) { - printf("ERROR - platform_init() failed!\n"); - return false; - } - if(mcc_platform_init_button_and_led() != 0) { printf("ERROR - initButtonAndLed() failed!\n"); return false; } - // Print some statistics of the object sizes and heap memory consumption - // if the MBED_HEAP_STATS_ENABLED is defined. + // Print some statistics of current heap memory consumption, useful for finding + // out where the memory goes. #ifdef MBED_HEAP_STATS_ENABLED - print_m2mobject_stats(); print_heap_stats(); #endif + +#ifdef MBED_STACK_STATS_ENABLED + print_stack_statistics(); +#endif printf("Start simple mbed Cloud Client\n"); if (application_init_fcc() != 0) { diff --git a/source/application_init.h b/source/application_init.h index 7789d4e..52aafc2 100644 --- a/source/application_init.h +++ b/source/application_init.h @@ -30,5 +30,10 @@ bool application_init(void); +/* + * Prints the FCC status and corresponding error description, if any. + */ +void print_fcc_status(int fcc_status); + #endif //APPLICATION_INIT_H diff --git a/source/memory_tests.cpp b/source/memory_tests.cpp index 82c56f2..2940de9 100644 --- a/source/memory_tests.cpp +++ b/source/memory_tests.cpp @@ -1,5 +1,5 @@ // ---------------------------------------------------------------------------- -// Copyright 2016-2017 ARM Ltd. +// Copyright 2016-2018 ARM Ltd. // // SPDX-License-Identifier: Apache-2.0 // @@ -19,7 +19,7 @@ #ifdef TARGET_LIKE_MBED -#ifdef MBED_HEAP_STATS_ENABLED +#if defined (MBED_HEAP_STATS_ENABLED) || (MBED_STACK_STATS_ENABLED) // used by print_heap_stats only #include "mbed_stats.h" #define __STDC_FORMAT_MACROS @@ -45,7 +45,9 @@ #include "mbed_stats.h" #include +#endif +#if defined (MBED_HEAP_STATS_ENABLED) void print_heap_stats() { mbed_stats_heap_t stats; @@ -170,6 +172,9 @@ void print_m2mobject_stats() M2MSecurity *security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer); mbed_stats_heap_get(&stats); printf("M2MSecurity heap size: %" PRIu32 "\n", stats.current_size - initial); + + // If the MbedCloudClient is already instantiated, this corrupts heap as it frees the + // singleton of M2MSecurity, which is still used by it. Use with care. M2MSecurity::delete_instance(); mbed_stats_heap_get(&stats); if (initial != stats.current_size) { @@ -213,5 +218,24 @@ void print_m2mobject_stats() } printf("*************************************\n\n"); } + #endif // MBED_HEAP_STATS_ENABLED +#ifdef MBED_STACK_STATS_ENABLED +void print_stack_statistics() +{ + printf("** MBED THREAD STASK STATS **\n"); + int cnt = osThreadGetCount(); + mbed_stats_stack_t *stats = (mbed_stats_stack_t*) malloc(cnt * sizeof(mbed_stats_stack_t)); + + if (stats) { + cnt = mbed_stats_stack_get_each(stats, cnt); + for (int i = 0; i < cnt; i++) { + printf("Thread: 0x%" PRIx32 ", Stack size: %" PRIu32 ", Max stack: %" PRIu32 "\r\n", stats[i].thread_id, stats[i].reserved_size, stats[i].max_size); + } + + free(stats); + } + printf("*****************************\n\n"); +} +#endif // MBED_STACK_STATS_ENABLED #endif // TARGET_LIKE_MBED diff --git a/source/memory_tests.h b/source/memory_tests.h index b359184..9c87bd6 100644 --- a/source/memory_tests.h +++ b/source/memory_tests.h @@ -40,4 +40,6 @@ void print_m2mobject_stats(); void print_heap_stats(); +void print_stack_statistics(); + #endif // !__MEMORY_TESTS_H__ diff --git a/source/simplem2mclient.h b/source/simplem2mclient.h index 25b075b..adaf6b6 100644 --- a/source/simplem2mclient.h +++ b/source/simplem2mclient.h @@ -27,6 +27,8 @@ #include "mbed-client/m2minterface.h" #include "key_config_manager.h" #include "resource.h" +#include "application_init.h" +#include "factory_configurator_client.h" #ifdef MBED_CLOUD_CLIENT_USER_CONFIG_FILE #include MBED_CLOUD_CLIENT_USER_CONFIG_FILE @@ -36,7 +38,7 @@ #include "update_ui_example.h" #endif -#ifdef MBED_HEAP_STATS_ENABLED +#if defined (MBED_HEAP_STATS_ENABLED) || (MBED_STACK_STATS_ENABLED) #include "memory_tests.h" #endif @@ -91,7 +93,7 @@ class SimpleM2MClient { void client_registered() { _registered = true; - printf("\nClient registered\n\n"); + printf("\nClient registered\n"); static const ConnectorClientEndpointInfo* endpoint = NULL; if (endpoint == NULL) { endpoint = _cloud_client.endpoint_info(); @@ -106,6 +108,9 @@ class SimpleM2MClient { } #ifdef MBED_HEAP_STATS_ENABLED print_heap_stats(); +#endif +#ifdef MBED_STACK_STATS_ENABLED + print_stack_statistics(); #endif } @@ -115,6 +120,9 @@ class SimpleM2MClient { printf("\nClient unregistered - Exiting application\n\n"); #ifdef MBED_HEAP_STATS_ENABLED print_heap_stats(); +#endif +#ifdef MBED_STACK_STATS_ENABLED + print_stack_statistics(); #endif } @@ -219,6 +227,9 @@ class SimpleM2MClient { // Add some test resources to measure memory consumption. // This code is activated only if MBED_HEAP_STATS_ENABLED is defined. create_m2mobject_test_set(_obj_list); +#endif +#ifdef MBED_STACK_STATS_ENABLED + print_stack_statistics(); #endif _cloud_client.add_objects(_obj_list); @@ -227,8 +238,11 @@ class SimpleM2MClient { // Print memory statistics if the MBED_HEAP_STATS_ENABLED is defined. #ifdef MBED_HEAP_STATS_ENABLED - printf("Register being called\r\n"); - print_heap_stats(); + printf("Register being called\r\n"); + print_heap_stats(); +#endif +#ifdef MBED_STACK_STATS_ENABLED + print_stack_statistics(); #endif }