In order to better support applications which use the new rtems_task_construct() directive add the CONFIGURE_INIT_TASK_STORAGE_SIZE configuration option. If this option is specified, then the Classic API initialization task is constructed with rtems_task_construct().
Update #4181. --- cpukit/Makefile.am | 1 + cpukit/doxygen/appl-config.h | 48 +++++++++++++++ cpukit/include/rtems/confdefs/inittask.h | 53 ++++++++++++++--- cpukit/include/rtems/rtems/tasksdata.h | 45 +++++++++++++- cpukit/include/rtems/score/interr.h | 3 +- cpukit/rtems/src/taskconstructuser.c | 65 +++++++++++++++++++++ cpukit/sapi/src/interrtext.c | 3 +- spec/build/cpukit/librtemscpu.yml | 1 + spec/build/testsuites/sptests/grp.yml | 2 + spec/build/testsuites/sptests/spfatal34.yml | 19 ++++++ testsuites/sptests/spfatal34/init.c | 50 ++++++++++++++++ testsuites/sptests/spfatal34/spfatal34.doc | 11 ++++ testsuites/sptests/spfatal34/spfatal34.scn | 8 +++ testsuites/sptests/spinternalerror02/init.c | 2 +- 14 files changed, 296 insertions(+), 15 deletions(-) create mode 100644 cpukit/rtems/src/taskconstructuser.c create mode 100644 spec/build/testsuites/sptests/spfatal34.yml create mode 100644 testsuites/sptests/spfatal34/init.c create mode 100644 testsuites/sptests/spfatal34/spfatal34.doc create mode 100644 testsuites/sptests/spfatal34/spfatal34.scn diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am index 8c7f9c1ed4..b7435d7eb6 100644 --- a/cpukit/Makefile.am +++ b/cpukit/Makefile.am @@ -790,6 +790,7 @@ librtemscpu_a_SOURCES += rtems/src/statustoerrno.c librtemscpu_a_SOURCES += rtems/src/systemeventreceive.c librtemscpu_a_SOURCES += rtems/src/systemeventsend.c librtemscpu_a_SOURCES += rtems/src/taskconstruct.c +librtemscpu_a_SOURCES += rtems/src/taskconstructuser.c librtemscpu_a_SOURCES += rtems/src/taskcreate.c librtemscpu_a_SOURCES += rtems/src/taskdelete.c librtemscpu_a_SOURCES += rtems/src/taskexit.c diff --git a/cpukit/doxygen/appl-config.h b/cpukit/doxygen/appl-config.h index 00230ac2d6..f469f8b41c 100644 --- a/cpukit/doxygen/appl-config.h +++ b/cpukit/doxygen/appl-config.h @@ -1145,9 +1145,57 @@ * out by ``<rtems/confdefs.h>`` does not overflow an integer of type <a * href="https://en.cppreference.com/w/c/types/integer">uintptr_t</a>. * @endparblock + * + * @par Notes + * @parblock + * The + * + * * ``CONFIGURE_INIT_TASK_STACK_SIZE`` and + * + * * #CONFIGURE_INIT_TASK_STORAGE_SIZE + * + * configuration options are mutually exclusive. + * @endparblock */ #define CONFIGURE_INIT_TASK_STACK_SIZE +/* Generated from spec:/acfg/if/init-task-storage-size */ + +/** + * @brief This configuration option is an integer define. + * + * The value of this configuration option defines the task storage size of the + * Classic API initialization task. If this configuration option is specified, + * then the Classic API initialization task is constructed by + * rtems_task_construct() instead of using rtems_task_create(). + * + * @par Default Value + * The default value is 0. + * + * @par Value Constraints + * @parblock + * The value of this configuration option shall satisfy all of the following + * constraints: + * + * * It shall be greater than or equal to #CONFIGURE_MINIMUM_TASK_STACK_SIZE. + * + * * It shall be defined using RTEMS_TASK_STORAGE_SIZE(). + * @endparblock + * + * @par Notes + * @parblock + * A task storage area of the specified size is defined by the configuration + * for the Classic API initialization task. The + * + * * #CONFIGURE_INIT_TASK_STACK_SIZE and + * + * * ``CONFIGURE_INIT_TASK_STORAGE_SIZE`` + * + * configuration options are mutually exclusive. + * @endparblock + */ +#define CONFIGURE_INIT_TASK_STORAGE_SIZE + /* Generated from spec:/acfg/if/rtems-init-tasks-table */ /** diff --git a/cpukit/include/rtems/confdefs/inittask.h b/cpukit/include/rtems/confdefs/inittask.h index 25453f031d..f1d937e561 100644 --- a/cpukit/include/rtems/confdefs/inittask.h +++ b/cpukit/include/rtems/confdefs/inittask.h @@ -48,6 +48,7 @@ #ifdef CONFIGURE_RTEMS_INIT_TASKS_TABLE #include <rtems/confdefs/percpu.h> +#include <rtems/confdefs/threads.h> #include <rtems/rtems/object.h> #include <rtems/rtems/tasksdata.h> #include <rtems/sysinit.h> @@ -72,15 +73,6 @@ #define CONFIGURE_INIT_TASK_PRIORITY 1 #endif -#ifndef CONFIGURE_INIT_TASK_STACK_SIZE - #define CONFIGURE_INIT_TASK_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE -#endif - -#if CONFIGURE_INIT_TASK_STACK_SIZE > CONFIGURE_MINIMUM_TASK_STACK_SIZE - #define _CONFIGURE_INIT_TASK_STACK_EXTRA \ - ( CONFIGURE_INIT_TASK_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE ) -#endif - #ifdef __cplusplus extern "C" { #endif @@ -113,6 +105,47 @@ RTEMS_STATIC_ASSERT( #pragma GCC diagnostic pop +#ifdef CONFIGURE_INIT_TASK_STORAGE_SIZE + +#ifdef CONFIGURE_INIT_TASK_STACK_SIZE + #error "CONFIGURE_INIT_TASK_STACK_SIZE and CONFIGURE_INIT_TASK_STORAGE_SIZE are mutually exclusive" +#endif + +RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) +static char _RTEMS_tasks_User_task_storage[ CONFIGURE_INIT_TASK_STORAGE_SIZE ]; + +const RTEMS_tasks_User_task_config _RTEMS_tasks_User_task_config = { + { + CONFIGURE_INIT_TASK_NAME, + CONFIGURE_INIT_TASK_PRIORITY, + _RTEMS_tasks_User_task_storage, + sizeof( _RTEMS_tasks_User_task_storage ), + CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE, + NULL, + CONFIGURE_INIT_TASK_INITIAL_MODES, + CONFIGURE_INIT_TASK_ATTRIBUTES, + }, + CONFIGURE_INIT_TASK_ENTRY_POINT, + CONFIGURE_INIT_TASK_ARGUMENTS +}; + +RTEMS_SYSINIT_ITEM( + _RTEMS_tasks_Construct_user_task, + RTEMS_SYSINIT_CLASSIC_USER_TASKS, + RTEMS_SYSINIT_ORDER_MIDDLE +); + +#else /* CONFIGURE_INIT_TASK_STORAGE_SIZE */ + +#ifndef CONFIGURE_INIT_TASK_STACK_SIZE + #define CONFIGURE_INIT_TASK_STACK_SIZE CONFIGURE_MINIMUM_TASK_STACK_SIZE +#endif + +#if CONFIGURE_INIT_TASK_STACK_SIZE > CONFIGURE_MINIMUM_TASK_STACK_SIZE + #define _CONFIGURE_INIT_TASK_STACK_EXTRA \ + ( CONFIGURE_INIT_TASK_STACK_SIZE - CONFIGURE_MINIMUM_TASK_STACK_SIZE ) +#endif + const rtems_initialization_tasks_table _RTEMS_tasks_User_task_table = { CONFIGURE_INIT_TASK_NAME, CONFIGURE_INIT_TASK_STACK_SIZE, @@ -129,6 +162,8 @@ RTEMS_SYSINIT_ITEM( RTEMS_SYSINIT_ORDER_MIDDLE ); +#endif /* CONFIGURE_INIT_TASK_STORAGE_SIZE */ + #ifdef __cplusplus } #endif diff --git a/cpukit/include/rtems/rtems/tasksdata.h b/cpukit/include/rtems/rtems/tasksdata.h index 55090f71b0..8005b522ad 100644 --- a/cpukit/include/rtems/rtems/tasksdata.h +++ b/cpukit/include/rtems/rtems/tasksdata.h @@ -61,10 +61,49 @@ typedef struct { extern const rtems_initialization_tasks_table _RTEMS_tasks_User_task_table; /** - * @brief System initialization handler to create and start the first user - * task. + * @brief Creates and starts the Classic API initialization task using + * rtems_task_create() and the configuration provided by + * ::_RTEMS_tasks_User_task_table. */ -extern void _RTEMS_tasks_Initialize_user_task( void ); +void _RTEMS_tasks_Initialize_user_task( void ); + +/** + * @brief This structure provides the configuration to construct and start the + * Classic API initialization task. + */ +typedef struct { + /** + * @brief This member provides the task configuration for + * rtems_task_construct(). + */ + rtems_task_config config; + + /** + * @brief This member provides the task entry point for rtems_task_start(). + */ + rtems_task_entry entry_point; + + /** + * @brief This member provides the task argument for rtems_task_start(). + */ + rtems_task_argument argument; +} RTEMS_tasks_User_task_config; + +/** + * @brief This structure provides the configuration of the Classic API + * initialization task. + * + * It is used by _RTEMS_tasks_Construct_user_task() and initialized via + * <rtems/confdefs.h>, see also #CONFIGURE_INIT_TASK_STORAGE_SIZE. + */ +extern const RTEMS_tasks_User_task_config _RTEMS_tasks_User_task_config; + +/** + * @brief Constructs and starts the Classic API initialization task using + * rtems_task_construct() and the configuration provided by + * ::_RTEMS_tasks_User_task_config. + */ +void _RTEMS_tasks_Construct_user_task( void ); /** * The following instantiates the information control block used to diff --git a/cpukit/include/rtems/score/interr.h b/cpukit/include/rtems/score/interr.h index b1f1061c82..01ece772b8 100644 --- a/cpukit/include/rtems/score/interr.h +++ b/cpukit/include/rtems/score/interr.h @@ -204,7 +204,8 @@ typedef enum { INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT = 38, INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL = 39, INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA = 40, - INTERNAL_ERROR_TOO_LARGE_TLS_SIZE = 41 + INTERNAL_ERROR_TOO_LARGE_TLS_SIZE = 41, + INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED = 42, } Internal_errors_Core_list; typedef CPU_Uint32ptr Internal_errors_t; diff --git a/cpukit/rtems/src/taskconstructuser.c b/cpukit/rtems/src/taskconstructuser.c new file mode 100644 index 0000000000..bc59aabdd2 --- /dev/null +++ b/cpukit/rtems/src/taskconstructuser.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup ClassicTasks + * + * @brief This source file contains the implementation of + * _RTEMS_tasks_Construct_user_task(). + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/rtems/tasksimpl.h> +#include <rtems/score/assert.h> +#include <rtems/score/threadimpl.h> +#include <rtems/score/interr.h> + +void _RTEMS_tasks_Construct_user_task( void ) +{ + const RTEMS_tasks_User_task_config *config; + rtems_status_code status; + rtems_id id; + + config = &_RTEMS_tasks_User_task_config; + status = rtems_task_construct( &config->config, &id ); + + if ( status != RTEMS_SUCCESSFUL ) { + _Internal_error( INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED ); + } + + status = rtems_task_start( id, config->entry_point, config->argument ); + _Assert( status == RTEMS_SUCCESSFUL ); + (void) status; + + _Assert( _Thread_Global_constructor == 0 ); + _Thread_Global_constructor = id; +} diff --git a/cpukit/sapi/src/interrtext.c b/cpukit/sapi/src/interrtext.c index 3d49135c44..654b3110ad 100644 --- a/cpukit/sapi/src/interrtext.c +++ b/cpukit/sapi/src/interrtext.c @@ -68,7 +68,8 @@ static const char *const internal_error_text[] = { "INTERNAL_ERROR_ILLEGAL_USE_OF_FLOATING_POINT_UNIT", "INTERNAL_ERROR_ARC4RANDOM_GETENTROPY_FAIL", "INTERNAL_ERROR_NO_MEMORY_FOR_PER_CPU_DATA", - "INTERNAL_ERROR_TOO_LARGE_TLS_SIZE" + "INTERNAL_ERROR_TOO_LARGE_TLS_SIZE", + "INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED" }; const char *rtems_internal_error_text( rtems_fatal_code error ) diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml index 8f96af1e75..797aff6322 100644 --- a/spec/build/cpukit/librtemscpu.yml +++ b/spec/build/cpukit/librtemscpu.yml @@ -1284,6 +1284,7 @@ source: - cpukit/rtems/src/systemeventreceive.c - cpukit/rtems/src/systemeventsend.c - cpukit/rtems/src/taskconstruct.c +- cpukit/rtems/src/taskconstructuser.c - cpukit/rtems/src/taskcreate.c - cpukit/rtems/src/taskdelete.c - cpukit/rtems/src/taskexit.c diff --git a/spec/build/testsuites/sptests/grp.yml b/spec/build/testsuites/sptests/grp.yml index b1bf85942d..3ceddfad44 100644 --- a/spec/build/testsuites/sptests/grp.yml +++ b/spec/build/testsuites/sptests/grp.yml @@ -254,6 +254,8 @@ links: uid: spfatal32 - role: build-dependency uid: spfatal33 +- role: build-dependency + uid: spfatal34 - role: build-dependency uid: spfifo01 - role: build-dependency diff --git a/spec/build/testsuites/sptests/spfatal34.yml b/spec/build/testsuites/sptests/spfatal34.yml new file mode 100644 index 0000000000..b3bea84cda --- /dev/null +++ b/spec/build/testsuites/sptests/spfatal34.yml @@ -0,0 +1,19 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: test-program +cflags: [] +copyrights: +- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/sptests/spfatal34/init.c +stlib: [] +target: testsuites/sptests/spfatal34.exe +type: build +use-after: [] +use-before: [] diff --git a/testsuites/sptests/spfatal34/init.c b/testsuites/sptests/spfatal34/init.c new file mode 100644 index 0000000000..7e436e58ed --- /dev/null +++ b/testsuites/sptests/spfatal34/init.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "../spfatal_support/spfatal.h" + +#define FATAL_ERROR_TEST_NAME "34" + +#define FATAL_ERROR_DESCRIPTION "Classic API Init task construct failure" + +#define FATAL_ERROR_EXPECTED_SOURCE INTERNAL_ERROR_CORE + +#define FATAL_ERROR_EXPECTED_ERROR \ + INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED + +#define CONFIGURE_INIT_TASK_STORAGE_SIZE 0 + +static void force_error( void ) +{ + RTEMS_UNREACHABLE(); +} + +#include "../spfatal_support/spfatalimpl.h" diff --git a/testsuites/sptests/spfatal34/spfatal34.doc b/testsuites/sptests/spfatal34/spfatal34.doc new file mode 100644 index 0000000000..d2640ab8f0 --- /dev/null +++ b/testsuites/sptests/spfatal34/spfatal34.doc @@ -0,0 +1,11 @@ +This file describes the directives and concepts tested by this test set. + +test set name: spfatal34 + +directives: + + - _RTEMS_tasks_Construct_user_task() + +concepts: + + - Provoke a Classic API initialization task construct failure. diff --git a/testsuites/sptests/spfatal34/spfatal34.scn b/testsuites/sptests/spfatal34/spfatal34.scn new file mode 100644 index 0000000000..0ad19816a0 --- /dev/null +++ b/testsuites/sptests/spfatal34/spfatal34.scn @@ -0,0 +1,8 @@ +*** BEGIN OF TEST SPFATAL 34 *** +*** TEST VERSION: 6.0.0.be2dc00ae7b5db5381da49a3ec42f2088fa66bc9 +*** TEST STATE: EXPECTED_PASS +*** TEST BUILD: +*** TEST TOOLS: 10.2.1 20200918 (RTEMS 6, RSB 3ce72f014292bbb4e6b3bab9ede9e0b4a71ef5a8, Newlib 749cbcc) +Fatal error (Classic API Init task construct failure) hit + +*** END OF TEST SPFATAL 34 *** diff --git a/testsuites/sptests/spinternalerror02/init.c b/testsuites/sptests/spinternalerror02/init.c index 1b7d0b4388..1564061956 100644 --- a/testsuites/sptests/spinternalerror02/init.c +++ b/testsuites/sptests/spinternalerror02/init.c @@ -36,7 +36,7 @@ static void test_internal_error_text(void) } while ( text != text_last ); rtems_test_assert( - error - 3 == INTERNAL_ERROR_TOO_LARGE_TLS_SIZE + error - 3 == INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED ); } -- 2.26.2 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel