STM32CubeWBA: Flash management

1. Introduction

Flash management proposes a simple interface to the upper layers to execute operations in flash memory. It manages synchronization between flash operations and the RF activity. Thus, users do not have to add the step of synchronizing RF timing and flash operations.

2. Concepts

This chapter deals with the major concepts and features of the flash management. The flash management is a multi-layer organization that relies on different concepts. The most important concepts are described below.

2.1. Organization

Flash management is based on a 5 layers distribution composed of:

Flash management overview
Flash management overview
Simple NVM Arbiter
Specific flash interface that emulates the behavior of multiple Non Volatile Memories (NVM).
Related files
  • simple_nvm_arbiter_common.h:
Common header of the SNVMA module. It contains definitions and type definitions.
  • simple_nvm_arbiter.h:
Header of the SNVMA module. It contains the function prototypes.
  • simple_nvm_arbiter.c:
Source file of the SNVMA module.
Flash manager
Main user interface for flash operation (flash write, flash erase, etc.).
Related files
  • flash_manager.h:
Header of the Flash manager module. It contains function prototypes, definitions, and type definitions.
  • flash_manager.c:
Source file of the Flash manager module.
RF Timing synchro
Module that realizes synchronization between Bluetooth® LE Link Layer and flash operations by activating or deactivating the dedicated flash control status.
Related files
  • rf_timing_synchro.h:
Header of the RF timing synchro module. It contains function prototypes, definitions, and type definitions.
  • rf_timing_synchro.c:
Source file of the RF timing synchro module.
Flash Driver
Low level driver abstraction layer. Controlled by the flash control statuses.
Related files
  • flash_driver.h:
Header of the flash driver module. It contains function prototypes, definitions, and type definitions.
  • flash_driver.c:
Source file of the flash driver module.
HAL Flash
Low level driver that interacts directly with the flash HW.
Related files
  • stm32wbaxx_hal_flash.h:
Header of the HAL flash driver.

2.2. Asynchronous Operations

All the flash operations are either executed via the Flash Manager interface or via the Simple NVM Arbiter interface. Both work on an asynchronous behavior, which means that the user is requesting operations to be performed and is notified later on, once the operation is finished.
However, since the operation is asynchronous, during write operation, the user must hold the buffer allocation as long as the write operation is not complete. In case of a content change in this buffer, the user must restart an entirely new flash operation.

2.3. Synchronous flash access with RF

Flash operations achieved with Flash manager or Simple NVM Arbiter are synchronized with RF activity. This means that flash operations are achieved only when there is no RF activity.
This feature is transparent to the user and is fully handled by the Flash manager or the Simple NVM Arbiter. Therefore, the user does not have to add the step of RF and flash synchronization.

2.4. Flash Access

In this flash management implementation, the flash access is protected at two distinct levels.

Flash semaphore
A semaphore is required to share the flash interface between several SW modules. The owner of the semaphore is the only one that can request flash operations. The semaphore is attributed to the first requester and released once its operation is over.
Flash control statuses
Independently from the flash semaphore, the flash driver provides flags – Flash Control Status – to prevent flash operation depending on the system activity. These flags/statuses are checked before any flash operation is done by the flash driver.

2.5. Typical use case

A classic flash operation routine is represented in the following schema:

Flash manager routine
Flash manager routine

According to the RF state, the Flash manager adapts its behavior. During RF activity, it requests the help of the RF timing synchro to synchronize flash operation and radio activity. Otherwise, the Flash manager simply executes the flash operation until all work is done.

3. Modules

3.1. RF Timing Synchro

The RF Timing Synchro is the manager of the synchronization between the flash operations and the RF activity. It is managed by the Flash manager and relies on the RF LL to determine whether or not flash operations can be achieved. This module is not intended to be managed by the user. Concepts are presented here for better user understanding.

To achieve the synchronization between the RF and the flash domains, the RF Timing Synchro sets up timing slots during which flash operations can proceed without interfering the RF activity.
These timing slots are the only moment when the flash access is authorized by the LL_RFTS flag. See the Flash Driver. The RFTS module enables the flag at the start of the timing slot and disables it at the end of the slot. This does not depend on if the timing slot is over or the Flash manager released the slot before its end.

3.2. Flash Driver

The Flash Driver is an overlay of the HAL driver with a flash access management. The main features are:

  • HAL driver abstraction for flash operations, i.e, Write and Erase
  • Flash access protection based on different flags

