mbed Blog

Optimizing memory usage in mbed OS 5.2

Three months ago we released mbed OS 5, the latest version of our operating system for microcontrollers. While we added a lot of new features - including an RTOS - we also saw a bigger than expected increase in flash and RAM usage, two things that are scarce on embedded devices. Reason for Vincent Coubard, Senior Software Engineer on the mbed team, to dig through the .map files and see how we can decrease memory usage in mbed OS.

Comparison with mbed 2.0

First, we need some baseline numbers. When compiling blinky - a simple program that just flashes an LED - on mbed 2.0, we see about 5K static RAM, and around 38K flash used (compiled with GCC 4.9.3 on the FRDM-K64F):

Allocated Heap: 65536 bytes
Allocated Stack: 32768 bytes
Total Static RAM memory (data + bss): 5128 bytes
Total RAM memory (data + bss + heap + stack): 103432 bytes
Total Flash memory (text + data + misc): 37943 bytes

When we compile the same program on mbed OS 5.1.2 we see a large increase in both RAM and flash usage, to almost 13K static RAM, and about 57K flash:

Allocated Heap: 65536 bytes
Allocated Stack: unknown
Total Static RAM memory (data + bss): 12832 bytes
Total RAM memory (data + bss + heap + stack): 78368 bytes
Total Flash memory (text + data + misc): 57284 bytes

Removing unused modules

To see where that memory went we can first look at how memory usage is split between different modules:

+---------------------+-------+-------+-------+
| Module              | .text | .data |  .bss |
+---------------------+-------+-------+-------+
| Fill                |   132 |     4 |  2377 |
| Misc                | 28807 |  2216 |    88 |
| features/frameworks |  4236 |    52 |   744 |
| hal/common          |  2745 |     4 |   325 |
| hal/targets         | 12172 |    12 |   200 |
| rtos/rtos           |   119 |     4 |     0 |
| rtos/rtx            |  5721 |    20 |  6786 |
| Subtotals           | 53932 |  2312 | 10520 |
+---------------------+-------+-------+-------+

Most of this is normal; we're loading the hardware abstraction layer and the RTOS, but we also see features/frameworks. That is weird, as that is where our test tools live. We happen to build one of our test harnesses into every binary. What a waste! By eliminating this module we save about 1K of RAM and a whopping 8K of flash:

Total Static RAM memory (data + bss): 11808 bytes
Total RAM memory (data + bss + heap + stack): 77344 bytes
Total Flash memory (text + data + misc): 49807 bytes

Printf and UART

The next target would be the Misc module with around 28K of flash used. When we look at a visual representation of the memory map for our program, we see the UART driver and various functions related to printf being compiled in. That is suspicious, given that we are not using either in our program.

/media/uploads/janjongboom/memory1.png

Visualization of our memory map showing the UART and printf functions in the top right corner.

We found that this was related to how we do traces and assertions in some of our modules, always redirecting error messages to printf. Whenever someone uses a single printf we need to compile in both the library and the UART driver (for serial communication). That is a huge overhead for something that is not actually used. While traces and assertions are very useful during development and in debug builds, we want them completely removed in release builds.

We already complied with standard C by not tracing in assertion code (assert and MBED_ASSERT functions) when NDEBUG is defined, but still wrote traces in error functions. By altering our drivers (1, 2) to fully disable logging to serial output on errors when NDEBUG is defined, we save 28K(!) of flash (but no RAM):

Total Static RAM memory (data + bss): 11808 bytes
Total RAM memory (data + bss + heap + stack): 77344 bytes
Total Flash memory (text + data + misc): 21244 bytes

To disable this feature you need to set the NDEBUG macro and the following configuration parameter in your mbed_app.json file:

{
    "macros": [ 
        "NDEBUG=1"
    ],
    "target_overrides": {
        "*": {
            "core.stdio-flush-at-exit": false
        }
    }
}

Some more information can be found in this comment.

Note: Different compilers, different results; when compiling with ARMCC the printf and UART libraries only cost 14K of flash.

No need for destruction

We can also take advantage of the fact that we run our programs only on embedded targets. When you run a C++ application on a desktop computer, the runtime constructs every global C++ object before main is called. It also registers a handle to destroy these objects when the program ends. This is injected by the compiler and has some implications for the application:

  • The code injected by the compiler consumes memory.
  • It implies dynamic memory allocation, and thus requires malloc and friends to be included in the binary, even when not used by the application.

