2008-06-02 Joel Sherrill <joel.sherrill@oarcorp.com>

* user/bsp.t, user/init.t: Rework initialization and BSP chapters to
	account for changes to initialization framework.
This commit is contained in:
Joel Sherrill
2008-06-02 16:07:42 +00:00
parent 89ae273da7
commit a73e356164
3 changed files with 271 additions and 182 deletions

View File

@@ -1,3 +1,8 @@
2008-06-02 Joel Sherrill <joel.sherrill@oarcorp.com>
* user/bsp.t, user/init.t: Rework initialization and BSP chapters to
account for changes to initialization framework.
2008-05-22 Joel Sherrill <joel.sherrill@OARcorp.com> 2008-05-22 Joel Sherrill <joel.sherrill@OARcorp.com>
* user/conf.t: Add baseline interface for Watchdog Driver. * user/conf.t: Add baseline interface for Watchdog Driver.

View File

@@ -33,20 +33,9 @@ initialization code are highly processor and target dependent,
the logical functionality of these actions are similar across a the logical functionality of these actions are similar across a
variety of processors and target platforms. variety of processors and target platforms.
Normally, the application's initialization is Normally, the BSP and some of the application initialization is
performed at two separate times: before the call to intertwined in the RTEMS initialization sequence controlled by
@code{@value{DIRPREFIX}initialize_executive} the shared function @code{boot_card()}.
(reset application initialization) and
after @code{@value{DIRPREFIX}initialize_executive}
in the user's initialization tasks
(local and global application initialization). The order of the
startup procedure is as follows:
@enumerate
@item Reset application initialization.
@item Call to @code{@value{DIRPREFIX}initialize_executive}
@item Local and global application initialization.
@end enumerate
The reset application initialization code is executed The reset application initialization code is executed
first when the processor is reset. All of the hardware must be first when the processor is reset. All of the hardware must be
@@ -57,49 +46,45 @@ application. Some of the hardware components may be initialized
in this code as well as any application initialization that does in this code as well as any application initialization that does
not involve calls to RTEMS directives. not involve calls to RTEMS directives.
The processor's Interrupt Vector Table which will be The processor's Interrupt Vector Table which will be used by the
used by the application may need to be set to the required value application may need to be set to the required value by the reset
by the reset application initialization code. Because application initialization code. Because interrupts are enabled
interrupts are enabled automatically by RTEMS as part of the automatically by RTEMS as part of the context switch to the first task,
@code{@value{DIRPREFIX}initialize_executive} directive, the Interrupt Vector Table MUST be set before this directive is invoked
the Interrupt Vector Table MUST to ensure correct interrupt vectoring. The processor's Interrupt Vector
be set before this directive is invoked to ensure correct Table must be accessible by RTEMS as it will be modified by the when
interrupt vectoring. The processor's Interrupt Vector Table installing user Interrupt Service Routines (ISRs) On some CPUs, RTEMS
must be accessible by RTEMS as it will be modified by the installs it's own Interrupt Vector Table as part of initialization and
@code{@value{DIRPREFIX}interrupt_catch} directive. thus these requirements are met automatically. The reset code which is
On some CPUs, RTEMS installs it's executed before the call to any RTEMS initialization routines has the
own Interrupt Vector Table as part of initialization and thus following requirements:
these requirements are met automatically. The reset code which
is executed before the call to @code{@value{DIRPREFIX}initialize_executive}
has the following requirements:
@itemize @bullet @itemize @bullet
@item Must not make any RTEMS directive calls. @item Must not make any blocking RTEMS directive calls.
@item If the processor supports multiple privilege levels, @item If the processor supports multiple privilege levels, must leave
must leave the processor in the most privileged, or supervisory, the processor in the most privileged, or supervisory, state.
state.
@item Must allocate a stack of at least @code{@value{RPREFIX}MINIMUM_STACK_SIZE} @item Must allocate a stack of at least @code{@value{RPREFIX}MINIMUM_STACK_SIZE}
bytes and initialize the stack pointer for the bytes and initialize the stack pointer for the initialization process.
@code{@value{DIRPREFIX}initialize_executive} directive.
@item Must initialize the processor's Interrupt Vector Table. @item Must initialize the processor's Interrupt Vector Table.
@item Must disable all maskable interrupts. @item Must disable all maskable interrupts.
@item If the processor supports a separate interrupt stack, @item If the processor supports a separate interrupt stack, must allocate
must allocate the interrupt stack and initialize the interrupt the interrupt stack and initialize the interrupt stack pointer.
stack pointer.
@end itemize @end itemize
The @code{@value{DIRPREFIX}initialize_executive} directive does not return to At the end of the initialization sequence, RTEMS does not return to the
the initialization code, but causes the highest priority BSP initialization code, but instead context switches to the highest
initialization task to begin execution. Initialization tasks priority task to begin application execution. This task is typically
are used to perform both local and global application a User Initialization Task which is responsible for performing both
initialization which is dependent on RTEMS facilities. The user local and global application initialization which is dependent on RTEMS
initialization task facility is typically used to create the facilities. It is also responsible for initializing any higher level
application's set of tasks. RTEMS services the application uses such as networking and blocking
device drivers.
@subsection Interrupt Stack Requirements @subsection Interrupt Stack Requirements
@@ -121,38 +106,36 @@ stack usage must account for the following requirements:
@item Application subroutine calls @item Application subroutine calls
@end itemize @end itemize
The size of the interrupt stack must be greater than The size of the interrupt stack must be greater than or equal to the
or equal to the constant @code{@value{RPREFIX}MINIMUM_STACK_SIZE}. constant @code{@value{RPREFIX}MINIMUM_STACK_SIZE}.
@subsection Processors with a Separate Interrupt Stack @subsection Processors with a Separate Interrupt Stack
Some processors support a separate stack for Some processors support a separate stack for interrupts. When an
interrupts. When an interrupt is vectored and the interrupt is interrupt is vectored and the interrupt is not nested, the processor
not nested, the processor will automatically switch from the will automatically switch from the current stack to the interrupt stack.
current stack to the interrupt stack. The size of this stack is The size of this stack is based solely on the worst-case stack usage by
based solely on the worst-case stack usage by interrupt service interrupt service routines.
routines.
The dedicated interrupt stack for the entire The dedicated interrupt stack for the entire application on some
application is supplied and initialized by the reset and architectures is supplied and initialized by the reset and initialization
initialization code of the user's board support package. Since code of the user's Board Support Package. Whether allocated and
all ISRs use this stack, the stack size must take into account initialized by the BSP or RTEMS, since all ISRs use this stack, the
the worst case stack usage by any combination of nested ISRs. stack size must take into account the worst case stack usage by any
combination of nested ISRs.
@subsection Processors without a Separate Interrupt Stack @subsection Processors Without a Separate Interrupt Stack
Some processors do not support a separate stack for Some processors do not support a separate stack for interrupts. In this
interrupts. In this case, without special assistance every case, without special assistance every task's stack must include
task's stack must include enough space to handle the task's enough space to handle the task's worst-case stack usage as well as
worst-case stack usage as well as the worst-case interrupt stack the worst-case interrupt stack usage. This is necessary because the
usage. This is necessary because the worst-case interrupt worst-case interrupt nesting could occur while any task is executing.
nesting could occur while any task is executing.
On many processors without dedicated hardware managed On many processors without dedicated hardware managed interrupt stacks,
interrupt stacks, RTEMS manages a dedicated interrupt stack in RTEMS manages a dedicated interrupt stack in software. If this capability
software. If this capability is supported on a CPU, then it is is supported on a CPU, then it is logically equivalent to the processor
logically equivalent to the processor supporting a separate supporting a separate interrupt stack in hardware.
interrupt stack in hardware.
@section Device Drivers @section Device Drivers
@@ -178,23 +161,20 @@ the application is to utilize timeslicing, the clock manager, the
timer manager, the rate monotonic manager, or the timeout option on blocking timer manager, the rate monotonic manager, or the timeout option on blocking
directives. directives.
The clock tick is usually provided as an interrupt The clock tick is usually provided as an interrupt from a counter/timer
from a counter/timer or a real-time clock device. When a or a real-time clock device. When a counter/timer is used to provide the
counter/timer is used to provide the clock tick, the device is clock tick, the device is typically programmed to operate in continuous
typically programmed to operate in continuous mode. This mode mode. This mode selection causes the device to automatically reload the
selection causes the device to automatically reload the initial initial count and continue the countdown without programmer intervention.
count and continue the countdown without programmer This reduces the overhead required to manipulate the counter/timer in
intervention. This reduces the overhead required to manipulate the clock tick ISR and increases the accuracy of tick occurrences.
the counter/timer in the clock tick ISR and increases the The initial count can be based on the microseconds_per_tick field
accuracy of tick occurrences. The initial count can be based on in the RTEMS Configuration Table. An alternate approach is to set
the microseconds_per_tick field in the RTEMS Configuration the initial count for a fixed time period (such as one millisecond)
Table. An alternate approach is to set the initial count for a and have the ISR invoke @code{@value{DIRPREFIX}clock_tick} on the
fixed time period (such as one millisecond) and have the ISR configured @code{microseconds_per_tick} boundaries. Obviously, this
invoke @code{@value{DIRPREFIX}clock_tick} can induce some error if the configured @code{microseconds_per_tick}
on the microseconds_per_tick boundaries. is not evenly divisible by the chosen clock interrupt quantum.
Obviously, this can induce some error if the configured
microseconds_per_tick is not evenly divisible by the chosen
clock interrupt quantum.
It is important to note that the interval between It is important to note that the interval between
clock ticks directly impacts the granularity of RTEMS timing clock ticks directly impacts the granularity of RTEMS timing
@@ -235,7 +215,7 @@ switch extension would save and restore the context of the
device. device.
For more information on user extensions, refer to the For more information on user extensions, refer to the
User Extensions chapter. @ref{User Extensions Manager} chapter.
@section Multiprocessor Communications Interface (MPCI) @section Multiprocessor Communications Interface (MPCI)

View File

@@ -10,17 +10,19 @@
@section Introduction @section Introduction
The initialization manager is responsible for The Initialization Manager is responsible for
initiating and shutting down RTEMS. Initiating RTEMS involves initiating and shutting down RTEMS. Initiating RTEMS involves
creating and starting all configured initialization tasks, and creating and starting all configured initialization tasks, and
for invoking the initialization routine for each user-supplied for invoking the initialization routine for each user-supplied
device driver. In a multiprocessor configuration, this manager device driver. In a multiprocessor configuration, this manager
also initializes the interprocessor communications layer. The also initializes the interprocessor communications layer. The
directives provided by the initialization manager are: directives provided by the Initialization Manager are:
@itemize @bullet @itemize @bullet
@item @code{@value{DIRPREFIX}initialize_executive_early} - Initialize RTEMS and do NOT Start Multitasking @item @code{@value{DIRPREFIX}initialize_data_structures} - Initialize RTEMS Data Structures
@item @code{@value{DIRPREFIX}initialize_executive_late} - Complete Initialization and Start Multitasking @item @code{@value{DIRPREFIX}initialize_before_drivers} - Perform Initialization Before Device Drivers
@item @code{@value{DIRPREFIX}initialize_device_drivers} - Initialize Device Drivers
@item @code{@value{DIRPREFIX}initialize_start_multitasking} - Complete Initialization and Start Multitasking
@item @code{@value{DIRPREFIX}shutdown_executive} - Shutdown RTEMS @item @code{@value{DIRPREFIX}shutdown_executive} - Shutdown RTEMS
@end itemize @end itemize
@@ -53,41 +55,40 @@ This transformation typically involves changing priority and
execution mode. RTEMS does not automatically delete the execution mode. RTEMS does not automatically delete the
initialization tasks. initialization tasks.
@subsection The System Initialization Task @subsection System Initialization
The System Initialization Task is responsible for System Initialization begins with board reset and continues
initializing all device drivers. As a result, this task has a through RTEMS initialization, initialization of all device
higher priority than all other tasks to ensure that no drivers, and eventually a context switch to the first user
application tasks executes until all device drivers are task. Remember, that interrupts are disabled during
initialized. After device initialization in a single processor initialization and the @i{initialization thread} is not
system, this task will delete itself. a task in any sense and the user should be very careful
during initialzation.
The System Initialization Task must have enough stack The BSP must ensure that the there is enough stack
space to successfully execute the initialization routines for space reserved for the initialization "thread" to
successfully execute the initialization routines for
all device drivers and, in multiprocessor configurations, the all device drivers and, in multiprocessor configurations, the
Multiprocessor Communications Interface Layer initialization Multiprocessor Communications Interface Layer initialization
routine. The CPU Configuration Table contains a field which routine.
allows the application or BSP to increase the default amount of
stack space allocated for this task.
In multiprocessor configurations, the System
Initialization Task does not delete itself after initializing
the device drivers. Instead it transforms itself into the
Multiprocessing Server which initializes the Multiprocessor
Communications Interface Layer, verifies multiprocessor system
consistency, and processes all requests from remote nodes.
@subsection The Idle Task @subsection The Idle Task
The Idle Task is the lowest priority task in a system The Idle Task is the lowest priority task in a system
and executes only when no other task is ready to execute. This and executes only when no other task is ready to execute. This
task consists of an infinite loop and will be preempted when any default implementation of this task consists of an infinite
other task is made ready to execute. loop. RTEMS allows the Idle Task body to be replaced by a CPU
specific implementation, a BSP specific implementation or an
application specific implementation.
The Idle Task is preemptible and @b{WILL} be preempted when
any other task is made ready to execute. This characteristic is
critical to the overall behavior of any application.
@subsection Initialization Manager Failure @subsection Initialization Manager Failure
The @code{@value{DIRPREFIX}ifatal_error_occurred} directive will be called The @code{@value{DIRPREFIX}fatal_error_occurred} directive will
from @code{@value{DIRPREFIX}initialize_executive} be invoked from @code{@value{DIRPREFIX}initialize_executive}
for any of the following reasons: for any of the following reasons:
@itemize @bullet @itemize @bullet
@@ -119,41 +120,71 @@ initialization sequence.
created or started successfully. created or started successfully.
@end itemize @end itemize
A discussion of RTEMS actions when a fatal error occurs
may be found @ref{Fatal Error Manager Announcing a Fatal Error}.
@section Operations @section Operations
@subsection Initializing RTEMS @subsection Initializing RTEMS
The Initializatiton Manager directives are called by the The Initialization Manager directives are called by the
board support package framework as part of its initialization Board Support Package framework as part of its initialization
sequence. RTEMS assumes that the board support package sequence. RTEMS assumes that the Board Support Package
successfully completed its initialization activities. These successfully completed its initialization activities. These
directives initialize RTEMS by performing the following actions: directives initialize RTEMS by performing the following actions:
@itemize @bullet @itemize @bullet
@item Initializing internal RTEMS variables; @item Initializing internal RTEMS variables;
@item Allocating system resources; @item Allocating system resources;
@item Creating and starting the System Initialization Task;
@item Creating and starting the Idle Task; @item Creating and starting the Idle Task;
@item Initialize all device drivers;
@item Creating and starting the user initialization task(s); and @item Creating and starting the user initialization task(s); and
@item Initiating multitasking. @item Initiating multitasking.
@end itemize @end itemize
This directive MUST be called before any other RTEMS The initialization directives MUST be called in the proper
directives. The effect of calling any RTEMS directives before sequence before any blocking directives may be used. The services
@code{@value{DIRPREFIX}initialize_executive_early} in this manager should be invoked just once per application
is unpredictable. Many of RTEMS actions and in precisely the following order:
during initialization are based upon the contents of the
Configuration Table. For more information regarding the format @itemize @bullet
and contents of this table, please refer to the chapter @item @code{@value{DIRPREFIX}initialize_data_structures}
Configuring a System. @item @code{@value{DIRPREFIX}initialize_before_drivers}
@item @code{@value{DIRPREFIX}initialize_device_drivers}
@item @code{@value{DIRPREFIX}initialize_start_multitasking}
@end itemize
It is recommended that the Board Support Package use the
provided framework which will invoke these services as
part of the executing the function @code{boot_card} in the
file @code{c/src/lib/libbsp/shared/bootcard.c}. This
framework will also assist in allocating memory to the
RTEMS Workspace and C Program Heap and initializing the
C Library.
The effect of calling any blocking RTEMS directives before
@code{@value{DIRPREFIX}initialize_start_multitasking}
is unpredictable but guaranteed to be bad. Afer the
directive @code{@value{DIRPREFIX}initialize_data_structures}
is invoked, it is permissible to allocate RTEMS objects and
perform non-blocking operations. But the user should be
distinctly aware that multitasking is not available yet
and they are @b{NOT} executing in a task context.
Many of RTEMS actions during initialization are based upon
the contents of the Configuration Table. For more information
regarding the format and contents of this table, please refer
to the chapter @ref{Configuring a System}.
The final step in the initialization sequence is the The final step in the initialization sequence is the
initiation of multitasking. When the scheduler and dispatcher initiation of multitasking. When the scheduler and dispatcher
are enabled, the highest priority, ready task will be dispatched are enabled, the highest priority, ready task will be dispatched
to run. Control will not be returned to the board support to run. Control will not be returned to the Board Support
package after multitasking is enabled until Package after multitasking is enabled until the
@code{@value{DIRPREFIX}shutdown_executive_late} @code{@value{DIRPREFIX}shutdown_executive} directive is called.
the directive is called. This directive is called as a side-effect of POSIX calls
including @code{exit}.
@subsection Shutting Down RTEMS @subsection Shutting Down RTEMS
@@ -161,26 +192,26 @@ The @code{@value{DIRPREFIX}shutdown_executive} directive is invoked by the
application to end multitasking and return control to the board application to end multitasking and return control to the board
support package. The board support package resumes execution at support package. The board support package resumes execution at
the code immediately following the invocation of the the code immediately following the invocation of the
@code{@value{DIRPREFIX}initialize_executive} directive. @code{@value{DIRPREFIX}initialize_start_multitasking} directive.
@section Directives @section Directives
This section details the initialization manager's This section details the Initialization Manager's
directives. A subsection is dedicated to each of this manager's directives. A subsection is dedicated to each of this manager's
directives and describes the calling sequence, related directives and describes the calling sequence, related
constants, usage, and status codes. constants, usage, and status codes.
@page @page
@subsection INITIALIZE_EXECUTIVE_EARLY - Initialize RTEMS and do NOT Start Multitasking @subsection INITIALIZE_DATA_STRUCTURES - Initialize RTEMS Data Structures
@cindex initialize RTEMS @cindex initialize RTEMS data structures
@subheading CALLING SEQUENCE: @subheading CALLING SEQUENCE:
@ifset is-C @ifset is-C
@findex rtems_initialize_executive_early @findex rtems_initialize_data_structures
@example @example
rtems_interrupt_level rtems_initialize_executive_early( void rtems_initialize_data_structures(
rtems_configuration_table *configuration_table rtems_configuration_table *configuration_table
); );
@end example @end example
@@ -198,42 +229,36 @@ NONE
@subheading DESCRIPTION: @subheading DESCRIPTION:
This directive is called when the board support This directive is called when the Board Support
package has completed its initialization to allow RTEMS to Package has completed its basic initialization and
initialize the application environment based upon the allows RTEMS to initialize the application environment based upon the
information in the Configuration Table, CPU Dependent information in the Configuration Table, User Initialization
Information Table, User Initialization Tasks Table, Device Tasks Table, Device Driver Table, User Extension Table,
Driver Table, User Extension Table, Multiprocessor Configuration Multiprocessor Configuration Table, and the Multiprocessor
Table, and the Multiprocessor Communications Interface (MPCI) Communications Interface (MPCI) Table. This directive returns
Table. This directive returns to the caller after completing to the caller after completing the basic RTEMS initialization.
the basic RTEMS initialization but before multitasking is
initiated. The interrupt level in place when the directive is
invoked is returned to the caller. This interrupt level should
be the same one passed to
@code{@value{DIRPREFIX}initialize_executive_late}.
@subheading NOTES: @subheading NOTES:
The application must use only one of the two The Initialization Manager directives must be used in the
initialization sequences: proper sequence and invokved only once in the life of an application.
@code{@value{DIRPREFIX}initialize_executive} or
@code{@value{DIRPREFIX}initialize_executive_early} and This directive must be invoked with interrupts disabled.
@code{@value{DIRPREFIX}initialize_executive_late}. Interrupts should be disabled as early as possible in
the initialization sequence and remain disabled until
the first context switch.
@page @page
@subsection INITIALIZE_EXECUTIVE_LATE - Complete Initialization and Start Multitasking @subsection INITIALIZE_BEFORE_DRIVERS - Perform Initialization Before Device Drivers
@cindex initialize RTEMS @cindex initialize RTEMS before device drivers
@cindex start multitasking
@subheading CALLING SEQUENCE: @subheading CALLING SEQUENCE:
@ifset is-C @ifset is-C
@findex rtems_initialize_executive_late @findex rtems_initialize_before_drivers
@example @example
void rtems_initialize_executive_late( void rtems_initialize_before_drivers(void);
rtems_interrupt_level bsp_level
);
@end example @end example
@end ifset @end ifset
@@ -249,21 +274,108 @@ NONE
@subheading DESCRIPTION: @subheading DESCRIPTION:
This directive is called after the This directive is called by the Board Support Package as the
@code{@value{DIRPREFIX}initialize_executive_early} second step in initializing RTEMS. This directive performs
directive has been called to complete initialization that must occur between basis RTEMS data structure
the RTEMS initialization sequence and initiate multitasking. initialization and device driver initialization. In particular,
The interrupt level returned by the in a multiprocessor configuration, this directive will create the
@code{@value{DIRPREFIX}initialize_executive_early} MPCI Server Task. This directive returns to the caller after
directive should be in bsp_level and this value is restored as completing the basic RTEMS initialization.
part of this directive returning to the caller after the
@code{@value{DIRPREFIX}shutdown_executive}
directive is invoked.
@subheading NOTES: @subheading NOTES:
This directive MUST be the second RTEMS directive The Initialization Manager directives must be used in the
called and it DOES NOT RETURN to the caller until the proper sequence and invokved only once in the life of an application.
This directive must be invoked with interrupts disabled.
Interrupts should be disabled as early as possible in
the initialization sequence and remain disabled until
the first context switch.
@page
@subsection INITIALIZE_DEVICE_DRIVERS - Initialize Device Drivers
@cindex initialize device drivers
@subheading CALLING SEQUENCE:
@ifset is-C
@findex rtems_initialize_device_drivers
@example
void rtems_initialize_device_drivers(void);
@end example
@end ifset
@ifset is-Ada
@example
NOT SUPPORTED FROM Ada BINDING
@end example
@end ifset
@subheading DIRECTIVE STATUS CODES:
NONE
@subheading DESCRIPTION:
This directive is called by the Board Support Package as the
third step in initializing RTEMS. This directive initializes
all statically configured device drivers and performs all RTEMS
initialization which requires device drivers to be initialized.
In a multiprocessor configuration, this service will initialize
the Multiprocessor Communications Interface (MPCI) and synchronize
with the other nodes in the system.
After this directive is executed, control will be returned to
the Board Support Package framework.
@subheading NOTES:
The Initialization Manager directives must be used in the
proper sequence and invokved only once in the life of an application.
This directive must be invoked with interrupts disabled.
Interrupts should be disabled as early as possible in
the initialization sequence and remain disabled until
the first context switch.
@page
@subsection INITIALIZE_START_MULTITASKING - Complete Initialization and Start Multitasking
@cindex initialize RTEMS
@cindex start multitasking
@subheading CALLING SEQUENCE:
@ifset is-C
@findex rtems_initialize_start_multitasking
@example
void rtems_initialize_start_multitasking(void);
@end example
@end ifset
@ifset is-Ada
@example
NOT SUPPORTED FROM Ada BINDING
@end example
@end ifset
@subheading DIRECTIVE STATUS CODES:
NONE
@subheading DESCRIPTION:
This directive is called after the other Initialization Manager
directives have successfully completed. This directive
initiates multitasking and performs a context switch to
the first user application task and enables interrupts as
a side-effect of that context switch.
@subheading NOTES:
This directive @b{DOES NOT RETURN} to the caller until the
@code{@value{DIRPREFIX}shutdown_executive} is invoked. @code{@value{DIRPREFIX}shutdown_executive} is invoked.
This directive causes all nodes in the system to This directive causes all nodes in the system to
@@ -271,14 +383,6 @@ verify that certain configuration parameters are the same as
those of the local node. If an inconsistency is detected, then those of the local node. If an inconsistency is detected, then
a fatal error is generated. a fatal error is generated.
The application must use only one of the two
initialization sequences:
@code{@value{DIRPREFIX}initialize_executive} or
@code{@value{DIRPREFIX}initialize_executive_early} and
@code{@value{DIRPREFIX}initialize_executive_late}.
@page @page
@subsection SHUTDOWN_EXECUTIVE - Shutdown RTEMS @subsection SHUTDOWN_EXECUTIVE - Shutdown RTEMS