Mistake on this page? Email us

Configuring for optimized memory use

This chapter describes the options to configure Device Management Client for optimized memory use and code size.

  • Optimization by feature configuration.
  • Optimization by API.
  • Optimization by application configuration.

Optimization by feature configuration

Device Management Client has multiple build-time feature configurations you can set using the mbed_app.json file. You can turn off several features as they have a direct impact on application memory size, both RAM and ROM.

In mbed-cloud-client\mbed-client's mbed_lib.json:

{
    "name": "mbed-client",
    "config": {
        "event-loop-size": 1024,
        "reconnection-count": 3,
        "reconnection-interval": 5,
        "tcp-keepalive-interval": 540,
        "disable-bootstrap-feature": null,
        "coap-disable-obs-feature":null,
        "dtls_peer_max_timeout": null,
        "tls-max-retry": null,
        "sn-coap-max-blockwise-payload-size" : null,
        "sn-coap-duplication-max-msgs-count": 5,
        "sn-coap-max-incoming-message-size": null,
        "sn-coap-resending-queue-size-msgs": 5,
        "sn-coap-resending-queue-size-bytes": null,
        "sn-coap-blockwise-max-time-data-stored": null,
        "disable-interface-description": null,		==> If your application does not want to send Resource's interface "plain-text" format to Device Management, turn this to 1 to save ROM.
        "disable-resource-type": null,			==> If your application does not want to send Resource's description in "plain-text" format to Device Management, turn this to 1 to save ROM.
        "disable-delayed-response": null,
        "disable-block-message": null,
        "memory-optimized-api": null,			==> If your application can create a Resource structure on ROM rather than on RAM, turn this to 1. This saves around 66 bytes of RAM per Resource.
        "enable-observation-parameters" : 1	    	==> If your application doesn't follow strict LwM2M Write attribute for handling notifications as per spec rules, turn this to false. This saves around 160 bytes of RAM per resource.
    }
}

In mbed-cloud-client's mbed_lib.json:

{
    "name": "mbed-cloud-client",
    "config": {
        "update-download-protocol": {
            "help": "Set up download protocol for update firmware",
            "required": true,
            "options": ["MBED_CLOUD_CLIENT_UPDATE_DOWNLOAD_PROTOCOL_COAP", "MBED_CLOUD_CLIENT_UPDATE_DOWNLOAD_PROTOCOL_HTTP"],
            "default": "MBED_CLOUD_CLIENT_UPDATE_DOWNLOAD_PROTOCOL_COAP",
            "value": "MBED_CLOUD_CLIENT_UPDATE_DOWNLOAD_PROTOCOL_COAP"
        },
        "update-storage": {
            "help": "Storage option for update image. Common values: ARM_UCP_FLASHIAP and ARM_UCP_FLASHIAP_BLOCKDEVICE.",
            "macro_name": "MBED_CLOUD_CLIENT_UPDATE_STORAGE",
            "default": null,
            "value": null
        },
        "disable-certificate-enrollment": {
            "help": "Enables or disables certificate enrollment feature",
            "options": ["null", "1"],
            "default": 1,
            "value": 1             ==> Is disabled by default and saves around 7 KB of ROM.
        },
        "external-sst-support": {
            "help": "Enables external secure storage feature (KVstore)",
            "options": ["null", "1"],
            "default": 1,
            "value": 1
        },
        "psa-support": {
            "help": "Enables Platform Security Architecture (PSA) feature",
            "options": [ "null", "1" ],
            "default": null,
            "value": null
        },
        "secure-element-support": {
            "help": "Enables Secure Element feature",
            "options": [ "null", "1"],
            "default": null,
            "value": null
        },
        "enable-device-sentry": {
            "help": "Enables Device Sentry feature",
            "options": [ "null", "1" ],
            "default": null,
            "value": null         ==> Is disabled by default and saves around 7KB of ROM
        }
    },
    "macros" : [
        "ARM_UC_PROFILE_MBED_CLOUD_CLIENT=1",
        "SN_COAP_REDUCE_BLOCKWISE_HEAP_FOOTPRINT=1"
    ]
}