When we run an application on an embedded device we don't need handlers to destroy objects when the program exits, because the application will never end. By removing the registration of destructors on application startup, and by eliminating the code to destruct objects when exit() is called, we can shave off another 2.5K of RAM and an additional 8K of flash:

Total Static RAM memory (data + bss): 8008 bytes
Total RAM memory (data + bss + heap + stack): 73544 bytes
Total Flash memory (text + data + misc): 14102 bytes

Conclusion

Together these three optimizations gave us a huge decrease of both static RAM (47%) and flash (2.69x less) usage. Compared with mbed 2.0 we use 3K more RAM - which is mainly due to the inclusion of mbed RTOS - but we use only half the flash. We'll continue to make improvements on this in the near future. All patches have landed and are included in mbed OS 5.2.

-

This article was written by Vincent Coubard (Senior Software Engineer) and Jan Jongboom (Developer Evangelist IoT).

Using Bluetooth Low Energy from JavaScript on mbed

Some time ago we blogged about adding JavaScript support for mbed OS 5 through the JerryScript VM. In this blog post we'll show how you can use the Bluetooth Low Energy API from a JavaScript application. Writing your BLE application in JavaScript on mbed means enjoying the flexibility of a dynamic language while leveraging the well tested, widely used and battery friendly mbed BLE API.

In this article we'll write a small program in JavaScript that allows us to control an LED on our development board from a smartphone.

Prerequisites

You will need a development board capable of running mbed OS 5 with at least 64K of RAM, like the Nordic Semiconductors nRF52-DK. If your board does not have an on-board BLE chip you'll also need a Bluetooth shield.

In addition you'll need the following software:

Getting started

Open a terminal window and run:

$ git clone https://github.com/ARMmbed/mbed-js-ble-example
$ cd mbed-js-ble-example
$ npm install

This will clone the example program, and install all dependencies (mbed OS 5, JerryScript and the JS BLE wrapper).

If you are using the IDB05A1 Bluetooth shield, open mbed-js-ble-example/build/jerryscript/targets/mbedos5/mbed_app.json and replace the content with:

{
        "*": {
            "target.features_add": ["BLE"],
            "target.extra_labels_add": ["ST_BLUENRG"],
            "target.macros_add": ["IDB0XA1_D13_PATCH"]
        }
    }
}

If you're using an ST NUCLEO board (like the F401RE or F411RE), remove the line that starts with target.macros_add.

Now we can build our program. Run (change NRF52_DK to your target name):

$ gulp --target=NRF52_DK

The binary will be in build/out/TARGETNAME/ and will be named mbedos5.hex or mbedos5.bin (depending on your target; see the last line of the build output). Use drag-and-drop programming to flash the program on your board.

Interacting with the device

After flashing the device will be broadcasting under the name `Battery Device` with two services: a battery service and an LED control service. You can use a Bluetooth monitor like nRF Connect) to view the device and interact with its characteristics.

/media/uploads/janjongboom/jsble1a.png /media/uploads/janjongboom/jsble2a.png

Scanning for the device, and then seeing the device services after connecting using nRF Connect for Android.

To toggle the LED write 00 or 01 as a byte array to characteristic 9871.

JavaScript API

To change the program open main.js. This file has access to all BLE functions.

var controlLed = DigitalOut(LED1);		// LED controllable through BLE

// global BLE object
var ble = BLEDevice();

// Define a new service and a characteristic. 
// Characteristic takes in: char UUID (16 bit only for now), array of permissable actions (read, write or notify), and a packet size (in this case 1 byte).
var batteryChar = BLECharacteristic('2a19', ['read', 'notify'], 1);
// Service takes in: service UUID (16 bit only), and an array of characteristics
var batteryService = BLEService('180f', [batteryChar]);
var batteryLevel = 100;

// If a characteristic has 'write' enabled you can register an 'onUpdate' callback, which will fire when the char is being written over BLE
var ledChar = BLECharacteristic('9871', ['read', 'write'], 1);
ledChar.onUpdate(function(newValue) {
    // newValue is an array of bytes. You can also get the value through 'ledChar.read()'
    print('Updated ledChar, newValue is ' + (newValue[0] ? 'on' : 'off'));
    // LED 0/1 are switched on the nRF52-DK. Might need to change for your platform.
    controlLed.write(newValue[0] ? 0 : 1);
});
var ledService = BLEService('9870', [ ledChar ]);

print('created variables');

ble.onConnection(function() {
    print('GATT connected');
});

