nRF5 SDK v15.3.0
Experimental: Section variables

Section variables are variables that are placed in a named section by different independent pieces of code (for example, files or modules), so that they can be shared. The section variables module facilitates the handling of section variables by abstracting the required compiler-specific code.

The sharing of variables happens at compile time (or more precisely, at link time). One module (the registrar) creates a named section that can hold variables. Other modules (the registrants) can then register variables to place them into the section at link time. Each variable can be accessed by the registrar and the registrant that created it.

Main reasons for using section variables are:

A typical use case for section variables is the initialization of a module that allows multiple users to register with it and that manages a shared resource (for example, Experimental: Flash Storage). Each of the users provides a configuration structure that is kept by the module. Without the use of section variables, these configuration structures can be dynamically registered at run time or handled through a shared header file. With run-time registration, the module can never know the final number of registrants. With a shared header file, you must modify the code of the registrar (which might be a library that you do not want to change). With section variables, the number of registrants is known immediately when the code runs, and you need to modify only the registrant code.

Section variables are used in Experimental: Flash Storage and Experimental: Flash Data Storage to configure flash page usage, for example.

The following code examples show how to use section variables in an application. In a typical use case, there is one registrar module that creates the named section and uses the data in it and one or more registrant modules that register their data in the named section.

Creating a named section

Creating a named section requires two steps:

  1. In the code of the registrar module, create and name the section (section_name in this example), indicating the data type of the variables to be stored in it (data_type_t in this example):
    NRF_SECTION_DEF(section_name, data_type_t);
    Note that all variables in a named section must be of the same type.
  2. If you are using GCC, tell the linker that there is a named section. To do so, add the following definition to the root level of the linker script that is used in the compilation (replace section_name with the name of your section):
    SECTIONS
    {
    .section_name :
    {
    PROVIDE(__start_section_name = .);
    KEEP(*(.section_name))
    PROVIDE(__stop_section_name = .);
    } > RAM
    } INSERT AFTER .data;

Registering section set variables

In the code of the registrant module, use the NRF_SECTION_ITEM_REGISTER macro to register a section variable. The following code example shows how to register the variable var_name of type data_type_t in the section named section_name and assign it the value var_value:

NRF_SECTION_ITEM_REGISTER(section_name, data_type_t var_name) = {var_value};

If the registrant does not require to update the value of the section variable, define the variable as const. If this is the case for all section variables in a named section, the section is placed in flash:

NRF_SECTION_ITEM_REGISTER(section_name, const data_type_t var_name ) = {var_value};

To simplify registrations, you can define macros that fill in the name of the named section. See the following example from Experimental: Flash Storage:

#define FS_REGISTER_CFG(cfg_var) NRF_SECTION_ITEM_REGISTER(fs_data, cfg_var)

Using section variables

The Section variables module provides several macros that the registrar can use to retrieve section variables and information about the named section and the variables it contains.

The following code example shows how to iterate through all registered section variables to initialize the registrar module for all registrants:

static void init_func(void)
{
int vars_cnt = NRF_SECTION_ITEM_COUNT(section_name, data_type_t);
for (int i = 0; i < vars_cnt; i++)
{
data_type_t * p_var_name = NRF_SECTION_ITEM_GET(section_name, data_type_t, i);
// Add initialization code here
}
}
Note
Using this module, it is not possible to control the order of the variables in a named section across compiler versions and across compilations. This feature is provided by Experimental: Section variables iterator.

Experimental: Section variables iterator


Documentation feedback | Developer Zone | Subscribe | Updated