You can also save ROM by disabling some of the development mode features from your application. For example, disabling the printing of human-readable error text messages over console saves around 4.5KB of ROM.

To disable the error texts, add this macro in your application's mbed_app.json:

"macros": [ "DISABLE_ERROR_DESCRIPTION"]

Optimization by API

Device Management Client offers APIs you can use to create Resources on ROM rather than on RAM.

When you create Resources on ROM, you can save up to 66 bytes of RAM on each Resource. If your application is creating a large number of Resources, we recommend that you create them at build time statically on ROM rather than at runtime.

To create Resources on ROM using the Client API:

  1. Enable memory optimization in your application's mbed_app.json:

    "mbed-client.memory-optimized-api": 1,
    
  2. Create a structure for the Resources:

    const static sn_nsdl_static_resource_parameters_s resource1_params_static = {
    #ifndef RESOURCE_ATTRIBUTES_LIST
    #ifndef DISABLE_RESOURCE_TYPE
        (char*)"IsMaster",      // resource_type_ptr
    #endif
    #ifndef DISABLE_INTERFACE_DESCRIPTION
        (char*)"",                     // interface_description_ptr
    #endif
    #else
        default_attributes,
    #endif
        (char*)RESOURCE1_PATH,    // path
        false,                  // external_memory_block
        SN_GRS_DYNAMIC,         // mode
        false                   // free_on_delete
    };
    
    static sn_nsdl_dynamic_resource_parameters_s resource1_params_dynamic = {
        __nsdl_c_callback,
        &resource1_params_static,
        NULL,
        {NULL, NULL},                     // link
        0,
        0, // coap_content_type PLAIN_TEXT
        M2MBase::GET_ALLOWED,   // access
        0,                      // registered
        true,                  // publish_uri
        false,                  // free_on_delete
        true,                   // observable
        false,                  // auto-observable
        false,                  // always_publish
        0                       // publish_value
    };
    
    const static M2MBase::lwm2m_parameters resource1_params = {
        0, // max_age
        (char*)RESOURCE1,
        &resource1_params_dynamic,
        M2MBase::Resource, // base_type
        M2MBase::INTEGER,
        false,
        false, // free_on_delete
        false  // identifier_int_type
    };
    
    

    The details for sn_nsdl_static_resource_parameters_s, sn_nsdl_dynamic_resource_parameters_s and M2MBase::lwm2m_parameters structures are defined in mbed-cloud-client\mbed-client\mbed-client-c\nsdl-c\sn_nsdl_lib.h and mbed-cloud-client\mbed-client\m2mbase.h.

  3. Pass this structure to the API for Device Management Client to register it as a Resource:

    M2MResource* create_dynamic_resource(resource1_params,M2MResourceInstance::STRING, true);
    

Optimization by application configuration

There are other application-level configurations that have a direct impact on memory use, especially the runtime memory.

  • You can configure the application in a mode where you can run Device Management Client on the main application thread rather than its own event thread, thereby saving up to 10KB of RAM.

    To build and run this configuration successfully, use these values in your application's mbed_app.json:

     "nanostack-hal.event-loop-use-mbed-events"             : true,
     "nanostack-hal.event-loop-dispatch-from-application"   : false,
     "nanostack-hal.critical-section-usable-from-interrupt" : true,
     "events.shared-dispatch-from-application"   		: true,
    
  • Study your final application size and prepare your application memory configuration so that you can have your firmware update image candidate downloaded on the internal flash.

    This has a cascading effect on the ROM size. If your application and firmware image can completely reside inside the internal flash and you don't require external flash, you don't need FileSystem libraries in your build. This can save up to 40KB of flash memory and 5-10KB of RAM, as well.

    For example, if you are using a K64F board for your application development and your final image is less than 512KB of flash, you can fit a firmware candidate into the second memory bank of 512KB (K64F flash size is 1MB). You don't need external flash for storing Device Management Client-related information, and thus you can reduce the memory size. However, if your application requires external flash or filesystem to store your application user data, this optimization doesn't apply.

    See the wifi_esp8266_minimal.json configuration in our reference Device Management Client example application. It runs on K64F and Wi-Fi configuration without a filesystem or external flash.