ble.onDisconnection(function() {
    print('GATT disconnected');

    ble.startAdvertising();
});

ble.ready(function() {
    print('ble stack ready');
    ble.addServices([
        batteryService,
        ledService
    ]);
    // startAdvertising takes a third argument as well (interval), default value is 1000 (ms).
    ble.startAdvertising('Battery Device', [
        batteryService.getUUID(),
        ledService.getUUID()
    ]);

    // writing to a characteristic by sending a byte array
    ledChar.write([ controlLed.read() ? 0 : 1 ]);
});

// We can schedule code by using normal JS constructs like setInterval and setTimeout
setInterval(function() {
    blink();

    // if we're connected we'll update the value of the battery characteristic
    if (ble.isConnected()) {
        batteryChar.write([batteryLevel]);

        batteryLevel--;
        if (batteryLevel <= 0) {
            batteryLevel = 100;
        }
    }
}, 1000);

print('main.js has finished executing.');

Note: To see debug messages (print calls), connect a serial monitor to the device and listen on baud rate 115200.

From here it's easy to use other peripherals, load drivers and create new services and characteristics. If you're interested in porting new peripheral drivers, see: Using mbed libraries with JerryScript.

Conclusion

By porting the mbed BLE API for JavaScript we can combine a well-tested and performant BLE stack and run it in a dynamic virtual machine runtime. This allows for quicker prototyping, fewer errors, and writing code without having to deal with ISRs or context switching - while still maintaining proper battery life, and the ability to run your code on a low-cost microcontroller. Combined with Web Bluetooth, you can write your embedded client and application in a single language.

When porting this library we've also experimented with ways to distribute mbed libraries and their JS wrappers through npm - rather than through mbed CLI - and we'll continue this work for the rest of the year. We also presented our work on JavaScript on mbed during JSConf.asia 2016 last week, and you can find the video here:

-

Jan Jongboom is Developer Evangelist IoT at ARM and has warm feelings for both C++ and JavaScript.

Highlights from mbed Connect USA to ARM TechCon 2016

/media/uploads/katiedmo/mbedconnectbannerchina.png Needless to say, last week was extremely busy for the mbed Team. Monday Oct 24 kicked off with our first developer summit event, ARM mbed Connect – USA, followed by the announcement of the new mbed Cloud services and the mbed Zone at ARM TechCon 2016.

mbed Connect

This year at mbed Connect, we brought together not only the mbed partnership but the mbed developer community. With 99 companies represented and mbed team members from over 14 different countries on location, we were able to showcase a diverse group of dedicated IoT experts, evangelists, and engineers. See what everyone was talking about during the event here!

Join us at our next event in Shenzhen, China on December 5. Register before tickets run out!

10 highlights from mbed Connect – USA

/media/uploads/katiedmo/2-michael-accelerating_i-p-v_with_iot_-2310_mthv1.jpg

  • ARM’s first IoT invention was a connected toaster – Your toast can tell you the weather forecast for the day.
  • “Learn how to see. Realize that everything connects to everything else.” - Leonardo da Vinci
  • “There were 15 billion ARM based devices shipped in 2015 alone,” and they are landing in IoT applications.
  • Using the connectivity interplay of technologies is the best advantage of IoT.
    • Bluetooth 5.0 will improve coverage by 5x.
    • Mission-critical services will be optimized by 1ms latency and 10 / even 20Gbps of throughput per connection that will unleash the smart connected world.
    • LoRa will help to connect long-range devices and networks up to 30 miles apart.
  • mbed OS bridges the rich ecosystem of chips, technologies software and middleware that our partnership provides and offers a layer through which driver portability, development tools, security, connectivity and the kernel can power developer productivity.
  • mbed OS 5.2 headline features:
    • Wi-Fi SoC and module support
    • Hardware entropy support
    • Memory footprint profiling
  • The micro:bit’s goal is to lower barriers to technology invention for young people. They have had nearly 2 million compiles to devices and 10 million code simulator runs.
  • IoT security challenges of IoT must be thought through holistically…Across the hardware, across the device software (looking at strong isolation), across communication layers and all the way to the cloud.
  • “IP connectivity will win the day” – Bill Curtis, Thread board member
  • “Supply chain vocabulary [for enterprise industries] will take time [to learn], the challenge is translating the benefits” of IoT for each industry. – Thomas Kurian, IoT strategy & new business development expert, Zebra Technologies Corporation

/media/uploads/katiedmo/mbedconnect_2016.jpg

