Status

Date

Doc Version

Applicable

Confidentiality

RELEASED

v1.0

Wirepas Massive V5.x

PUBLIC

Introduction

This document describes how the Wirepas Massive Bootloader works and how the flash memory is organized when using Wirepas stack and SDK

What you’ll learn

  • How Wirepas Massive bootloader works
  • How the flash memory is organized and how it can be customized.

What you’ll need

  • Basic knowledge of Wirepas Massive is a plus. You can refer to the Wirepas Massive Concept document [1] for more details.
  • Because Bootloader is also linked to Over The Air Programming (OTAP), it is recommended to read the Wirepas Massive OTAP Application Note [2] prior to this document

Wirepas Flash structure

Wirepas Massive SDK and deliverables support multiple product configurations to allow to develop different product architectures. Typically a device running Wirepas Massive will run the Stack and an Application but other memory components can be added for example for application storage.

The default memory map of a device running Wirepas is presented below:

 Here is the description of each memory regions:

  • Bootloader: This is the Wirepas bootloader. It is described in the following chapter
    • BLCONFIG: Located at the end of the bootloader and contains its configuration (areas descriptions and OTAP keys).
      NOTE: BLCONFIG is generated at compile-time and can’t be modified after the device has been programmed.
  • Wirepas Stack: The Wirepas Massive stack firmware
  • Application: An application that runs alongside the stack firmware and is by default shared with the scratchpad and automatically managed by the bootloader. The scratchpad is written from the end of this memory region.
    Note: It is also possible to have a dedicated area for scratchpad allowing to have a fixed chunk of memory allocated for that purpose (supported on both internal or external flash).
  • App persistent: Starting from Wirepas Massive v5.1, the SDK reserves 16kB of flash memory solely for the application.
  • Persistent: Stored settings for stack firmware and application

About application size and scratchpad

By default, the scratchpad is stored in the same memory region as the application. It means that the maximum size of the scratchpad a device can store will depend on the application size. Depending on the total available flash of the microcontroller (MCU) the available space for the application + scratchpad varies between 232kB (for 512kB MCUs) and 748kB (for 1MB MCUs).

The bootloader maximizes the size left for the scratchpad based on the real size of the application (also to avoid a scratchpad to overwrite the application itself). For obvious reasons, the scratchpad area shall be large enough to store an OTAP image. Hence the size of the application shall remain aligned with the total available size of the application area and the targeted use cases.

Note: In case of an heterogenous network, the nodes having the smallest memory footprint are the limiting one for OTAP. It is highly recommended to ensure that the available smallest scratchpad area still allows to store any scratchpad to ensure proper OTAP.

About application size

By default a maximum application size is set in the SDK linker script for the application size (40KB for 512kB SoCs and 256kb for 1MB SoCs). This limit is here more to act as a warning rather than being a hard limit as per the previous explanation related to the Application area partitioning. It is possible to change those limits based on product needs keeping in mind to ensure a coherent flash memory map to ensure scratchpad storage and OTAP in the product.

Area organization

Description

The bootloader uses the concept of area to manage its memory regions. Instead of having hardcoded addresses in its code to know the location of each component, the bootloader maintains a list of areas that contain this information.

Up to 8 areas can be defined in the bootloader. They are defined and can be modified in the SDK. And they are stored inside the BLCONFIG when the device is flashed. This means that once flashed, it is not possible to modify the area list defined in a device for the lifetime of the product.

Each area defined in the bootloader has the following information:

Name

Description

Note

ID

32bit identifier

 

Address

Start address of the area in flash

Must start on a flash page boundary

Length

Size of the area in bytes

Must be a multiple of flash pages

Flag: Store version

Boolean, tells the bootloader to store a special header when updating this area.

The content of this header can be read using “MSAP Scratchpad Status” remote API command.

Flag : External flash

Boolean, indicate if the area is in internal or external flash

Only Scratchpad and User areas can be in external flash

Flag: Type

The type of Area:

  • Bootloader
  • Stack
  • Application
  • Persistent
  • Scratchpad
  • User

 

 

As an example, the below table describes the default area list for Nordic Semiconductor nRF52832 memory map that was described in the previous chapter :

Name

ID

Address

Length

Store version

External flash

Type

bootloader

0x000000 | HW_MAGIC

0x00000000

16k

false

false

BOOTLOADER

firmware

STACK_AREA_ID

0x00004000

240k

true

false

STACK

application

APP_AREA_ID

0x00040000

232kB

true

false

APPLICATION

app_persistent

0x8AE573BA

0x0007A000

16k

false

false

USER

persistent

0x200000 | HW_MAGIC

0x0007E000

8k

false

false

PERSISTENT

What are STACK_AREA_ID, APP_AREA_ID, HW_MAGIC?

HW_MAGIC: This is an 8 bit number used to identify the type of micro-controller the stack is running on. It is defined by Wirepas and can’t be modified. This value can be found in cHwMagic field here [5]

