Memory
Section Management
The generated C code of your application plus the code and data in the
OO RTX can be configured to end up at specific memory sections. If you
don't care, you do not need to do anything: your linker/locator will
use default allocation rules. All you will see are default sections in
your linker generated memory map. If you do care, you can instruct your
linker/locator with commands to locate specific sections at specific
locations.
Basically the information to insert a symbol in a specific section
needed by the linker/locator is needed at compile time. Via pragmas one
can steer which section to use for a symbol. To make the C code
portable with respect to toolchain and CPU, it is a bad idea to 'hard
code' pragmas in the source files. Instead, a mechanism based on macro
definitions has been implemented.
Prior to the definition of a symbol, a macro is set which triggers a
compiler pragma. A so-called section macro is translated into a section
name. A
section macro results:
- in a pragma to define a certain section (the
macro contains the text START_SEC)
- or in a pragma to return to the default
code or data section (the macro contains the text STOP_SEC).
The pragmas
are toolchain specific: the section macros are set in all sources but
the corresponding pragmas are set in an include file WSTMemoryTypes.h
See the examples below for a Keil ARM RealView toolchain specific
WSTMemoryTypes.h:
#if defined(
WST_RXF_RUNNING_START_SEC_CODE_FAST )
#undef
WST_RXF_RUNNING_START_SEC_CODE_FAST
#pragma arm section
code =
"CODE_OORTX_RUNNING_FAST"
#endif
#if defined(
WST_RXF_RUNNING_START_SEC_DATA_INIT_32_FAST )
#undef
WST_RXF_RUNNING_START_SEC_DATA_INIT_32_FAST
#pragma arm section
rwdata =
"DATA_OORTX_RUNNING_32_INIT_FAST"
#endif
In the OO RXT sources, section macros are used like for example:
#define
WST_RXF_RUNNING_START_SEC_CODE_FAST
#include
"WSTMemoryTypes.h"
void RiCTask_Init(const
RiCTask* const me)
{
.. /* some code */
}
#define
WST_RXF_RUNNING_STOP_SEC_CODE_FAST
#include
"WSTMemoryTypes.h"
and for the variable RiCProcessedTicks:
#define
WST_RXF_RUNNING_START_SEC_DATA_INIT_32_FAST
#include
"WSTMemoryTypes.h"
timeUnit
RiCProcessedTicks = (timeUnit) 0;
#define
WST_RXF_RUNNING_START_SEC_DATA_INIT_32_FAST
#include
"WSTMemoryTypes.h"
So: a section macro is set and WSTMemoryTypes.h is included, which
tests for such macros and inserts the proper pragma which enables some
named section.
The section macros are inserted by Willert Software Tools in all OO RTX
files, and via the profile WST_RXF_V5.sbs
the section macros are also inserted in the Rhapsody generated source
files of your application.
The file WSTMemoryTypes.h
is toolchain specific and must contain section macros for:
- the memory categories: OORTX, OSAL, APPL
- the phases: ONPOWER, DOWNPOWER, SLEEP, RUNNING
- for code: CODE
- for data sizes: 8 (bits), 16 (bits), 24 (bits), 32 (bits),
UNSPECIFIED (bits)
- for data types: INIT, NOINIT, CONST
- for memory types: FAST, SLOW
As a result of these memory categories, phases, memory types, code and
different data sizes and types, the file WSTMemoryTypes.h is quite
large and difficult to maintain. For this, we have provided a
conversion script MacroAndPragma2Header.awk which takes two
files
as input:
- a file which describes the memory categories, phases,
memory types, code and different data sizes and types.
The descriptions are within C comment in the file WSTMemoryTypeMacro.template
which is installed in the directory
<your Rhapsody>\Share\WST_RXF_V5\<your product>\Config\MemorySections
- a file which describes the toolchain specific pragmas for
the named code- and data sections.
This is the file WSTMemoryTypePragmas.txt
which is also installed in the directory
<your Rhapsody>\Share\WST_RXF_V5\<your product>\Config\MemorySections
In some cases, in particular when the generated WSTMemoryTypes.h will
slow down the compiler when parsing all macros and pragmas, the file
WSTMemoryTypePragmas.txt is left empty. The file WSTMemoryTypePragmas.txt.example
serves as an example how you can
implement WSTMemoryTypePragmas.txt, please refer
to the installed
files for the compiler bridge.
In actual implementation in RiCTask.c of the example above of section
macros for data the macro WST_TIMEUNIT_ADDRESS_SIZE
is used. All _ADDRESS_SIZE macros are part of the implemented
compiler bridge interface, because ANSI-C does not allow for
use of the sizeof operator in
preprocessor statements, which is why we use these _ADDRESS_SIZE
macros.
Copyright (c) Willert
Software Tools GmbH. All rights reserved.