ARM TechCon 2016

The new mbed Cloud services announced!

mbed Cloud is a device management solution optimized for IoT which reduces operational costs and enables new value generating services in a secure way. According to Device Pilot Device Management Survey 2016, “86% of companies reporting device management to be the key issue”. mbed Cloud provides one solution for any device, any network. To find out more about mbed Cloud and request access, check out cloud.mbed.com.

mbed Zone at ARM TechCon

At the mbed Zone, over 21 partners showcased their mbed technologies and commercially available technologies including Avnet, Accenture, Bosch, MultiTech, NXP, OnSemi, Silicon Labs, Toshiba, u-blox, Spirent, Device Pilot, Spindance, ComTech Telecommunications, IBM, Micrium, Nuvoton, and Elan Microelectronics. In which NXP took home best IoT product, best in show and readers choice for the Hexiwear wearables development platform and Device Pilot for best software product.

In addition, we featured 6 mbed demos, from the latest mbed OS technology to the first peek at the new mbed Cloud services. We also showcased a smart enterprise building lighting solution with OpenAIS, HPE’s smart factory to improve health and safety of factory workers, Zebra’s smart refrigerator food safety reference design, and last but certainly the not least, the micro:bit demonstrating the creative possibilities that kids can unleash with this simple embedded development board.

/media/uploads/katiedmo/20161026_150428.jpg /media/uploads/katiedmo/20161026_150421.jpg /media/uploads/katiedmo/20161026_145700.jpg

Now the team is gearing up for mbed Connect – China in just a few weeks. If we didn’t get the chance to connect with you last week in California, we hope to see you in Shenzhen!

Winner of the Hackster.io Hexiwear Contest!

With more than 1000 participants and 65 projects submitted for the Hackster.io Hexiwear contest, it was incredibly difficult for the selection committee to choose a winner for the best mbed Enabled project. There were plenty of fantastic ideas and the competition was fierce!

/media/uploads/dirons/hexiwarembed_ZNS1Iim.png

We’re pleased to announce today that the grand prize for the best ARM mbed design has been awarded to Hexy, a virtual pet that spurs good decisions!

Hexy is a wearable activity monitor built using the NXP Hexiwear development platform alongside ARM mbed OS and Compiler, which transmits different reactions to movement (or lack thereof) on the Hexiwear’s LED display. The cute virtual pet stays happy, as long as the wearer continues to be active. As soon as they get lazy and stop moving, the onboard sensors stop receiving data and Hexy gets mad, displaying an irritated red emoji, encouraging users to be active.

/media/uploads/dirons/hexy.png

Congratulations to Hexy’s creator, Hackster.io user Ish Ot Jr, who will be receiving an Occulus Rift VR headset as his prize.

Thanks to all the participants for your creativity and ingenuity, keep up the great work!

Whitepaper: Managing Internet of Things Devices with the Lightweight Machine-to-Machine (LWM2M) Protocol

Connecting Internet of Things (IoT) devices to the Internet and managing them offers many benefits but also requires more complex software stacks on IoT devices. The days of in-house designs of operating systems and communication protocol stacks are numbered.

The good news is that there is no need to recruit a team of experts in every aspect of security, network stacks or technology standards in order to develop an IoT product – simply take advantage of the industry's largest ecosystem, saving on months of development costs.

By building on top of Internet standards with mature implementations, you can significantly reduce your development time, leading to a faster time to market. As an additional side effect of using the standards described below, you benefit from an energy efficient standards-based communication, with state-of-the-art security.

Thanks to the ever-increasing deployment of IoT devices, companies are now faced with a number of challenges independent of the vertical where these products are used, such as:

  • How to let customers control their devices in a (near) real-time fashion over the internet.
  • How to collect sensor data from these devices securely so that value-added services, such as analytics, can be provided.
  • How to update the software of these devices once they are deployed.
  • How to obtain statistics and trouble-shooting information to determine failure causes and to offer customer support when devices malfunction.
  • How to manage these devices over their lifetime, including the provisioning of security credentials and distribution of access control lists, to ensure that only entitled parties can access sensitive data.

The Lightweight Machine to Machine (LWM2M) protocol developed by the Open Mobile Alliance (OMA) is a technology that addresses these challenges and has been successfully deployed in smart city, smart manufacturing and asset management applications.

Interested in OMA’s LWM2M protocol and how it can solve some of IoT’s biggest challenges? Request a download link for this whitepaper!