STACK_AREA_ID: This is the area ID of the stack, its value is 0x000001xx. xx the lowest 8bits is the HW_MAGIC. Each architecture has a different HW_MAGIC & STACK_AREA_ID so that loading a scratchpad from an incompatible architecture will not cause the stack firmware to get corrupted.

APP_AREA_ID: This is the area ID of the application, it is a combination of the HW_MAGIC, and the app_specific_area_id. app_specific_area_id consist of the 24 high bits of APP_AREA_ID and is defined for each application in source/xxx_apps/<app_name>/config.mk file.

Relation with OTAP

As explained previously, each memory area is identified by a 32-bit ID. The list of areas is stored in the bootloader BLCONFIG. A scratchpad image is a collection of binary files, each of these files being identified by an area id.

When processing a scratchpad, the bootloader will read the id of each file. Then it updates the corresponding area whose area id is matching the one in the scratchpad file (assuming that the bootloader was able to authenticate the scratchpad, see [2]).

Wirepas Bootloader

Wirepas Bootloader is part of the Wirepas deliverables and is provided together with the Wirepas Massive Stack. The bootloader is responsible for the initial boot and management of the Over The Air Programming (OTAP).

The following chapters will explain how the Bootloader works and how it can be configured. The bootloader can be further customized for some special needs, i.e. external flash support and init functions. Please refer to the ‘Wirepas Massive Bootloader Development Guide' [3] for more information.

What does the bootloader do?

The diagram below describes the typical Bootloader execution flow:

The bootloader is divided into 4 main tasks:

  • System initialization
  • Scratchpad validity check
    • The bootloader verifies the scratchpad is present in memory and that it is valid.
  • Scratchpad processing
    • The scratchpad is processed and the areas updated by the bootloader, if needed.
  • The Bootloader always terminates by calling the stack entry point.

These 4 tasks are further described in the following sections.

System initialization

During the System Init, clocks and memory are initialized. It is possible to customize the bootloader to call a function ‘First Boot’ at first boot (before the debug port is locked) and early during the boot sequence ‘Early init’. Please refer to the Wirepas Massive Bootloader Development Guide [3] for more information.

Scratchpad validity check

Once the system is initialized, the bootloader will look for the scratchpad in the memory. It can be located in the following places:

  • At the end of the application area.
    • This is the default place where the scratchpad is be stored
  • In a dedicated scratchpad area:
    • In internal memory.
      • See below how to add a dedicated scratchpad area.
    • In external memory
      • See [3] to customize the bootloader with a flash driver to store the scratchpad in an external flash chipset.

Each scratchpad image is encrypted and authenticated. Once the scratchpad is found, the bootloader will try to authenticate it. Up to 28 key pairs (authentication key, encryption key) are stored in the bootloader BLCONFIG. It will try all of the keys until one is found that is able to authenticate the scratchpad.

If the bootloader fails to authenticate the scratchpad or if none is present, it will start the stack directly. 

Process the scratchpad

Once the scratchpad image is authenticated, the bootloader possesses the encryption key to decrypt its content.

As the scratchpad is a collection of files, the bootloader will iterate over each one and will try to process them. Each file contains a header with the Area id it is linked to. If the ID of the file matches one of the areas defined in the bootloader, it will process this file. Otherwise, it will skip it and move to the next one.

The following steps are executed to process a file and update an area:

  • Erasing the corresponding area.
  • Decompress/decrypt the file to RAM
  • Write the data to the area.

Once all files in the scratchpad have been processed, the update is finished and the bootloader will call the stack entry point.

Customizing the bootloader keys and Areas

At the end of the build process, 3 files are used to generate the BLCONFIG of the bootloader. These files describe the areas and keys for the bootloader:

  • custom_bootloader_keys.ini: The list of key pairs.
  • mcu/<mcu_name>/ini_files/<mcu_name>_wp.ini : List of areas reserved by Wirepas Stack and which can’t be changed.
  • mcu/<mcu_name>/ini_files/<mcu_name>_app.ini : List of areas that can be modified.

These 3 files are merged together at compile-time and contain the exact bootloader configuration. The merged file is located in the application build folder (build/<board_name>/<app_name>/bootloader_full_config.ini) and must be used to check the bootloader configuration.

The built image build/<board_name>/<app_name>/final_image_<app_name>.hex contains the bootloader and its configuration BLCONFIG (+ stack & application). Once the device is flashed, it will be impossible to modify the keys and the areas for the lifetime of the product. 

The following sections describe how these files can be modified (or replaced) to fit the application needs.

Adding a User Memory Area

For some applications it can be useful to have a dedicated memory area to store parameters or configurations. This can be done by defining a User memory area. This area type is only used by the application and can be accessed with the memory area library (see [4] for API description). It can also be updated through OTAP, independently from the application.

The User area is defined by adding a new area to the mcu/<mcu_name>/ini_files/<mcu_name>_app.ini file with the following parameters:

