Update #3269. --- .../testsuites/validation/libvalidation.yml | 1 + testsuites/validation/tx-call-within-isr.c | 134 ++++++++++++++++++ testsuites/validation/tx-support.h | 14 ++ 3 files changed, 149 insertions(+) create mode 100644 testsuites/validation/tx-call-within-isr.c
diff --git a/spec/build/testsuites/validation/libvalidation.yml b/spec/build/testsuites/validation/libvalidation.yml index d55d4b9e41..54c7ae0ac0 100644 --- a/spec/build/testsuites/validation/libvalidation.yml +++ b/spec/build/testsuites/validation/libvalidation.yml @@ -11,6 +11,7 @@ install: [] install-path: null links: [] source: +- testsuites/validation/tx-call-within-isr.c - testsuites/validation/tx-support.c target: validation type: build diff --git a/testsuites/validation/tx-call-within-isr.c b/testsuites/validation/tx-call-within-isr.c new file mode 100644 index 0000000000..226647c0bc --- /dev/null +++ b/testsuites/validation/tx-call-within-isr.c @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestSuites + * + * @brief This source file contains the implementation of CallWithinISR(), + * CallWithinISRSubmit(), and CallWithinISRWait(). + */ + +/* + * Copyright (C) 2021 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 "tx-support.h" + +#include <rtems/sysinit.h> +#include <rtems/score/chainimpl.h> + +#include <bsp.h> + +/* Some target architectures need this variable for <tm27.h> */ +uint32_t Interrupt_nest; + +#define _RTEMS_TMTEST27 + +#include <tm27.h> + +typedef struct { + Chain_Control pending; + RTEMS_INTERRUPT_LOCK_MEMBER( lock ) +} CallWithinISRContext; + +static CallWithinISRContext CallWithinISRInstance = { +#if defined( RTEMS_SMP ) + .lock = RTEMS_INTERRUPT_LOCK_INITIALIZER( "CallWithinISR" ), +#endif + .pending = CHAIN_INITIALIZER_EMPTY( CallWithinISRInstance.pending ) +}; + +static void CallWithinISRHandler( rtems_vector_number vector ) +{ + CallWithinISRContext *ctx; + + (void) vector; + ctx = &CallWithinISRInstance; + + while ( true ) { + rtems_interrupt_lock_context lock_context; + CallWithinISRRequest *request; + + rtems_interrupt_lock_acquire( &ctx->lock, &lock_context ); + request = (CallWithinISRRequest *) + _Chain_Get_unprotected( &ctx->pending ); + rtems_interrupt_lock_release( &ctx->lock, &lock_context ); + + if ( request == NULL ) { + break; + } + + ( *request->handler )( request->arg ); + _Atomic_Store_uint( &request->done, 1, ATOMIC_ORDER_RELEASE ); + } +} + +void CallWithinISR( void ( *handler )( void * ), void *arg ) +{ + CallWithinISRRequest request; + + request.handler = handler; + request.arg = arg; + CallWithinISRSubmit( &request ); + CallWithinISRWait( &request ); +} + +void CallWithinISRSubmit( CallWithinISRRequest *request ) +{ + CallWithinISRContext *ctx; + rtems_interrupt_lock_context lock_context; + + ctx = &CallWithinISRInstance; + + rtems_interrupt_lock_acquire( &ctx->lock, &lock_context ); + _Atomic_Store_uint( &request->done, 0, ATOMIC_ORDER_RELAXED ); + _Chain_Initialize_node( &request->node ); + _Chain_Append_unprotected( &ctx->pending, &request->node ); + rtems_interrupt_lock_release( &ctx->lock, &lock_context ); + + Cause_tm27_intr(); +} + +void CallWithinISRWait( const CallWithinISRRequest *request ) +{ + while ( _Atomic_Load_uint( &request->done, ATOMIC_ORDER_ACQUIRE ) == 0 ) { + /* Wait */ + } +} + +static void CallWithinISRInitialize( void ) +{ + Install_tm27_vector( CallWithinISRHandler ); +} + +RTEMS_SYSINIT_ITEM( + CallWithinISRInitialize, + RTEMS_SYSINIT_DEVICE_DRIVERS, + RTEMS_SYSINIT_ORDER_MIDDLE +); diff --git a/testsuites/validation/tx-support.h b/testsuites/validation/tx-support.h index 932584b168..9d5a51e461 100644 --- a/testsuites/validation/tx-support.h +++ b/testsuites/validation/tx-support.h @@ -38,6 +38,7 @@ #define _TX_SUPPORT_H #include <rtems.h> +#include <rtems/score/atomic.h> #ifdef __cplusplus extern "C" { @@ -99,6 +100,19 @@ void RestoreRunnerMode( void ); void RestoreRunnerPriority( void ); +typedef struct { + Chain_Node node; + void ( *handler )( void * ); + void *arg; + Atomic_Uint done; +} CallWithinISRRequest; + +void CallWithinISR( void ( *handler )( void * ), void *arg ); + +void CallWithinISRSubmit( CallWithinISRRequest *request ); + +void CallWithinISRWait( const CallWithinISRRequest *request ); + /** @} */ #ifdef __cplusplus -- 2.26.2 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel