Skip to main content

IAR Embedded Workbench for RH850 3.20.x

Application execution—an overview

In this section:

This section gives an overview of the execution of an embedded application divided into three phases.

The initialization phase

Initialization is executed when an application is started (the CPU is reset) but before the main function is entered. For simplicity, the initialization phase can be divided into:

  • Hardware initialization, which as a minimum, generally initializes the stack pointer.

    The hardware initialization is typically performed in the system startup code cstartup.s (or the corresponding file for multicore devices, see System startup and termination), and if required, by an extra low-level routine that you provide. It might include resetting/restarting the rest of the hardware, setting up the CPU, etc, in preparation for the software C/C++ system initialization.

  • Software C/C++ system initialization

    Typically, this includes assuring that every global (statically linked) C/C++ symbol receives its proper initialization value before the main function is called.

  • Application initialization

    This depends entirely on your application. It can include setting up an RTOS kernel and starting initial tasks for an RTOS-driven application. For a bare-bone application, it can include setting up various interrupts, initializing communication, initializing devices, etc.

For a ROM/flash-based system, constants and functions are already placed in ROM. The linker has already divided the available RAM into different areas for variables, stack, heap, etc. All symbols placed in RAM must be initialized before the main function is called.

The following sequence of illustrations gives a simplified overview of the different stages of the initialization.

  1. When an application is started, the system startup code first performs hardware initialization, such as initialization of the stack pointer to point at the predefined stack area:

    Bild_1_70percent.png
  2. Then, memories that should be zero-initialized are cleared, in other words, filled with zeros:

    Bild 2 70percent.png

    Typically, this is data referred to as zero-initialized data—variables declared as, for example, int i = 0;

  3. For initialized data, data declared, for example, like int i = 6; the initializers are copied from ROM to RAM

    Bild 3 70percent.png

    Then, dynamically initialized static objects are constructed, such as C++ objects.

  4. Finally, the main function is called:

    Bild 4 70percent.png

    For more information about each stage, see System startup and termination. For more information about data initialization, see Initialization at system startup.

The execution phase

The software of an embedded application is typically implemented as a loop, which is either interrupt-driven, or uses polling for controlling external interaction or internal events. For an interrupt-driven system, the interrupts are typically initialized at the beginning of the main function.

In a system with real-time behavior and where responsiveness is critical, a multi-task system might be required. This means that your application software should be complemented with a real-time operating system (RTOS). In this case, the RTOS and the different tasks must also be initialized at the beginning of the main function.

The termination phase

Typically, the execution of an embedded application should never end. If it does, you must define a proper end behavior.

To terminate an application in a controlled way, either call one of the Standard C library functions exit, _Exit, quick_exit, or abort, or return from main. If you return from main, the exit function is executed, which means that C++ destructors for static and global variables are called (C++ only) and all open files are closed.

Of course, in case of incorrect program logic, the application might terminate in an uncontrolled and abnormal way—a system crash.

For more information about this, see System termination.