Use linker set for system initialization

Make rtems_initialize_data_structures(),
rtems_initialize_before_drivers() and rtems_initialize_device_drivers()
static.  Rename rtems_initialize_start_multitasking() to
rtems_initialize_executive() and call the registered system
initialization handlers in this function.  Add system initialization API
available via #include <rtems/sysinit.h>.  Update the documentation
accordingly.

This is no functional change, only the method to call the existing
initialization routines changes.  Instead of direct function calls a
table of function pointers contained in the new RTEMS system
initialization linker set is used.  This table looks like this (the
actual addresses depend on the target).

nm *.exe | grep _Linker | sort
0201a2d0 D _Linker_set__Sysinit_begin
0201a2d0 D _Linker_set__Sysinit_bsp_work_area_initialize
0201a2d4 D _Linker_set__Sysinit_bsp_start
0201a2d8 D _Linker_set__Sysinit_rtems_initialize_data_structures
0201a2dc D _Linker_set__Sysinit_bsp_libc_init
0201a2e0 D _Linker_set__Sysinit_rtems_initialize_before_drivers
0201a2e4 D _Linker_set__Sysinit_bsp_predriver_hook
0201a2e8 D _Linker_set__Sysinit_rtems_initialize_device_drivers
0201a2ec D _Linker_set__Sysinit_bsp_postdriver_hook
0201a2f0 D _Linker_set__Sysinit_end

Add test sptests/spsysinit01.

Update #2408.
This commit is contained in:
Sebastian Huber
2015-09-22 16:21:12 +02:00
parent d19d1c23ec
commit d0c3983814
14 changed files with 457 additions and 349 deletions

View File