Flash operations are not intended to be achieved with these modules. Since no RF synchronization is achieved at this level, it may be necessary to look at the Flash Manager and the Simple NVM Arbiter parts for a better approach regarding flash operations and the management of the accesses of the flash.

However, this module is mandatory for any flash access management. There are three flags managing the flash access:

  • LL_RFTS:
Flag managed by the RF Timing Synchro(RFTS) module. It must always be set to DISABLE at the start of the application and during RF activity.
When a time slot is granted by the LL, the RFTS module enables this flag leading to the possibility to access the flash without any risk of breaking the RF activity.
When the time slot is about to close, the RFTS module disables this flag, precluding the possibility of further flash operations - RF activity protection.
  • LL_RFTS_BYPASS:
Flag managed by the user. It allows the user to bypass the impact of the above-mentioned flag leading to the possibility to directly access the flash even if the LL_RFTS flag is disabled.
This flag is intended to be used as an optimization flag. For instance, it can be set or reset at ends and restarts of RF activities.
  • SYSTEM:
This flag is updated based on any other request than the Firmware LL. When it is set to DISABLE, the Flash Driver stops any flash operation and waits for the flag to go back to ENABLE.

The following schema highlights the typical check of flash access:

Flash access check
Flash access check
Info white.png Information
This check routine is achieved each time a new flash operation has to be performed

3.3. Flash Manager

The Flash Manager is the main interface for Flash access. It handles the management of the RFTS modules and the call to the Flash driver for flash operations. Thus, it is not necessary to add the step of the RF synchronization with this module.
However, it is necessary to execute an erase before any write operation, as with every normal flash write.

The operations of this module are based on the principle of request/callback.

Request
The user requests an operation, then the operation is registered and executed later on. This can be right after the function return.
Callback
The user can register a callback. The latter is used as an operation status notification, with the state of the operation at the end, OR as a notification for a new possible request, that is, after the first one receives a busy error code.

A common use case is explained above, refer to the following schema.

3.4. Simple NVM Arbiter

The Simple NVM Arbiter is a different interface for flash operations. It relies on the Flash Manager modules but adds some new capabilities to it.

NVM Creation and Management
Adds the possibility to create and manage NVMs, support up to 32 NVMs.
NVMs are identified by a unique ID and are composed of at least 2 banks, 1 for restore and 1 ready for write.
Banks' sizes have a sector-based length.
The user can register up to 4 buffers in 1 NVM.
Ease Flash operations
Ease interaction with flash operations. The user no longer has to erase before write operations or retries.
Integrity check
An integrity check is computed at each new flash operation to ensure the content.
NVM Restore after reset
Restores NVMs contents at restart after initialization.
This allows the user to quickly restore its data after a reset.
If multiples versions are found, only the most recent one is kept for restore.

An overview of the situation is detailed as follows:

SNVMA Overview
SNVMA Overview

3.4.1. Concept

The way the SNVMA is working is simple and can be represented with the schema below.

SNVMA Way of Work
SNVMA Way of Work


There is a three step procedure:

  1. Initialize the SNVMA
  2. Register the buffer to work with
  3. Execute, as many times as necessary, the write or restore operation
Buffer ID and NVM ID
Buffer ID and NVM ID are directly related, each NVM owns up to 4 different buffers, and the managed buffer ID is hard coded:
  • NVM ID #0 owns buffer #0 to #3
  • NVM ID #1 owns buffer #4 to #7
  • Etc.
Even if the relation between buffer ID and NVM ID are hardcoded, it is possible to specify the different buffer IDs in the simple_nvm_arbiter_conf.h file.
Write and Restore operations
Normally, write operations are present to make sure the RAM buffer content is kept in flash for a later possible restore.
Before starting of the write operation, the integrity is computed on the whole buffer content and is rechecked once the write operation is over.
If any content update occurs during the write operation, an integrity mismatch is detected and leads to the restart of the store procedure.
During a write operation, all the registered buffers of the NVM are written down. For instance, there are 3 buffers registered in the NVM ID #2, the buffer ID #9 requests a write operation, the buffer ID#8 and the buffer ID#11 contents are also planned to be written during the write operation.

Otherwise, restore operations are simple read operations with checks for integrity, buffer ID, etc.

4. Interfaces

Below is a list of the available functions for the different flash management modules:

4.1. Flash Driver

4.1.1. Flash Driver error codes

FD_FlashOp_Status_t
Error code Description
FD_FLASHOP_SUCCESS Flash operation success
FD_FLASHOP_FAILURE Flash operation failure

4.1.2. Flash Driver functions

FD_SetStatus

Description

Update Flash Control status.
Syntax
void FD_SetStatus(FD_Flash_ctrl_bm_t Flags_bm, FD_FLASH_Status_t Status);
Parameters
[in] Flags_bm
Type: FD_Flash_ctrl_bm_t
Description: Bit mask identifying the caller
[in] Status
Type: FD_FLASH_Status_t
Description: Action requested (enable or disable flash access)
Return Value
None
FD_WriteData

Description

Write a block of 128 bits (4 x 32-bit words) in flash
Syntax
FD_FlashOp_Status_t FD_WriteData(uint32_t Dest, uint32_t Payload);
Parameters
[in] Dest
Type: uint32_t
Description: Address where to write in flash (128-bit aligned)
[in] Payload
Type: uint32_t
Description: Address of data to be written in flash (32-bit aligned)
Return Value
FD_FlashOp_Status_t
FD_EraseSectors

Description

Erase one sector of flash
Syntax
FD_FlashOp_Status_t FD_EraseSectors(uint32_t Sect);
Parameters
[in] Sect
Type: uint32_t
Description: Identifier of the sector to erase
Return Value
FD_FlashOp_Status_t

4.2. RF Timing Synchro

4.2.1. RF Timing Synchro error codes

RFTS_Cmd_Status_t
Error code Description
RFTS_CMD_OK The RF Timing synchronization command was successfully executed
RFTS_WINDOW_REQ_FAILED The RF Timing synchronization module failed to register the window request
RFTS_WINDOW_REL_ERROR An error occurred during the window release procedure

4.2.2. RF Timing Synchro functions

RFTS_ReqWindow

Description

Request a time window to the Firmware Link Layer
Syntax
RFTS_Cmd_Status_t RFTS_ReqWindow(uint32_t Duration, void (*Callback)(void));
Parameters
[in] Duration
Type: uint32_t
Description: Duration in us of the time window requested
[in] Callback
Type: void (*Callback)(void)
Description: Callback to be called when time window is allocated
Return Value
RFTS_Cmd_Status_t
RFTS_RelWindow

Description

Execute necessary tasks to allow the time window to be released
Syntax
RFTS_Cmd_Status_t RFTS_RelWindow(void);
Parameters
None
Return Value
RFTS_Cmd_Status_t

4.3. Flash Manager

4.3.1. Flash Manager error codes

FM_Cmd_Status_t
Error code Description
FM_OK The Flash Manager is available and a window request is scheduled
FM_BUSY The Flash Manager is busy and the caller will be called back when it is available
FM_ERROR An error occurred while processing the command

4.3.2. Flash Manager functions

FM_Write

Description

Request the Flash Manager module to initiate a Flash Write operation
Syntax
FM_Cmd_Status_t FM_Write(uint32_t *Src, uint32_t *Dest, int32_t Size, FM_CallbackNode_t *CallbackNode);
Parameters
[in] Src
Type: uint32_t *
Description: Address of the data to be stored in FLASH. It shall be 32bits aligned
[in] Dest
Type: uint32_t *
Description: Address where the data shall be written. It shall be 128bits aligned
[in] Size
Type: int32_t
Description: This is the size of data to be written in Flash. The size is a multiple of 32bits (size = 1 means 32bits)
[in] CallbackNode
Type: FM_CallbackNode_t *
Description: Pointer to the callback node for storage in list
Return Value
FM_Cmd_Status_t
FM_Erase

Description

Request the Flash Manager module to initiate a Flash Erase operation
Syntax
FM_Cmd_Status_t FM_Erase(uint32_t FirstSect, uint32_t NbrSect, FM_CallbackNode_t *CallbackNode);
Parameters
[in] FirstSect
Type: uint32_t
Description: Index of the first sector to erase
[in] NbrSect
Type: uint32_t
Description: Number of sector to erase
[in] CallbackNode
Type: FM_CallbackNode_t *
Description: Pointer to the callback node for storage in list
Return Value
FM_Cmd_Status_t
FM_BackgroundProcess

Description

Execute Flash Manager background tasks
Syntax
void FM_BackgroundProcess (void);
Parameters
None
Return Value
None
FM_ProcessRequest

Description

Request to the user scheduler to be scheduled
Syntax
void FM_ProcessRequest (void);
Parameters
None
Return Value
None

4.4. Simple NVM Arbiter

4.4.1. Simple NVM Arbiter error codes