[area:user_area_name]
id      = 0x8xxxxxxx     ; Top bit (bit 31) must be 1.
address = 0x00080000     ; Area start address
length  = 524288         ; Length in bytes : 512 kB
flags   = 0x00000016     ; Don’t store version; ext flash; User area

Figure 2: Example of User area definition

Parameter

Purpose

[area:…]

Name of the user memory area. Name is for documentation purposes only.

id = …

32-bit memory area ID. Bit 31 must be 1. 

address = …

Start address of memory area. Must be aligned with a Flash erase block start address.

length = …

Length of memory area, in bytes. Must be a multiple of Flash erase block length.

flags = …

Flags: 0x16 for User area in external memory; 0x14 for User area in internal memory

Table 3: User area parameters

Note: User area in the internal flash is always located between the application area and the persistent area, as these two areas are used by the stack and cannot be moved.

Dedicated Scratchpad Area

By default, the scratchpad is stored at the end of the application area. It means that the maximum memory allocated to the scratchpad varies with the size of the application. The bootloader can be configured to store the scratchpad in a dedicated area. This area can be either in an internal or an external flash memory (if the external flash driver has been implemented).

First a Scratchpad area must be declared in the mcu/<mcu_name>/ini_files/<mcu_name>_app.ini file with the following parameters:

[area:scratchpad_area_name]
id      = 0x30000003  ; Area ID: HWM_NRF52832_SP_2 | 0x30000000
address = 0x00080000  ; Area start address
length  = 524288      ; Length in bytes : 512 kB 
flags   = 0x00000012  ; External flash, Scratchpad area

Figure 3: Example of Scratchpad area definition

Parameter

Purpose

[area:…]

Name of the scratchpad memory area.

id = …

32-bit memory area ID. 0x300000xx for scratchpad area. The lower byte is the hardware magic of the radio hardware used, this value can be found in [5].

address = …

Start address of memory area. Must be aligned with a Flash erase block start address.

length = …

Length of memory area, in bytes. Must be a multiple of Flash erase block length.

flags = …

Flags: 0x12 for Scratchpad area in external memory; 0x10 for Scratchpad area in internal memory

 Table 4: Scratchpad area parameters

Then the scratchpad section must be modified so that its area matches the one defined above:

; Scratchpad location in Flash memory
[scratchpad]
area = "scratchpad_area_name"   ; Area where scratchpad will be stored

Figure 4: Define the area where the scratchpad is located

Modifying the Application Size

By default, the Application area occupies all the free flash that is left in the device. If User areas have been added to the internal flash, the application area size must be reduced to match the real amount of memory that is left for it.

[area:application]
id      = APP_AREA_ID   ;
address = 0x00040000    ;
length  = 245760        ; Adjust length to remaining memory.
flags   = 0x00000009    ;

Building with a Custom Scratchpad File

By default, all applications use the same .ini file stored in mcu/<mcu_name>/ini_files/<mcu_name>_app.ini but it can be copied to the application folder and modified if needed. The new .ini file can be specified from the application config.mk as followed:

# Define a specific scratchpad ini
INI_FILE_APP = $(APP_SRCS_PATH)/scratchpad_custom.ini

Otherwise, the location of the .ini file can be given to the command line with INI_FILE_APP= when building.

e.g. make target_board=pca10040 app_name=custom_app INI_FILE_APP=<path_of_ini_file>

Bootloader keys

The bootloader can store up to 28 key pairs in its BLCONFIG. A key pair consists of:

  • An authentication key: used to authenticate a scratchpad image before processing it.
  • An encryption key: used to decrypt the binary files contained in the scratchpad image.

When authenticating a scratchpad image, the bootloader will try all the keys in its BLCONFIG. It is mandatory that one of these keys has been used to generate (encrypt & authenticate) the scratchpad image. Otherwise, the bootloader won’t be able to process it.

Building with a Custom Key File

By default, all applications use the same custom_bootloader_keys.ini file stored at the root of the SDK but it can be copied elsewhere to the application folder and modified as needed. The new key file can be specified from the application config.mk as followed:

# Define a specific scratchpad ini
KEY_FILE = $(APP_SRCS_PATH)/custom_bootloader_keys.ini

Otherwise, the location of the key file can be given to the command line with KEY_FILE= when the application has been built.

e.g. make target_board=pca10040 app_name=custom_app KEY_FILE=<path_of_key_file>

References

[1] Wirepas Mesh Concepts
[2] Wirepas Mesh OTAP Application Note
[3] Wirepas Mesh Bootloader Development Guide 
[4] https://wirepas.github.io/wm-sdk/master/df/d08/memory__area_8h.html
[5] Wirepas Mesh Dual-MCU API Reference Manual

Date

Version

Notes

v1.0

Initial version.

Legal Notice

Use of this document is strictly subject to Wirepas’ Terms of Use and Legal Notice.

Copyright © 2021 Wirepas Oy