@@ -8,25 +8,8 @@
* This is the C entry point for ALL RTEMS BSPs. It is invoked * This is the C entry point for ALL RTEMS BSPs. It is invoked
* from the assembly language initialization file usually called * from the assembly language initialization file usually called
* start.S. It provides the framework for the BSP initialization * start.S. It provides the framework for the BSP initialization
* sequence. The basic flow of initialization is: * sequence. For the basic flow of initialization see RTEMS C User's Guide,
* * Initialization Manager.
* + start.S: basic CPU setup (stack, zero BSS)
* + boot_card
* + bspstart.c: bsp_start - more advanced initialization
* + obtain information on BSP memory and allocate RTEMS Workspace
* + rtems_initialize_data_structures
* + allocate memory to C Program Heap
* + initialize C Library and C Program Heap
* + rtems_initialize_before_drivers
* + bsp_predriver_hook
* + rtems_initialize_device_drivers
* - all device drivers
* + bsp_postdriver_hook
* + rtems_initialize_start_multitasking
* - 1st task executes C++ global constructors
* .... appplication runs ...
* - exit
* + will not return to here
* *
* This style of initialization ensures that the C++ global * This style of initialization ensures that the C++ global
* constructors are executed after RTEMS is initialized. * constructors are executed after RTEMS is initialized.
@@ -46,6 +29,7 @@
#include <bsp/bootcard.h> #include <bsp/bootcard.h>
#include <rtems.h> #include <rtems.h>
#include <rtems/sysinit.h>
/* /*
* At most a single pointer to the cmdline for those target * At most a single pointer to the cmdline for those target
@@ -53,6 +37,36 @@
*/ */
const char *bsp_boot_cmdline; const char *bsp_boot_cmdline;
RTEMS_SYSINIT_ITEM(
bsp_work_area_initialize,
RTEMS_SYSINIT_BSP_WORK_AREAS,
RTEMS_SYSINIT_ORDER_MIDDLE
);
RTEMS_SYSINIT_ITEM(
bsp_start,
RTEMS_SYSINIT_BSP_START,
RTEMS_SYSINIT_ORDER_MIDDLE
);
RTEMS_SYSINIT_ITEM(
bsp_libc_init,
RTEMS_SYSINIT_BSP_LIBC,
RTEMS_SYSINIT_ORDER_MIDDLE
);
RTEMS_SYSINIT_ITEM(
bsp_predriver_hook,
RTEMS_SYSINIT_BSP_PRE_DRIVERS,
RTEMS_SYSINIT_ORDER_MIDDLE
);
RTEMS_SYSINIT_ITEM(
bsp_postdriver_hook,
RTEMS_SYSINIT_BSP_POST_DRIVERS,
RTEMS_SYSINIT_ORDER_MIDDLE
);
/* /*
* This is the initialization framework routine that weaves together * This is the initialization framework routine that weaves together
* calls to RTEMS and the BSP in the proper sequence to initialize * calls to RTEMS and the BSP in the proper sequence to initialize
@@ -73,59 +87,7 @@ void boot_card(
bsp_boot_cmdline = cmdline; bsp_boot_cmdline = cmdline;
/* rtems_initialize_executive();
* Initialize the RTEMS Workspace and the C Program Heap.
*/
bsp_work_area_initialize();
/*
* Invoke Board Support Package initialization routine written in C.
*/
bsp_start();
/*
* Initialize RTEMS data structures
*/
rtems_initialize_data_structures();
/*
* Initialize the C library for those BSPs using the shared
* framework.
*/
bsp_libc_init();
/*
* Let RTEMS perform initialization it requires before drivers
* are allowed to be initialized.
*/
rtems_initialize_before_drivers();
/*
* Execute BSP specific pre-driver hook. Drivers haven't gotten
* to initialize yet so this is a good chance to initialize
* buses, spurious interrupt handlers, etc..
*
* NOTE: Many BSPs do not require this handler and use the
* shared stub.
*/
bsp_predriver_hook();
/*
* Initialize all device drivers.
*/
rtems_initialize_device_drivers();
/*
* Invoke the postdriver hook. This normally opens /dev/console
* for use as stdin, stdout, and stderr.
*/
bsp_postdriver_hook();
/*
* Complete initialization of RTEMS and switch to the first task.
* Global C++ constructors will be executed in the context of that task.
*/
rtems_initialize_start_multitasking();
/*************************************************************** /***************************************************************
*************************************************************** ***************************************************************

View File

@@ -71,26 +71,8 @@ void bsp_reset(void);
* assembly language initialization file usually called @c start.S which does * assembly language initialization file usually called @c start.S which does
* the basic CPU setup (stack, C runtime environment, zero BSS, load other * the basic CPU setup (stack, C runtime environment, zero BSS, load other
* sections) and calls afterwards boot_card(). The boot card function provides * sections) and calls afterwards boot_card(). The boot card function provides
* the framework for the BSP initialization sequence. The basic flow of * the framework for the BSP initialization sequence. For the basic flow of
* initialization is: * initialization see RTEMS C User's Guide, Initialization Manager.
*
* - disable interrupts, interrupts will be enabled during the first context
* switch
* - bsp_work_area_initialize() - initialize the RTEMS Workspace and the C
* Program Heap
* - bsp_start() - more advanced initialization
* - rtems_initialize_data_structures()
* - initialize C Library
* - rtems_initialize_before_drivers()
* - bsp_predriver_hook()
* - rtems_initialize_device_drivers()
* - initialization of all device drivers
* - bsp_postdriver_hook()
* - rtems_initialize_start_multitasking()
* - 1st task executes C++ global constructors
* - .... application runs ...
* - exit
* - will not return to here
* *
* This style of initialization ensures that the C++ global constructors are * This style of initialization ensures that the C++ global constructors are
* executed after RTEMS is initialized. * executed after RTEMS is initialized.

View File

@@ -46,46 +46,16 @@ extern const rtems_multiprocessing_table
#endif #endif
/** /**
* @brief RTEMS data structures initialization. * @brief Initializes the system and starts multitasking.
* *
* This routine implements the portion of the RTEMS initializatin process * Iterates through the system initialization linker set and invokes the
* that involves initializing data structures to a state that scheduling * registered handlers. The final step is to start multitasking.
* can occur in a consistent manner.
*/
void rtems_initialize_data_structures(void);
/**
* @brief RTEMS initialization before the device drivers are initialized.
* *
* This routine implements the portion of RTEMS initialization that * This directive should be called by boot_card() only.
* is done immediately before device drivers are initialized.
*/
void rtems_initialize_before_drivers(void);
/**
* @brief RTEMS initialization that initializes all device drivers.
*
* This routine implements the portion of RTEMS initialization that
* initializes all device drivers.
*/
void rtems_initialize_device_drivers(void);
/**
* @brief Starts the multitasking.
*
* This directive initiates multitasking and performs a context switch to the
* first user application task and may enable interrupts as a side-effect of
* that context switch. The context switch saves the executing context. The
* application runs now. The directive rtems_shutdown_executive() will return
* to the saved context. The exit() function will use this directive.
*
* After a return to the saved context a fatal system state is reached. The
* fatal source is RTEMS_FATAL_SOURCE_EXIT with a fatal code set to the value
* passed to rtems_shutdown_executive().
* *
* This directive does not return. * This directive does not return.
*/ */
void rtems_initialize_start_multitasking(void) void rtems_initialize_executive(void)
RTEMS_NO_RETURN; RTEMS_NO_RETURN;
/** /**
@@ -93,9 +63,8 @@ void rtems_initialize_start_multitasking(void)
* *
* This routine implements the rtems_shutdown_executive directive. The * This routine implements the rtems_shutdown_executive directive. The
* invocation of this directive results in the RTEMS environment being * invocation of this directive results in the RTEMS environment being
* shutdown and multitasking halted. From the application's perspective, * shutdown and multitasking halted. The system is terminated with a fatal
* invocation of this directive results in the rtems_initialize_executive * source of RTEMS_FATAL_SOURCE_EXIT and the specified result code.
* directive exitting to the startup code which invoked it.
*/ */
void rtems_shutdown_executive( void rtems_shutdown_executive(
uint32_t result uint32_t result

View File

@@ -31,6 +31,7 @@
#include <rtems/config.h> #include <rtems/config.h>
#include <rtems/extensionimpl.h> #include <rtems/extensionimpl.h>
#include <rtems/init.h> #include <rtems/init.h>
#include <rtems/sysinit.h>
#include <rtems/score/sysstate.h> #include <rtems/score/sysstate.h>
#include <rtems/score/apiext.h> #include <rtems/score/apiext.h>
@@ -62,7 +63,7 @@
Objects_Information *_Internal_Objects[ OBJECTS_INTERNAL_CLASSES_LAST + 1 ]; Objects_Information *_Internal_Objects[ OBJECTS_INTERNAL_CLASSES_LAST + 1 ];
void rtems_initialize_data_structures(void) static void rtems_initialize_data_structures(void)
{ {
/* /*
* Dispatching and interrupts are disabled until the end of the * Dispatching and interrupts are disabled until the end of the
@@ -152,7 +153,7 @@ void rtems_initialize_data_structures(void)
*/ */
} }
void rtems_initialize_before_drivers(void) static void rtems_initialize_before_drivers(void)
{ {
#ifdef RTEMS_DRVMGR_STARTUP #ifdef RTEMS_DRVMGR_STARTUP
_DRV_Manager_initialization(); _DRV_Manager_initialization();
@@ -163,7 +164,7 @@ void rtems_initialize_before_drivers(void)
#endif #endif
} }
void rtems_initialize_device_drivers(void) static void rtems_initialize_device_drivers(void)
{ {
/* /*
* Initialize all the device drivers and initialize the MPCI layer. * Initialize all the device drivers and initialize the MPCI layer.
@@ -246,8 +247,37 @@ void rtems_initialize_device_drivers(void)
_API_extensions_Run_postdriver(); _API_extensions_Run_postdriver();
} }
void rtems_initialize_start_multitasking(void) RTEMS_LINKER_ROSET( _Sysinit, rtems_sysinit_item );
RTEMS_SYSINIT_ITEM(
rtems_initialize_data_structures,
RTEMS_SYSINIT_DATA_STRUCTURES,
RTEMS_SYSINIT_ORDER_MIDDLE
);
RTEMS_SYSINIT_ITEM(
rtems_initialize_before_drivers,
RTEMS_SYSINIT_BEFORE_DRIVERS,
RTEMS_SYSINIT_ORDER_MIDDLE
);
RTEMS_SYSINIT_ITEM(
rtems_initialize_device_drivers,
RTEMS_SYSINIT_DEVICE_DRIVERS,
RTEMS_SYSINIT_ORDER_MIDDLE
);
void rtems_initialize_executive(void)
{ {
const volatile rtems_sysinit_item *cur = RTEMS_LINKER_SET_BEGIN(_Sysinit );
const volatile rtems_sysinit_item *end = RTEMS_LINKER_SET_END( _Sysinit );
/* Invoke the registered system initialization handlers */
while ( cur != end ) {
( *cur->handler )();
++cur;
}
_System_state_Set( SYSTEM_STATE_UP ); _System_state_Set( SYSTEM_STATE_UP );
_SMP_Request_start_multitasking(); _SMP_Request_start_multitasking();

View File

@@ -18,6 +18,7 @@ include_rtemsdir = $(includedir)/rtems
include_rtems_HEADERS = include_rtems_HEADERS =
include_rtems_HEADERS += include/rtems/linkersets.h include_rtems_HEADERS += include/rtems/linkersets.h
include_rtems_HEADERS += include/rtems/sysinit.h
include_rtems_HEADERS += include/rtems/system.h include_rtems_HEADERS += include/rtems/system.h
include_rtems_HEADERS += include/rtems/seterr.h include_rtems_HEADERS += include/rtems/seterr.h

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2015 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef _RTEMS_SYSINIT_H
#define _RTEMS_SYSINIT_H
#include <rtems/linkersets.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* The value of each module define must consist of exactly six hexadecimal
* digits without a 0x-prefix. A 0x-prefix is concatenated with the module and
* order values to form a proper integer literal.
*/
#define RTEMS_SYSINIT_BSP_WORK_AREAS 000100
#define RTEMS_SYSINIT_BSP_START 000200
#define RTEMS_SYSINIT_DATA_STRUCTURES 000300
#define RTEMS_SYSINIT_BSP_LIBC 000400
#define RTEMS_SYSINIT_BEFORE_DRIVERS 000500
#define RTEMS_SYSINIT_BSP_PRE_DRIVERS 000600
#define RTEMS_SYSINIT_DEVICE_DRIVERS 000700
#define RTEMS_SYSINIT_BSP_POST_DRIVERS 000800
/*
* The value of each order define must consist of exactly two hexadecimal
* digits without a 0x-prefix. A 0x-prefix is concatenated with the module and
* order values to form a proper integer literal.
*/
#define RTEMS_SYSINIT_ORDER_FIRST 00
#define RTEMS_SYSINIT_ORDER_MIDDLE 08
#define RTEMS_SYSINIT_ORDER_LAST 0f
typedef void ( *rtems_sysinit_handler )( void );
typedef struct {
rtems_sysinit_handler handler;
} rtems_sysinit_item;
/* The enum helps to detect typos in the module and order parameters */
#define _RTEMS_SYSINIT_INDEX_ITEM( handler, index ) \
enum { _Sysinit_##handler = index }; \
RTEMS_LINKER_ROSET_ITEM_ORDERED( \
_Sysinit, \
rtems_sysinit_item, \
handler, \
index \
) = { handler }
/* Create index from module and order */
#define _RTEMS_SYSINIT_ITEM( handler, module, order ) \
_RTEMS_SYSINIT_INDEX_ITEM( handler, 0x##module##order )
/* Perform parameter expansion */
#define RTEMS_SYSINIT_ITEM( handler, module, order ) \
_RTEMS_SYSINIT_ITEM( handler, module, order )
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _RTEMS_SYSINIT_H */

View File

@@ -47,6 +47,10 @@ $(PROJECT_INCLUDE)/rtems/linkersets.h: include/rtems/linkersets.h $(PROJECT_INCL
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/linkersets.h $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/linkersets.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/linkersets.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/linkersets.h
$(PROJECT_INCLUDE)/rtems/sysinit.h: include/rtems/sysinit.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/sysinit.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/sysinit.h
$(PROJECT_INCLUDE)/rtems/system.h: include/rtems/system.h $(PROJECT_INCLUDE)/rtems/$(dirstamp) $(PROJECT_INCLUDE)/rtems/system.h: include/rtems/system.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/system.h $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/system.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/system.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/system.h

View File

@@ -16,10 +16,7 @@ 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_data_structures} - Initialize RTEMS Data Structures @item @code{@value{DIRPREFIX}initialize_executive} - Initialize RTEMS
@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
@@ -58,12 +55,12 @@ System Initialization begins with board reset and continues
through RTEMS initialization, initialization of all device through RTEMS initialization, initialization of all device
drivers, and eventually a context switch to the first user drivers, and eventually a context switch to the first user
task. Remember, that interrupts are disabled during task. Remember, that interrupts are disabled during
initialization and the @i{initialization thread} is not initialization and the @i{initialization context} is not
a task in any sense and the user should be very careful a task in any sense and the user should be very careful
during initialzation. during initialization.
The BSP must ensure that the there is enough stack The BSP must ensure that the there is enough stack
space reserved for the initialization "thread" to space reserved for the initialization context to
successfully execute the initialization routines for 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
@@ -125,71 +122,96 @@ may be found @ref{Fatal Error Manager Announcing a Fatal Error}.
@subsection Initializing RTEMS @subsection Initializing RTEMS
The Initialization Manager directives are called by the The Initialization Manager @code{@value{DIRPREFIX}initialize_executive}
Board Support Package framework as part of its initialization directives is called by the @code{boot_card} routine. The @code{boot_card}
sequence. RTEMS assumes that the Board Support Package routine is invoked by the Board Support Package once a basic C run-time
successfully completed its initialization activities. These environment is set up. This consists of
directives initialize RTEMS by performing the following actions:
@itemize @bullet @itemize @bullet
@item Initializing internal RTEMS variables; @item a valid and accessible text section, read-only data, read-write data and
@item Allocating system resources; zero-initialized data,
@item Creating and starting the Idle Task; @item an initialization stack large enough to initialize the rest of the Board
@item Initialize all device drivers; Support Package, RTEMS and the device drivers,
@item Creating and starting the user initialization task(s); and @item all registers and components mandated by Application Binary Interface, and
@item Initiating multitasking. @item disabled interrupts.
@end itemize @end itemize
The initialization directives MUST be called in the proper The @code{@value{DIRPREFIX}initialize_executive} directive uses a system
sequence before any blocking directives may be used. The services initialization linker set to initialize only those parts of the overall RTEMS
in this manager should be invoked just once per application feature set that is necessary for a particular application. @xref{Linker
and in precisely the following order: Sets}. Each RTEMS feature used the application may optionally register an
initialization handler. The system initialization API is available via
@code{#included <rtems/sysinit.h>}.
@itemize @bullet A list of all initialization steps follows. Some steps are optional depending
@item @code{@value{DIRPREFIX}initialize_data_structures} on the requested feature set of the application. The initialization steps are
@item @code{@value{DIRPREFIX}initialize_before_drivers} execute in the order presented here.
@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 @table @dfn
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 @item RTEMS_SYSINIT_BSP_WORK_AREAS
@code{@value{DIRPREFIX}initialize_start_multitasking} The work areas consisting of C Program Heap and the RTEMS Workspace are
is unpredictable but guaranteed to be bad. After the initialized by the Board Support Package. This step is mandatory.
directive @code{@value{DIRPREFIX}initialize_data_structures}
is invoked, it is permissible to allocate RTEMS objects and @item RTEMS_SYSINIT_BSP_START
perform non-blocking operations. But the user should be Basic initialization step provided by the Board Support Package. This step is
distinctly aware that multitasking is not available yet mandatory.
and they are @b{NOT} executing in a task context.
@item RTEMS_SYSINIT_DATA_STRUCTURES
This directive is called when the Board Support Package has completed its basic
initialization and allows RTEMS to initialize the application environment based
upon the information in the Configuration Table, User Initialization Tasks
Table, Device Driver Table, User Extension Table, Multiprocessor Configuration
Table, and the Multiprocessor Communications Interface (MPCI) Table.
@item RTEMS_SYSINIT_BSP_LIBC
Depending on the application configuration the IO library and root filesystem
is initialized. This step is mandatory.
@item RTEMS_SYSINIT_BEFORE_DRIVERS
This directive performs initialization that must occur between basis RTEMS data
structure initialization and device driver initialization. In particular, in a
multiprocessor configuration, this directive will create the MPCI Server Task.
@item RTEMS_SYSINIT_BSP_PRE_DRIVERS
Initialization step performed right before device drivers are initialized
provided by the Board Support Package. This step is mandatory.
@item RTEMS_SYSINIT_DEVICE_DRIVERS
This step initializes all statically configured device drivers and performs all
RTEMS initialization which requires device drivers to be initialized. This
step is mandatory.
In a multiprocessor configuration, this service will initialize the
Multiprocessor Communications Interface (MPCI) and synchronize with the other
nodes in the system.
@item RTEMS_SYSINIT_BSP_POST_DRIVERS
Initialization step performed right after device drivers are initialized
provided by the Board Support Package. This step is mandatory.
@end table
The final action of the @code{@value{DIRPREFIX}initialize_executive} directive
is to start multitasking. RTEMS does not return to the initialization context
and the initialization stack may be re-used for interrupt processing.
Many of RTEMS actions during initialization are based upon Many of RTEMS actions during initialization are based upon
the contents of the Configuration Table. For more information the contents of the Configuration Table. For more information
regarding the format and contents of this table, please refer regarding the format and contents of this table, please refer
to the chapter @ref{Configuring a System}. to the chapter @ref{Configuring a System}.
The final step in the initialization sequence is the The final action 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 the Package after multitasking is enabled. The initialization stack may be re-used
@code{@value{DIRPREFIX}shutdown_executive} directive is called. for interrupt processing.
This directive is called as a side-effect of POSIX calls
including @code{exit}.
@subsection Shutting Down RTEMS @subsection Shutting Down RTEMS
The @code{@value{DIRPREFIX}shutdown_executive} directive is invoked by the 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 terminate the system.
support package. The board support package resumes execution at
the code immediately following the invocation of the
@code{@value{DIRPREFIX}initialize_start_multitasking} directive.
@section Directives @section Directives
@@ -199,144 +221,7 @@ directives and describes the calling sequence, related
constants, usage, and status codes. constants, usage, and status codes.
@page @page
@subsection INITIALIZE_DATA_STRUCTURES - Initialize RTEMS Data Structures @subsection INITIALIZE_EXECUTIVE - Initialize RTEMS
@cindex initialize RTEMS data structures
@subheading CALLING SEQUENCE:
@ifset is-C
@findex rtems_initialize_data_structures
@example
void rtems_initialize_data_structures(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 when the Board Support
Package has completed its basic initialization and
allows RTEMS to initialize the application environment based upon the
information in the Configuration Table, User Initialization
Tasks Table, Device Driver Table, User Extension Table,
Multiprocessor Configuration Table, and the Multiprocessor
Communications Interface (MPCI) Table. This directive returns
to the caller after completing the basic RTEMS initialization.
@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_BEFORE_DRIVERS - Perform Initialization Before Device Drivers
@cindex initialize RTEMS before device drivers
@subheading CALLING SEQUENCE:
@ifset is-C
@findex rtems_initialize_before_drivers
@example
void rtems_initialize_before_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
second step in initializing RTEMS. This directive performs
initialization that must occur between basis RTEMS data structure
initialization and device driver initialization. In particular,
in a multiprocessor configuration, this directive will create the
MPCI Server Task. This directive returns to the caller after
completing the basic RTEMS initialization.
@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_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 initialize RTEMS
@cindex start multitasking @cindex start multitasking
@@ -344,9 +229,9 @@ the first context switch.
@subheading CALLING SEQUENCE: @subheading CALLING SEQUENCE:
@ifset is-C @ifset is-C
@findex rtems_initialize_start_multitasking @findex rtems_initialize_executive
@example @example
void rtems_initialize_start_multitasking(void); void rtems_initialize_executive(void);
@end example @end example
@end ifset @end ifset
@@ -362,24 +247,15 @@ NONE
@subheading DESCRIPTION: @subheading DESCRIPTION:
This directive initiates multitasking and performs a context switch to the Iterates through the system initialization linker set and invokes the
first user application task and may enable interrupts as a side-effect of registered handlers. The final step is to start multitasking.
that context switch. The context switch saves the executing context. The
application runs now. The directive rtems_shutdown_executive() will return
to the saved context. The exit() function will use this directive.
After a return to the saved context a fatal system state is reached. The
fatal source is RTEMS_FATAL_SOURCE_EXIT with a fatal code set to the value
passed to rtems_shutdown_executive().
@subheading NOTES: @subheading NOTES:
This directive @b{DOES NOT RETURN} to the caller. This directive should be called by @code{boot_card} only.
This directive causes all nodes in the system to This directive @b{does not return} to the caller. Errors in the initialization
verify that certain configuration parameters are the same as sequence are usually fatal and lead to a system termination.
those of the local node. If an inconsistency is detected, then
a fatal error is generated.
@page @page
@subsection SHUTDOWN_EXECUTIVE - Shutdown RTEMS @subsection SHUTDOWN_EXECUTIVE - Shutdown RTEMS
@@ -411,16 +287,13 @@ NONE
@subheading DESCRIPTION: @subheading DESCRIPTION:
This directive is called when the application wishes This directive is called when the application wishes to shutdown RTEMS. The
to shutdown RTEMS and return control to the board support system is terminated with a fatal source of @code{RTEMS_FATAL_SOURCE_EXIT} and
package. The board support package resumes execution at the the specified @code{result} code.
code immediately following the invocation of the
@code{@value{DIRPREFIX}initialize_executive} directive.
@subheading NOTES: @subheading NOTES:
This directive MUST be the last RTEMS directive This directive @b{must} be the last RTEMS directive
invoked by an application and it DOES NOT RETURN to the caller. invoked by an application and it @b{does not return} to the caller.
This directive should not be invoked until the This directive may be called any time.
executive has successfully completed initialization.

View File

@@ -33,6 +33,7 @@ _SUBDIRS = \
spsignal_err01 spport_err01 spmsgq_err01 spmsgq_err02 spsem_err01 \ spsignal_err01 spport_err01 spmsgq_err01 spmsgq_err02 spsem_err01 \
spsem_err02 sptask_err01 spevent_err03 sptask_err03 sptask_err02 \ spsem_err02 sptask_err01 spevent_err03 sptask_err03 sptask_err02 \
sptask_err04 spclock_err01 sptask_err04 spclock_err01
_SUBDIRS += spsysinit01
if HAS_SMP if HAS_SMP
else else
_SUBDIRS += sp29 _SUBDIRS += sp29

View File

@@ -46,6 +46,7 @@ AM_CONDITIONAL(HAS_SMP,test "$rtems_cv_RTEMS_SMP" = "yes")
# Explicitly list all Makefiles here # Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
spsysinit01/Makefile
splinkersets01/Makefile splinkersets01/Makefile
spstdthreads01/Makefile spstdthreads01/Makefile
spsyslock01/Makefile spsyslock01/Makefile

View File

@@ -0,0 +1,19 @@
rtems_tests_PROGRAMS = spsysinit01
spsysinit01_SOURCES = init.c
dist_rtems_tests_DATA = spsysinit01.scn spsysinit01.doc
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../automake/compile.am
include $(top_srcdir)/../automake/leaf.am
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
LINK_OBJS = $(spsysinit01_OBJECTS)
LINK_LIBS = $(spsysinit01_LDLIBS)
spsysinit01$(EXEEXT): $(spsysinit01_OBJECTS) $(spsysinit01_DEPENDENCIES)
@rm -f spsysinit01$(EXEEXT)
$(make-exe)
include $(top_srcdir)/../automake/local.am

View File

@@ -0,0 +1,176 @@
/*
* Copyright (c) 2015 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <rtems.h>
#include <rtems/libio_.h>
#include <rtems/sysinit.h>
#include <rtems/test.h>
#include <rtems/score/sysstate.h>
#include <rtems/score/wkspace.h>
const char rtems_test_name[] = "SPSYSINIT 1";
#define FIRST(x) \
static void x##_first(void); \
RTEMS_SYSINIT_ITEM( \
x##_first, \
x, \
RTEMS_SYSINIT_ORDER_FIRST \
); \
static void x##_first(void)
#define LAST(x) \
static void x##_last(void); \
RTEMS_SYSINIT_ITEM( \
x##_last, \
x, \
RTEMS_SYSINIT_ORDER_LAST \
); \
static void x##_last(void)
static int step;
static void next_step(int expected)
{
assert(step == expected);
step = expected + 1;
}
FIRST(RTEMS_SYSINIT_BSP_WORK_AREAS)
{
rtems_test_begink();
assert(_Workspace_Area.area_begin == 0);
next_step(0);
}
LAST(RTEMS_SYSINIT_BSP_WORK_AREAS)
{
assert(_Workspace_Area.area_begin != 0);
next_step(1);
}
FIRST(RTEMS_SYSINIT_BSP_START)
{
/*
* Since the work performed here is BSP-specific, there is no way to test pre
* and post conditions.
*/
next_step(2);
}
LAST(RTEMS_SYSINIT_BSP_START)
{
next_step(3);
}
FIRST(RTEMS_SYSINIT_DATA_STRUCTURES)
{
assert(_System_state_Is_before_initialization(_System_state_Get()));
next_step(4);
}
LAST(RTEMS_SYSINIT_DATA_STRUCTURES)
{
assert(_System_state_Is_before_multitasking(_System_state_Get()));
next_step(5);
}
FIRST(RTEMS_SYSINIT_BSP_LIBC)
{
assert(rtems_libio_semaphore == 0);
next_step(6);
}
LAST(RTEMS_SYSINIT_BSP_LIBC)
{
assert(rtems_libio_semaphore != 0);
next_step(7);
}
FIRST(RTEMS_SYSINIT_BEFORE_DRIVERS)
{
/* Omit test of build configuration specific pre and post conditions */
next_step(8);
}
LAST(RTEMS_SYSINIT_BEFORE_DRIVERS)
{
next_step(9);
}
FIRST(RTEMS_SYSINIT_BSP_PRE_DRIVERS)
{
/*
* Since the work performed here is BSP-specific, there is no way to test pre
* and post conditions.
*/
next_step(10);
}
LAST(RTEMS_SYSINIT_BSP_PRE_DRIVERS)
{
next_step(11);
}
FIRST(RTEMS_SYSINIT_DEVICE_DRIVERS)
{
assert(!_IO_All_drivers_initialized);
next_step(12);
}
LAST(RTEMS_SYSINIT_DEVICE_DRIVERS)
{
assert(_IO_All_drivers_initialized);
next_step(13);
}
FIRST(RTEMS_SYSINIT_BSP_POST_DRIVERS)
{
assert(rtems_libio_iop_freelist != NULL);
next_step(14);
}
LAST(RTEMS_SYSINIT_BSP_POST_DRIVERS)
{
assert(rtems_libio_iop_freelist == NULL);
next_step(15);
}
static void Init(rtems_task_argument arg)
{
next_step(16);
rtems_test_endk();
exit(0);
}
#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_INIT
#include <rtems/confdefs.h>

View File

@@ -0,0 +1,13 @@
This file describes the directives and concepts tested by this test set.
test set name: spsysinit01
directives:
- rtems_initialize_executive()
concepts:
- Ensures that each initialization step is performed in the right order.
- Ensures that each initialization step performs the intended
initializations.

View File

@@ -0,0 +1,2 @@
*** BEGIN OF TEST SPSYSINIT 1 ***
*** END OF TEST SPSYSINIT 1 ***