SNVMA_Cmd_Status_t
Error code Description
SNVMA_ERROR_OK No error code
SNVMA_ERROR_NOK Error that occurred before any check
SNVMA_ERROR_NOT_INIT Error code for a module not yet initialized
SNVMA_ERROR_ALREADY_INIT Error code for a module already initialized
SNVMA_ERROR_CMD_PENDING Error code for a command pending
SNVMA_ERROR_NVM_NULL Error code for a NULL NVM pointer
SNVMA_ERROR_NVM_NOT_ALIGNED Error code for a not aligned NVM address
SNVMA_ERROR_NVM_OVERLAP_FLASH Error code for a NVM size that overlaps flash capacities
SNVMA_ERROR_NVM_BUFFER_FULL Error code for a full NVM Buffer
SNVMA_ERROR_NVM_BANK_EMPTY Error code for an empty NVM Buffer
SNVMA_ERROR_NVM_BANK_CORRUPTED Error code for a corrupted NVM Buffer
SNVMA_ERROR_CRC_INIT Error code for a CRC initialization fail
SNVMA_ERROR_BUFFERID_NOT_KNOWN Error code for an unknown Buffer ID
SNVMA_ERROR_BUFFERID_NOT_REGISTERED Error code a non-registered Buffer ID
SNVMA_ERROR_BUFFER_NULL Error code for a NULL Buffer pointer
SNVMA_ERROR_BUFFER_NOT_ALIGNED Error code for a not aligned Buffer address
SNVMA_ERROR_BUFFER_SIZE Error code for a Buffer size that is not OK
SNVMA_ERROR_BUFFER_CONFIG_MISSMATCH Error code for a mismatch between the registered buffer and the buffer to restore
SNVMA_ERROR_FLASH_ERROR Error code for a flash error
SNVMA_ERROR_UNKNOWN Error code for an unknown error

4.4.2. Simple NVM Arbiter functions

SNVMA_Init

Description

Initialize the Simple NVM Arbiter
Syntax
SNVMA_Cmd_Status_t SNVMA_Init (const uint32_t * p_NvmStartAddress);
Parameters
[in] p_NvmStartAddress
Type: const uint32_t *
Description: Start address of the NVM to work with - Shall be aligned 128 bits
Return Value
SNVMA_Cmd_Status_t
SNVMA_Register

Description

Register a user buffer to a NVM.
Buffer IDs are hardcoded, please refer to SNVMA_BufferId_t enumeration
Syntax
SNVMA_Cmd_Status_t SNVMA_Register (const SNVMA_BufferId_t BufferId,
                                   const uint32_t * p_BufferAddress,
                                   const uint32_t BufferSize);
Parameters
[in] BufferId
Type: const SNVMA_BufferId_t
Description: Id of the user which ask for buffer registration
[in] p_BufferAddress
Type: const uint32_t *
Description: Address of the buffer to be registered - Shall be aligned 32 bits
[in] BufferSize
Type: const uint32_t
Description: Size of the buffer to be registered - Shall be a multiple of 32bits
Return Value
SNVMA_Cmd_Status_t
SNVMA_Restore

Description

Restore a user buffer from a NVM.
The user buffer information shall first be provided by calling SNVMA_Register.
Buffer IDs are hardcoded, please refer to SNVMA_BufferId_t enumeration
Syntax
SNVMA_Cmd_Status_t SNVMA_Restore (const SNVMA_BufferId_t BufferId);
Parameters
[in] BufferId
Type: const SNVMA_BufferId_t
Description: Id of the user which ask for buffer registration
Return Value
SNVMA_Cmd_Status_t
SNVMA_Write

Description

Register a user buffer to a NVM.
The user buffer information must first be provided by calling SNVMA_Register.
Buffer IDs are hardcoded, refer to SNVMA_BufferId_t enumeration.
A buffer write request cannot be scheduled once its NVM is already on a write operation. This leads to an SNVMA_OPERATION_FAILED callback status.
Syntax
SNVMA_Cmd_Status_t SNVMA_Write (const SNVMA_BufferId_t BufferId,
                                void (* Callback) (SNVMA_Callback_Status_t));
Parameters
[in] BufferId
Type: const SNVMA_BufferId_t
Description: Id of the user which ask for buffer registration
[in] Callback
Type: void (* Callback) (SNVMA_Callback_Status_t))
Description: Callback function for operation status return - Can be NULL
Return Value
SNVMA_Cmd_Status_t


Info white.png Information
For more information about the Background process system, please visit STM32CubeWBA System modules article