The following code examples show a typical usage of section variables in an application.
The examples are taken from the actual usage by Experimental: Flash Storage and the Experimental: Flash Data Storage module.
The following code registers a named section as a symbol. It is not required by all compilers, but it should be invoked to keep the code portable. This code should be placed in the code unit that accesses registered items in the named section:
The following code registers the type fs_config_t to be stored in the named section called fs_data. This code should be placed in the code unit that accesses variables in the named section:
In the header file of the module that is providing the section variables, you should generate a macro to simplify the registration. This macro should be defined in a header file that the registrants include:
This new macro will fill in the name of the named section for all registration calls. Every code unit that requires a registration must invoke this macro to place a configuration inside the named section. The call should be in the code unit.
Here is an example of how this is done in fds.c:
This becomes a statically placed instance of fs_config that can be used to call into the module that uses section variables. Note that const data must be initialized using an initializer list. This safeguards the data from being corrupted.
If the user of the registered variables does not require to update data inside the registrations, it is possible to add a const modifier for the call. In this case, the named section will be placed in flash:
One of the benefits of using section variables is that it is no longer required to keep a registration token for all calls to be able to distinguish where the call came from, which the module needs to locate on every call. The registered entry in the named section acts as a registration token as well.
An example is the following call to erase all pages for a registration in FStorage:
The module that provides section variables must know the start and end address of the named section and must be able to get the count to be able to iterate over all registered items.
Some convenience macros have been generated in fstorage.c
for internal use. These macros point to the relevant macro declarations in section_vars.h:
Every function request requires the registered section variable as a parameter. To verify the call from a registered user, it is possible to use the macros for the start and end addresses of the named section to see that the registration is correct. Here is an example of such a function:
You can iterate through the elements in an init function or similar in the following way (using the convenience macros described before):
Keil does not require linker scripts. Named sections are generated automatically when registration macros are invoked.
For GCC compilations, you must add a definition for a linker script used in the compilation.This addition should be at the root level of the linker script file:
This definition will add a named section fs_data that is aligned to a word and that has __start_fs_data and __stop_fs_data as symbols that are used from the code.
For IAR compilations, you must make additions to an ilink file.