This page discusses some issues that are related to the implementation of the OBS Framework source code on an embedded target.
Memory Occupation
Since a framework is not an application, it is not possible to give a single memory
occupation figure for the OBS Framework. Most applications instantiated from the
framework will only use a subset of the classes it offers and hence the impact of the
framework usage on the memory footprint of the final application may vary. It is however
possible to gain a qualitative idea of the likely impact by measuring the memory
occupation of the
RegressionTest
application that runs all the test cases provided by the framework in sequence. The
results of the measurements are given by the table below.
The measurements were performed on the SIS ERC32 simulator (version 3.0.5). The application was compiled and linked using the ERC32 GNU cross-compiler system (version 2.0.7). The figures refer to the version of the framework and its regression test as they existed in the ObsFramework CVS repository on April 28-th 2004 at 2 pm. It should also be noted that measurements on an earlier version of the framework had been performed on an ERC32 board by Estec TOS-ESC personnel which demonstrated the compatibility of the framework software with a real ERC32 hardware environment.
At the time of the measurement, the framework consisted of 239 C++ classes (including the
test case classes). Note also that that RegressionTest
application performs
I/O operations (to write the results of the tests to the standard output) and therefore
its memory requirements include the applicable library routines. These would obviously
not be needed in a real embedded applications. The framework classes make extensive use
of assertions to check pre- and post-conditions and invariants. The assertions were
however disabled for the measurements (as they would be in a real operational situation).
The table shows the size of the .text
, .data
, and
.bss
sections as reported by the SIS simulator when the application is
loaded. Five sets of measurements were made, corresponding to five different sets of
compiler options as indicated in the first column. As expected, the most important gain
arises from the use of the -fno-rtti
and -fno-exceptions
options. The -fno-rtti
option removes all code and data related to the use
of the C++ run-time type information mechanism. The -fno-exceptions
removes
all code and data related to the use of the C++ exception mechanism (recall that the
framework classes use a very restricted subset of the C++
language that does not use either the RTTI or the exception mechanisms). Taken
together, these two options basically eliminate the overhead associated to the use of
the C++ language.
The compiler options obviously only have an impact on the framework code proper. They do
not affect the size of the run-time system or of any libraries that are linked into the
executable. Further gains could be achieved by rebuilding the gcc environment with the
same options used for the framework. The results of the tests done on the
hello
and empty
reference programs (see below in this page)
however indicate that any such overheads are very small.
Compiler Options |
.text
|
.data
|
.bss
|
---|---|---|---|
-O | 317264 | 65856 | 5716 |
-O2 | 311056 | 65776 | 5716 |
-O3 | 311360 | 65776 | 5716 |
-Os | 313680 | 70432 | 5716 |
-O -fno-rtti -fno-exceptions | 268976 | 18840 | 1956 |
A perspective on the above figures can be gained by comparing them with the corresponding
figures for some simple reference applications (the source code for the reference
applications can be found in directory scripts/TestMains
of the OBS
Framework delivery). The next table gives figures for the following reference applications:
-
empty.c
: an application consisting of an emptymain
(the main returns immediately without doing anything). -
empty.cpp
: same asmain.c
but with thecpp
extension to force the use of the C++ compiler. -
hello.c
: the classical 'Hello World' program consisting of amain
that writes "Hello World" and returns immediately. -
hello.cpp
: same ashello.c
but with thecpp
extension to force the use of the C++ compiler.
The table shows the memory occupation figures for two typical compiler configuration
options. For each application, two figures are given corresponding to
the.text
and the .data
. The figures for the .bss
section are not given as they are negligible in all cases.
Compiler Options |
empty.c
|
empty.cpp
|
hello.c
|
hello.cpp
|
---|---|---|---|---|
-O | 6384 / 16 | 6384 / 72 | 26496 / 1200 | 26496 / 1256 |
-O -fno-rtti -fno-exceptions | 6384 / 16 | 6384 / 16 | 26496 / 1200 | 26496 / 1200 |
The following remarks apply to the above results:
- There is no difference in the memory occupation of the
empty
andhello
programs between the case when they are compiled with the C and with the C++ compiler. This suggests that the C++ compiler does not add unnecessary overheads with respect to the C compiler when it is compiling code that, though embedded within acpp
file, is really plain C code. - For the
empty
andhello
programs, there is no difference between the results with and without RTTI and exception handling because these two programs are pure C programs which do not use classes (exception handling and RTTI are class-related mechanisms).
The next set of figures explore the impact of the class construct on the memory occupation. The following reference applications are considered:
-
hello.c
: the classical 'Hello World' program consisting of amain
that writes "Hello World" and returns immediately. -
helloBaseClass.cpp
: a class-based version of the classical 'Hello World' program. This program consists of a single class with a dummy constructor that returns without taking any action and a singleprintHelloWorld
method that writes "Hello World" and returns immediately. The main program instantiates the class on the stack and calls its methodprintHelloWorld
. -
helloDerivedClass.cpp
: a class-based version of the classical 'Hello World' program that includes a base and a derived classe with one pure virtual methods. This program consists of two classes: a base class and a derived class that extends the base class. The base class defines a dummy constructor that returns without taking any action and a pure virtual methodprintHelloWorld
. The derived class defines a dummy constructor that returns without doing anything and it provides an implementation for the methodprintHelloWorld
that writes "Hello World" and returns immediately. The main program instantiates the derived class on the stack and calls its methodprintHelloWorld
.
The table shows the memory occupation figures for the two compiler configuration options as used above.
Compiler Options |
hello.c
|
helloBaseClass.cpp
|
helloDerivedClass.cpp
|
---|---|---|---|
-O | 26496 / 1200 | 26544 / 1328 | 41360 / 4688 |
-O -fno-rtti -fno-exceptions | 26496 / 1200 | 26544 / 1200 | 26592 / 1232 |
The following remarks apply to the above results:
- There is basically no difference in the memory occupation of the
hello
andhelloBaseClass
programs. Their functionality is the same but the former is implemented as a pure C program whereas the latter is implemented as a C++ program that uses the class construct with only non-virtual methods. The essential equality in memory footprint for the two applications indicates that the use of the class construct - as long as only non-virtual methods are used - does not introduce any memory overheads. The small difference in memory occupation (less than 100 bytes) is probably due to the code that implements the class constructors. - There is a very large difference in memory occupation between the
helloBaseClass
and thehelloDerivedClass
programs when only the-O
compiler option is used. The second program differs from the first one because it uses class extension and pure virtual methods. The extra code probably originates in the RTTI and exception handling mechanisms. This is suggested by the fact that when the "-O -fno-rtti -fno-exceptions
" compiler options are used (which remove all RTTI and exception handling), then the memory overhead with respect to the simplehello
program disappears almost completely. This again indicates that the use of these compiler options removes all overheads due to the C++ language.
Finally, memory occupation was measured for a sample application. Except for its
main program (which can be found in directorysrc/cpp/SampleApplication
, the
sample application was entirely generated automatically by running the generator
meta-components (first the instantiators and then the configurers) on the sample application model. The
resulting application is far from representative of a real on-board application but,
unlike the programs considered above, it only contains framework classes (i.e. no I/O
libraries). The total number of concrete classes that are explicitly defined in the
sample application model is 101. The real number of concrete classes used by the sample
application may be slightly higher due to components that are "pulled in" without being
explicitly defined in the application model (such as the dynamic factory components).
The total number of classes included in the executable is of course still higher because
it includes all the non-concrete classes that are used by the instantiated classes. The
memory usage figures for this sample application are as follows:
Compiler Options |
SampleApplication.cpp
|
---|---|
-O | 143904 / 51112 |
-O -fno-rtti -fno-exceptions | 116736 / 15808 |
Byte Ordering
Most OBS Framework classes are independent of the byte ordering policy adopted by the processor on which their code runs. The regression tests provided by the framework test suite, in particular, run without changes on both an Intel PC (little-endian) and on the SPARC-based ERC32 (big-endian).
Byte ordering problems are relevant only for the classes that process the telemetry and
telecommand images (e.g. memcpy
standard C routine. Byte ordering inconsistencies could therefore be
resolved, without touching the framework source code, by providing a new implementation
for this routine.
Alignment Constraints
Some compiler and some processors enforce particular alignment constraints. The OBS Framework code has been written to be independent of these constraints. The regression tests provided by the framework test suite, in particular, run without changes both on an Intel PC with the Microsoft VisualStudio compiler an Intel PC - to which no alignment constraints apply - and on the SPARC-based ERC32 with the gcc compiler - for which alignment constraints apply.