forked from Imagelibrary/rtems
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:
@@ -8,25 +8,8 @@
|
||||
* This is the C entry point for ALL RTEMS BSPs. It is invoked
|
||||
* from the assembly language initialization file usually called
|
||||
* start.S. It provides the framework for the BSP initialization
|
||||
* sequence. The basic flow of initialization is:
|
||||
*
|
||||
* + 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
|
||||
* sequence. For the basic flow of initialization see RTEMS C User's Guide,
|
||||
* Initialization Manager.
|
||||
*
|
||||
* This style of initialization ensures that the C++ global
|
||||
* constructors are executed after RTEMS is initialized.
|
||||
@@ -46,6 +29,7 @@
|
||||
#include <bsp/bootcard.h>
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/sysinit.h>
|
||||
|
||||
/*
|
||||
* At most a single pointer to the cmdline for those target
|
||||
@@ -53,6 +37,36 @@
|
||||
*/
|
||||
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
|
||||
* calls to RTEMS and the BSP in the proper sequence to initialize
|
||||
@@ -73,59 +87,7 @@ void boot_card(
|
||||
|
||||
bsp_boot_cmdline = cmdline;
|
||||
|
||||
/*
|
||||
* 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();
|
||||
rtems_initialize_executive();
|
||||
|
||||
/***************************************************************
|
||||
***************************************************************
|
||||
|
||||
@@ -71,26 +71,8 @@ void bsp_reset(void);
|
||||
* assembly language initialization file usually called @c start.S which does
|
||||
* the basic CPU setup (stack, C runtime environment, zero BSS, load other
|
||||
* sections) and calls afterwards boot_card(). The boot card function provides
|
||||
* the framework for the BSP initialization sequence. The basic flow of
|
||||
* initialization is:
|
||||
*
|
||||
* - 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
|
||||
* the framework for the BSP initialization sequence. For the basic flow of
|
||||
* initialization see RTEMS C User's Guide, Initialization Manager.
|
||||
*
|
||||
* This style of initialization ensures that the C++ global constructors are
|
||||
* executed after RTEMS is initialized.
|
||||
|
||||
@@ -46,46 +46,16 @@ extern const rtems_multiprocessing_table
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief RTEMS data structures initialization.
|
||||
* @brief Initializes the system and starts multitasking.
|
||||
*
|
||||
* This routine implements the portion of the RTEMS initializatin process
|
||||
* that involves initializing data structures to a state that scheduling
|
||||
* can occur in a consistent manner.
|
||||
*/
|
||||
void rtems_initialize_data_structures(void);
|
||||
|
||||
/**
|
||||
* @brief RTEMS initialization before the device drivers are initialized.
|
||||
* Iterates through the system initialization linker set and invokes the
|
||||
* registered handlers. The final step is to start multitasking.
|
||||
*
|
||||
* This routine implements the portion of RTEMS initialization that
|
||||
* 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 should be called by boot_card() only.
|
||||
*
|
||||
* This directive does not return.
|
||||
*/
|
||||
void rtems_initialize_start_multitasking(void)
|
||||
void rtems_initialize_executive(void)
|
||||
RTEMS_NO_RETURN;
|
||||
|
||||
/**
|
||||
@@ -93,9 +63,8 @@ void rtems_initialize_start_multitasking(void)
|
||||
*
|
||||
* This routine implements the rtems_shutdown_executive directive. The
|
||||
* invocation of this directive results in the RTEMS environment being
|
||||
* shutdown and multitasking halted. From the application's perspective,
|
||||
* invocation of this directive results in the rtems_initialize_executive
|
||||
* directive exitting to the startup code which invoked it.
|
||||
* shutdown and multitasking halted. The system is terminated with a fatal
|
||||
* source of RTEMS_FATAL_SOURCE_EXIT and the specified result code.
|
||||
*/
|
||||
void rtems_shutdown_executive(
|
||||
uint32_t result
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <rtems/config.h>
|
||||
#include <rtems/extensionimpl.h>
|
||||
#include <rtems/init.h>
|
||||
#include <rtems/sysinit.h>
|
||||
#include <rtems/score/sysstate.h>
|
||||
|
||||
#include <rtems/score/apiext.h>
|
||||
@@ -62,7 +63,7 @@
|
||||
|
||||
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
|
||||
@@ -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
|
||||
_DRV_Manager_initialization();
|
||||
@@ -163,7 +164,7 @@ void rtems_initialize_before_drivers(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void rtems_initialize_device_drivers(void)
|
||||
static void rtems_initialize_device_drivers(void)
|
||||
{
|
||||
/*
|
||||
* Initialize all the device drivers and initialize the MPCI layer.
|
||||
@@ -246,8 +247,37 @@ void rtems_initialize_device_drivers(void)
|
||||
_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 );
|
||||
|
||||
_SMP_Request_start_multitasking();
|
||||
|
||||
@@ -18,6 +18,7 @@ include_rtemsdir = $(includedir)/rtems
|
||||
|
||||
include_rtems_HEADERS =
|
||||
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/seterr.h
|
||||
|
||||
|
||||
75
cpukit/score/include/rtems/sysinit.h
Normal file
75
cpukit/score/include/rtems/sysinit.h
Normal 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 */
|
||||
@@ -47,6 +47,10 @@ $(PROJECT_INCLUDE)/rtems/linkersets.h: include/rtems/linkersets.h $(PROJECT_INCL
|
||||
$(INSTALL_DATA) $< $(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)
|
||||
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/system.h
|
||||
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/system.h
|
||||
|
||||
303
doc/user/init.t
303
doc/user/init.t
@@ -16,10 +16,7 @@ also initializes the interprocessor communications layer. The
|
||||
directives provided by the Initialization Manager are:
|
||||
|
||||
@itemize @bullet
|
||||
@item @code{@value{DIRPREFIX}initialize_data_structures} - Initialize RTEMS Data Structures
|
||||
@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}initialize_executive} - Initialize RTEMS
|
||||
@item @code{@value{DIRPREFIX}shutdown_executive} - Shutdown RTEMS
|
||||
@end itemize
|
||||
|
||||
@@ -58,12 +55,12 @@ System Initialization begins with board reset and continues
|
||||
through RTEMS initialization, initialization of all device
|
||||
drivers, and eventually a context switch to the first user
|
||||
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
|
||||
during initialzation.
|
||||
during initialization.
|
||||
|
||||
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
|
||||
all device drivers and, in multiprocessor configurations, the
|
||||
Multiprocessor Communications Interface Layer initialization
|
||||
@@ -125,71 +122,96 @@ may be found @ref{Fatal Error Manager Announcing a Fatal Error}.
|
||||
|
||||
@subsection Initializing RTEMS
|
||||
|
||||
The Initialization Manager directives are called by the
|
||||
Board Support Package framework as part of its initialization
|
||||
sequence. RTEMS assumes that the Board Support Package
|
||||
successfully completed its initialization activities. These
|
||||
directives initialize RTEMS by performing the following actions:
|
||||
The Initialization Manager @code{@value{DIRPREFIX}initialize_executive}
|
||||
directives is called by the @code{boot_card} routine. The @code{boot_card}
|
||||
routine is invoked by the Board Support Package once a basic C run-time
|
||||
environment is set up. This consists of
|
||||
|
||||
@itemize @bullet
|
||||
@item Initializing internal RTEMS variables;
|
||||
@item Allocating system resources;
|
||||
@item Creating and starting the Idle Task;
|
||||
@item Initialize all device drivers;
|
||||
@item Creating and starting the user initialization task(s); and
|
||||
@item Initiating multitasking.
|
||||
@item a valid and accessible text section, read-only data, read-write data and
|
||||
zero-initialized data,
|
||||
@item an initialization stack large enough to initialize the rest of the Board
|
||||
Support Package, RTEMS and the device drivers,
|
||||
@item all registers and components mandated by Application Binary Interface, and
|
||||
@item disabled interrupts.
|
||||
@end itemize
|
||||
|
||||
The initialization directives MUST be called in the proper
|
||||
sequence before any blocking directives may be used. The services
|
||||
in this manager should be invoked just once per application
|
||||
and in precisely the following order:
|
||||
The @code{@value{DIRPREFIX}initialize_executive} directive uses a system
|
||||
initialization linker set to initialize only those parts of the overall RTEMS
|
||||
feature set that is necessary for a particular application. @xref{Linker
|
||||
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
|
||||
@item @code{@value{DIRPREFIX}initialize_data_structures}
|
||||
@item @code{@value{DIRPREFIX}initialize_before_drivers}
|
||||
@item @code{@value{DIRPREFIX}initialize_device_drivers}
|
||||
@item @code{@value{DIRPREFIX}initialize_start_multitasking}
|
||||
@end itemize
|
||||
A list of all initialization steps follows. Some steps are optional depending
|
||||
on the requested feature set of the application. The initialization steps are
|
||||
execute in the order presented here.
|
||||
|
||||
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.
|
||||
@table @dfn
|
||||
|
||||
The effect of calling any blocking RTEMS directives before
|
||||
@code{@value{DIRPREFIX}initialize_start_multitasking}
|
||||
is unpredictable but guaranteed to be bad. After 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.
|
||||
@item RTEMS_SYSINIT_BSP_WORK_AREAS
|
||||
The work areas consisting of C Program Heap and the RTEMS Workspace are
|
||||
initialized by the Board Support Package. This step is mandatory.
|
||||
|
||||
@item RTEMS_SYSINIT_BSP_START
|
||||
Basic initialization step provided by the Board Support Package. This step is
|
||||
mandatory.
|
||||
|
||||
@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
|
||||
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 action in the initialization sequence is the
|
||||
initiation of multitasking. When the scheduler and dispatcher
|
||||
are enabled, the highest priority, ready task will be dispatched
|
||||
to run. Control will not be returned to the Board Support
|
||||
Package after multitasking is enabled until the
|
||||
@code{@value{DIRPREFIX}shutdown_executive} directive is called.
|
||||
This directive is called as a side-effect of POSIX calls
|
||||
including @code{exit}.
|
||||
Package after multitasking is enabled. The initialization stack may be re-used
|
||||
for interrupt processing.
|
||||
|
||||
@subsection Shutting Down RTEMS
|
||||
|
||||
The @code{@value{DIRPREFIX}shutdown_executive} directive is invoked by the
|
||||
application to end multitasking and return control to the board
|
||||
support package. The board support package resumes execution at
|
||||
the code immediately following the invocation of the
|
||||
@code{@value{DIRPREFIX}initialize_start_multitasking} directive.
|
||||
application to end multitasking and terminate the system.
|
||||
|
||||
@section Directives
|
||||
|
||||
@@ -199,144 +221,7 @@ directives and describes the calling sequence, related
|
||||
constants, usage, and status codes.
|
||||
|
||||
@page
|
||||
@subsection INITIALIZE_DATA_STRUCTURES - Initialize RTEMS Data Structures
|
||||
|
||||
@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
|
||||
@subsection INITIALIZE_EXECUTIVE - Initialize RTEMS
|
||||
|
||||
@cindex initialize RTEMS
|
||||
@cindex start multitasking
|
||||
@@ -344,9 +229,9 @@ the first context switch.
|
||||
@subheading CALLING SEQUENCE:
|
||||
|
||||
@ifset is-C
|
||||
@findex rtems_initialize_start_multitasking
|
||||
@findex rtems_initialize_executive
|
||||
@example
|
||||
void rtems_initialize_start_multitasking(void);
|
||||
void rtems_initialize_executive(void);
|
||||
@end example
|
||||
@end ifset
|
||||
|
||||
@@ -362,24 +247,15 @@ NONE
|
||||
|
||||
@subheading DESCRIPTION:
|
||||
|
||||
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().
|
||||
Iterates through the system initialization linker set and invokes the
|
||||
registered handlers. The final step is to start multitasking.
|
||||
|
||||
@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
|
||||
verify that certain configuration parameters are the same as
|
||||
those of the local node. If an inconsistency is detected, then
|
||||
a fatal error is generated.
|
||||
This directive @b{does not return} to the caller. Errors in the initialization
|
||||
sequence are usually fatal and lead to a system termination.
|
||||
|
||||
@page
|
||||
@subsection SHUTDOWN_EXECUTIVE - Shutdown RTEMS
|
||||
@@ -411,16 +287,13 @@ NONE
|
||||
|
||||
@subheading DESCRIPTION:
|
||||
|
||||
This directive is called when the application wishes
|
||||
to shutdown RTEMS and return control to the board support
|
||||
package. The board support package resumes execution at the
|
||||
code immediately following the invocation of the
|
||||
@code{@value{DIRPREFIX}initialize_executive} directive.
|
||||
This directive is called when the application wishes to shutdown RTEMS. The
|
||||
system is terminated with a fatal source of @code{RTEMS_FATAL_SOURCE_EXIT} and
|
||||
the specified @code{result} code.
|
||||
|
||||
@subheading NOTES:
|
||||
|
||||
This directive MUST be the last RTEMS directive
|
||||
invoked by an application and it DOES NOT RETURN to the caller.
|
||||
This directive @b{must} be the last RTEMS directive
|
||||
invoked by an application and it @b{does not return} to the caller.
|
||||
|
||||
This directive should not be invoked until the
|
||||
executive has successfully completed initialization.
|
||||
This directive may be called any time.
|
||||
|
||||
@@ -33,6 +33,7 @@ _SUBDIRS = \
|
||||
spsignal_err01 spport_err01 spmsgq_err01 spmsgq_err02 spsem_err01 \
|
||||
spsem_err02 sptask_err01 spevent_err03 sptask_err03 sptask_err02 \
|
||||
sptask_err04 spclock_err01
|
||||
_SUBDIRS += spsysinit01
|
||||
if HAS_SMP
|
||||
else
|
||||
_SUBDIRS += sp29
|
||||
|
||||
@@ -46,6 +46,7 @@ AM_CONDITIONAL(HAS_SMP,test "$rtems_cv_RTEMS_SMP" = "yes")
|
||||
|
||||
# Explicitly list all Makefiles here
|
||||
AC_CONFIG_FILES([Makefile
|
||||
spsysinit01/Makefile
|
||||
splinkersets01/Makefile
|
||||
spstdthreads01/Makefile
|
||||
spsyslock01/Makefile
|
||||
|
||||
19
testsuites/sptests/spsysinit01/Makefile.am
Normal file
19
testsuites/sptests/spsysinit01/Makefile.am
Normal 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
|
||||
176
testsuites/sptests/spsysinit01/init.c
Normal file
176
testsuites/sptests/spsysinit01/init.c
Normal 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>
|
||||
13
testsuites/sptests/spsysinit01/spsysinit01.doc
Normal file
13
testsuites/sptests/spsysinit01/spsysinit01.doc
Normal 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.
|
||||
2
testsuites/sptests/spsysinit01/spsysinit01.scn
Normal file
2
testsuites/sptests/spsysinit01/spsysinit01.scn
Normal file
@@ -0,0 +1,2 @@
|
||||
*** BEGIN OF TEST SPSYSINIT 1 ***
|
||||
*** END OF TEST SPSYSINIT 1 ***
|
||||
Reference in New Issue
Block a user