Performance - JawaharT/Best-Practices-On-Azure-Sphere GitHub Wiki

Introduction

In this section, you will learn the important aspects of performance for embedded systems. This is achieved by using the limited resources as and when required and taking advantage of the architecture of the system. Moreover, with the Azure Sphere, the best and simplest way is to manage memory and use built-in modules. These best practices will guide you to manage an embedded system as most have to rely on none or passive cooling.

Why Is Performance Important?

In general, performance is an important aspect of devices and systems but due to the limited resources available to embedded systems, it is important to utilise every aspect. For example, the balance between performance and energy savings (as part of power management) in high-level applications. Azure Sphere power APIs are used to enable devices to go into low power states to support running on batteries, here are the different states:

  • PowerSaver: Low performance for power longevity

  • Balanced: Performance and power is equal with respect to system load

  • HighPerformance: High power consumption for optimum performance

There are methods the developer can perform such as:

  • For all systems not necessarily limited to embedded systems and depending on your application, it is a good idea to limit remote communication, using the doctrine: “chunky not chatty”. 'Chunky' refers to sending data in blocks as opposed to 'chatty' which sends data in smaller frequent chunks.

  • When not being used to its full extent or running on batteries it is best if the developer saves memory state inside flash storage before sending the device to deep sleep. In Azure Sphere, the developer can put the device into a power-down state (penultimate state to switch off) this will power down everything other than the Real-time clock and can only reawaken the device if the wakeup pin is triggered or after a specific time period has elapsed. This can be used to conserve power during uneventful periods where the device is not used

  • Switch off peripherals when not in use (i.e. polling timers for peripherals in Azure Sphere high-level applications)

Deterministic Behaviour

Azure Sphere is built with the capabilities of real-time applications due to the purpose-built ARM Cortex-M processor as part of its MCU architecture. So, it is possible to develop a range of real-time/deterministic devices that could be built on Azure Sphere. The purpose of this section is for you to understand the possibilities and use cases of embedded systems available and take advantage of these behaviours.

Deterministic behaviour can be linked to performance which varies between the kind of device. Deterministic behaviour means the code needs to be executed within a given constraint and perform correctly as expected during a provided time window.

Real-time processing is through software to process data and provide an accurate output. Due to the deterministic behaviour, it means the device will complete a known task with correct output in the time allocated. Real-time systems such as the examples shown below are exhibit deterministic behaviour and some show real-time processing.

Examples of real-time and non-real-time systems

Real-time systems:

Industry Applications (behaviour type)
Healthcare Surgical Robots (deterministic and real-time processing), Patient monitoring (real-time processing), Epidemic Trackers (real-time processing)
Aviation Satellite Tracking systems (real-time processing), Flight Simulators (real-time processing)
Transportation Autopilot system in self-driving cars (deterministic and real-time processing), Navigation systems (real-time processing)
Military Radar systems (deterministic), Antimissile systems (real-time processing)

Epidemic tracker applications for citizens that use contact tracing use real-time processing to send alerts to other contacts in the case of a positive test, for quarantine purposes as well as to contain the spread of the virus. Satellite Tracking systems for Navigation use real-time processing because they need to pinpoint exactly where the source signal is to provide accurate timely guidance to the destination as well as track progress (in any industry from flights to cars). Antimissile systems need to determine and accurately predict the missile trajectory which can only be achieved through real-time sensor telemetry processing to prevent missiles from reaching the target.

The Azure Sphere has two ARM Cortex M4 cores inside the system on a chip (MT3620) to perform real-time processing. These M4 cores are for support of the real-time operating system and to perform real-time processing on the device. A real-time operating system (RTOS) is software that processes data coming in without buffer delays. A typical operating system deals with hardware resources as well as hosting applications but an RTOS also has to perform tasks with precise timing. Microsoft offers a standalone RTOS called Azure RTOS. Azure RTOS can be used if you already have embedded devices such as Raspberry Pis but only need real-time functionality with them. but the complete solution with the Azure Sphere is best in terms of cybersecurity challenges over the internet and for real-time processing.

Non-Real-time systems:

Most systems under this category are not related to embedded systems such as software applications like Internet forums, email, and accounting programs.

Handling Memory

Handling memory is also important for performance for small, embedded devices that have very little RAM onboard. It is important to have no memory leaks, these occur when allocated memory is not freed. This can lead to crashes as there is a memory block that is being wasted. if not handled correctly.

The best ways of handling these memory leaks:

  • Allocate all memory that is to be used upfront
  • Free all manually allocated memory using the free function as mentioned in section 2 (heap management)
  • Use a heap debugger to keep track of assigned memory (i.e. available on modern IDEs such as Visual Studio or Visual Studio Code)

Memory leaks can be hard to find especially if there are dynamically assigned but it is important to ensure that there are no memory leaks. This is your responsibility as the developer to clean it up by freeing memory when completed with it or during application exit.

Use of built-in C Runtime functions

There is no need to reinvent the wheel if not required, saves development time and can be safer to use than creating a unique version. This will ensure a small codebase that you can be confident that there will be no memory leaks if the correct version that considers memory presence is used. Also, it is important to understand the small differences between these built-in functions, for example, the strcpy and strncpy functions which have very similar purposes (i.e. are used to copy the contents of one string variable to another) but strncpy is clearly the better choice for embedded systems. The examples below will justify this choice.

Use of strcpy:

#include <stdio.h>
#include <string.h>

int main() {
    char original[] = "String";
    char copy[5];
    
    printf("%s\n", original);
    strcpy(copy, original);
    
    printf("%s\n", copy);
    return 0;
}

For embedded systems, strncpy is the best function to use for copying a string. This is because strncpy will only copy a portion of the string if the destination string length is less than the source string, which will prevent a buffer overflow inside the destination string.

Output:

String
String

Use of strncpy:

#include <stdio.h>
#include <string.h>

int main() {
    char original[] = "String81314";
    char copy[7];
    
    printf("%s\n", original);
    strncpy(copy, original, 6);
    
    printf("%s\n", copy);
    return 0;
}

With the use of strncpy, we can see that the third argument limits exactly the amount to copy even if the original contains a longer string than anticipated. So it is the better string copy function to use in this particular application. It is important as an embedded systems developer to find and develop functions that always have the limited resources of the SOC in mind to avoid crashes that may not occur on the desktop.

Output:

String81314
String

Strncpy has its third argument as six even though the string size allocation is seven because strings are considered as a one-dimensional array of characters which is expressed below:

// This is to show that a string is seen as a collection of individual characters, not as a specific string data type in C 
// ‘\0’ - denotes the end of the string, so a six-character string requires a size 7 array
char original[] = {'S', 't', 'r', 'i', 'n', 'g', '\0'};

Summary

To summarise this section provides details into how you could manage the performance of your Azure Sphere device. Specific C best practices to use inside your applications such as the best built-in functions for embedded solutions for optimum memory management. The basics of real-time systems, real-time processing, and deterministic behaviours and their purpose are also described.

⚠️ **GitHub.com Fallback** ⚠️