From 0edf263139088e8ac0ff1f0d52513f6fc85677d2 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 26 Oct 2012 10:05:07 +0200 Subject: rtems: Add system events System events are similar to normal events. They offer a second set of events. These events are intended for internal RTEMS use and should not be used by applications (with the exception of the transient system event). --- cpukit/rtems/Makefile.am | 2 + cpukit/rtems/include/rtems/rtems/event.h | 203 +++++++++++++++++++++ cpukit/rtems/include/rtems/rtems/tasks.h | 2 + cpukit/rtems/src/event.c | 1 + cpukit/rtems/src/systemeventreceive.c | 68 +++++++ cpukit/rtems/src/systemeventsend.c | 65 +++++++ cpukit/rtems/src/tasks.c | 2 + cpukit/score/include/rtems/score/states.h | 3 + cpukit/score/inline/rtems/score/states.inl | 15 ++ testsuites/sptests/Makefile.am | 2 + testsuites/sptests/configure.ac | 2 + testsuites/sptests/speventsystem01/Makefile.am | 19 ++ testsuites/sptests/speventsystem01/init.c | 101 ++++++++++ .../sptests/speventsystem01/speventsystem01.doc | 14 ++ .../sptests/speventsystem01/speventsystem01.scn | 2 + testsuites/sptests/speventtransient01/Makefile.am | 19 ++ testsuites/sptests/speventtransient01/init.c | 128 +++++++++++++ .../speventtransient01/speventtransient01.doc | 13 ++ .../speventtransient01/speventtransient01.scn | 2 + 19 files changed, 663 insertions(+) create mode 100644 cpukit/rtems/src/systemeventreceive.c create mode 100644 cpukit/rtems/src/systemeventsend.c create mode 100644 testsuites/sptests/speventsystem01/Makefile.am create mode 100644 testsuites/sptests/speventsystem01/init.c create mode 100644 testsuites/sptests/speventsystem01/speventsystem01.doc create mode 100644 testsuites/sptests/speventsystem01/speventsystem01.scn create mode 100644 testsuites/sptests/speventtransient01/Makefile.am create mode 100644 testsuites/sptests/speventtransient01/init.c create mode 100644 testsuites/sptests/speventtransient01/speventtransient01.doc create mode 100644 testsuites/sptests/speventtransient01/speventtransient01.scn diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am index bbf861177e..ff3174ebbc 100644 --- a/cpukit/rtems/Makefile.am +++ b/cpukit/rtems/Makefile.am @@ -209,6 +209,8 @@ librtems_a_SOURCES += src/eventsend.c librtems_a_SOURCES += src/eventsurrender.c librtems_a_SOURCES += src/eventtimeout.c librtems_a_SOURCES += src/eventdata.c +librtems_a_SOURCES += src/systemeventsend.c +librtems_a_SOURCES += src/systemeventreceive.c ## SIGNAL_C_FILES librtems_a_SOURCES += src/signal.c diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h index 381b328de2..b8d9987848 100644 --- a/cpukit/rtems/include/rtems/rtems/event.h +++ b/cpukit/rtems/include/rtems/rtems/event.h @@ -206,6 +206,207 @@ rtems_status_code rtems_event_receive ( /** @} */ +/** + * @defgroup ClassicEventSystem System Events + * + * @ingroup ClassicEvent + * + * System events are similar to normal events. They offer a second set of + * events. These events are intended for internal RTEMS use and should not be + * used by applications (with the exception of the transient system event). + * + * The event @ref RTEMS_EVENT_SYSTEM_TRANSIENT is used for transient usage. + * See also @ref ClassicEventTransient. This event may be used by every entity + * that fulfils its usage pattern. + * + * @{ + */ + +/** + * @brief Reserved system event for transient usage. + */ +#define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_0 + +/** + * @brief See rtems_event_send(). + */ +rtems_status_code rtems_event_system_send( + rtems_id id, + rtems_event_set event_in +); + +/** + * @brief See rtems_event_receive(). + */ +rtems_status_code rtems_event_system_receive( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +); + +/** @} */ + +/** + * @defgroup ClassicEventTransient Transient Event + * + * @ingroup ClassicEvent + * + * The transient event can be used by a client task to issue a request to + * another task or interrupt service (server). The server can send the + * transient event to the client task to notify about a request completion, see + * rtems_event_transient_send(). The client task can wait for the transient + * event reception with rtems_event_transient_receive(). + * + * The user of the transient event must ensure that this event is not pending + * once the request is finished or cancelled. A successful reception of the + * transient event with rtems_event_transient_receive() will clear the + * transient event. If a reception with timeout is used the transient event + * state is undefined after a timeout return status. The transient event can + * be cleared unconditionally with the non-blocking + * rtems_event_transient_clear(). + * + * @msc + * hscale="1.6"; + * M [label="Main Task"], IDLE [label="Idle Task"], S [label="Server"], TIME [label="System Tick Handler"]; + * |||; + * --- [label="sequence with request completion"]; + * M box M [label="prepare request\nissue request\ncall rtems_event_transient_receive()"]; + * M=>>IDLE [label="blocking operation"]; + * IDLE=>>S [label="request completion"]; + * S box S [label="call rtems_event_transient_send()"]; + * S=>>M [label="task is ready again"]; + * M box M [label="finish request"]; + * |||; + * --- [label="sequence with early request completion"]; + * M box M [label="prepare request\nissue request"]; + * M=>>S [label="request completion"]; + * S box S [label="call rtems_event_transient_send()"]; + * S=>>M [label="transient event is now pending"]; + * M box M [label="call rtems_event_transient_receive()\nfinish request"]; + * |||; + * --- [label="sequence with timeout event"]; + * M box M [label="prepare request\nissue request\ncall rtems_event_transient_receive()"]; + * M=>>IDLE [label="blocking operation"]; + * IDLE=>>TIME [label="timeout expired"]; + * TIME box TIME [label="cancel blocking operation"]; + * TIME=>>M [label="task is ready again"]; + * M box M [label="cancel request\ncall rtems_event_transient_clear()"]; + * @endmsc + * + * Suppose you have a task that wants to issue a certain request and then waits + * for request completion. It can create a request structure and store its + * task identifier there. Now it can place the request on a work queue of + * another task (or interrupt handler). Afterwards the task waits for the + * reception of the transient event. Once the server task is finished with the + * request it can send the transient event to the waiting task and wake it up. + * + * @code + * #include + * #include + * + * typedef struct { + * rtems_id task_id; + * bool work_done; + * } request; + * + * void server(rtems_task_argument arg) + * { + * rtems_status_code sc; + * request *req = (request *) arg; + * + * req->work_done = true; + * + * sc = rtems_event_transient_send(req->task_id); + * assert(sc == RTEMS_SUCCESSFUL); + * + * sc = rtems_task_delete(RTEMS_SELF); + * assert(sc == RTEMS_SUCCESSFUL); + * } + * + * void issue_request_and_wait_for_completion(void) + * { + * rtems_status_code sc; + * rtems_id id; + * request req; + * + * req.task_id = rtems_task_self(); + * req.work_done = false; + * + * sc = rtems_task_create( + * rtems_build_name('S', 'E', 'R', 'V'), + * 1, + * RTEMS_MINIMUM_STACK_SIZE, + * RTEMS_DEFAULT_MODES, + * RTEMS_DEFAULT_ATTRIBUTES, + * &id + * ); + * assert(sc == RTEMS_SUCCESSFUL); + * + * sc = rtems_task_start(id, server, (rtems_task_argument) &req); + * assert(sc == RTEMS_SUCCESSFUL); + * + * sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); + * assert(sc == RTEMS_SUCCESSFUL); + * + * assert(req.work_done); + * } + * @endcode + * + * @{ + */ + +/** + * @brief See rtems_event_system_send(). + * + * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be sent. + */ +RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_send( + rtems_id id +) +{ + return rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TRANSIENT ); +} + +/** + * @brief See rtems_event_system_receive(). + * + * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be received. + */ +RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_receive( + rtems_option option_set, + rtems_interval ticks +) +{ + rtems_event_set event_out; + + return rtems_event_system_receive( + RTEMS_EVENT_SYSTEM_TRANSIENT, + RTEMS_EVENT_ALL | option_set, + ticks, + &event_out + ); +} + +/** + * @brief See rtems_event_system_receive(). + * + * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be cleared. + */ +RTEMS_INLINE_ROUTINE void rtems_event_transient_clear( void ) +{ + rtems_event_set event_out; + + rtems_event_system_receive( + RTEMS_EVENT_SYSTEM_TRANSIENT, + RTEMS_EVENT_ALL | RTEMS_NO_WAIT, + 0, + &event_out + ); +} + +/** @} */ + /** * @defgroup ScoreEvent Event Handler * @@ -252,6 +453,8 @@ void _Event_Timeout( RTEMS_EVENT_EXTERN Thread_blocking_operation_States _Event_Sync_state; +RTEMS_EVENT_EXTERN Thread_blocking_operation_States _System_event_Sync_state; + /** @} */ #if defined(RTEMS_MULTIPROCESSING) diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h index d11e0bc522..f141c102e6 100644 --- a/cpukit/rtems/include/rtems/rtems/tasks.h +++ b/cpukit/rtems/include/rtems/rtems/tasks.h @@ -212,6 +212,8 @@ typedef struct { typedef struct { /** This field contains the event control for this task. */ Event_Control Event; + /** This field contains the system event control for this task. */ + Event_Control System_event; /** This field contains the Classic API Signal information for this task. */ ASR_Information Signal; /** diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c index ed148e8b37..d5c29f6a3e 100644 --- a/cpukit/rtems/src/event.c +++ b/cpukit/rtems/src/event.c @@ -34,6 +34,7 @@ void _Event_Manager_initialization( void ) { _Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; + _System_event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; /* * Register the MP Process Packet routine. diff --git a/cpukit/rtems/src/systemeventreceive.c b/cpukit/rtems/src/systemeventreceive.c new file mode 100644 index 0000000000..43f2bec048 --- /dev/null +++ b/cpukit/rtems/src/systemeventreceive.c @@ -0,0 +1,68 @@ +/** + * @file + * + * @ingroup ClassicEventSystem + * + * @brief rtems_event_system_receive() implementation. + */ + +/* + * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +rtems_status_code rtems_event_system_receive( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +) +{ + rtems_status_code sc; + + if ( event_out != NULL ) { + Thread_Control *executing = _Thread_Executing; + RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ]; + Event_Control *event = &api->System_event; + + if ( !_Event_sets_Is_empty( event_in ) ) { + _Thread_Disable_dispatch(); + _Event_Seize( + event_in, + option_set, + ticks, + event_out, + executing, + event, + &_System_event_Sync_state, + STATES_WAITING_FOR_SYSTEM_EVENT + ); + _Thread_Enable_dispatch(); + + sc = executing->Wait.return_code; + } else { + *event_out = event->pending_events; + sc = RTEMS_SUCCESSFUL; + } + } else { + sc = RTEMS_INVALID_ADDRESS; + } + + return sc; +} diff --git a/cpukit/rtems/src/systemeventsend.c b/cpukit/rtems/src/systemeventsend.c new file mode 100644 index 0000000000..13d31ccf85 --- /dev/null +++ b/cpukit/rtems/src/systemeventsend.c @@ -0,0 +1,65 @@ +/** + * @file + * + * @ingroup ClassicEventSystem + * + * @brief rtems_event_system_send() implementation. + */ + +/* + * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * 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. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +rtems_status_code rtems_event_system_send( + rtems_id id, + rtems_event_set event_in +) +{ + rtems_status_code sc; + Thread_Control *thread; + Objects_Locations location; + RTEMS_API_Control *api; + + thread = _Thread_Get( id, &location ); + switch ( location ) { + case OBJECTS_LOCAL: + api = thread->API_Extensions[ THREAD_API_RTEMS ]; + _Event_Surrender( + thread, + event_in, + &api->System_event, + &_System_event_Sync_state, + STATES_WAITING_FOR_SYSTEM_EVENT + ); + _Thread_Enable_dispatch(); + sc = RTEMS_SUCCESSFUL; + break; +#ifdef RTEMS_MULTIPROCESSING + case OBJECTS_REMOTE: + sc = RTEMS_ILLEGAL_ON_REMOTE_OBJECT; + break; +#endif + default: + sc = RTEMS_INVALID_ID; + break; + } + + return sc; +} diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c index 325eba0546..c679f1e6f2 100644 --- a/cpukit/rtems/src/tasks.c +++ b/cpukit/rtems/src/tasks.c @@ -65,6 +65,7 @@ static bool _RTEMS_tasks_Create_extension( created->API_Extensions[ THREAD_API_RTEMS ] = api; _Event_Initialize( &api->Event ); + _Event_Initialize( &api->System_event ); _ASR_Initialize( &api->Signal ); created->task_variables = NULL; @@ -93,6 +94,7 @@ static void _RTEMS_tasks_Start_extension( api = started->API_Extensions[ THREAD_API_RTEMS ]; _Event_Initialize( &api->Event ); + _Event_Initialize( &api->System_event ); } /* diff --git a/cpukit/score/include/rtems/score/states.h b/cpukit/score/include/rtems/score/states.h index eb4658e3be..f71bf9399e 100644 --- a/cpukit/score/include/rtems/score/states.h +++ b/cpukit/score/include/rtems/score/states.h @@ -81,6 +81,8 @@ typedef uint32_t States_Control; #define STATES_WAITING_FOR_BARRIER 0x10000 /** This macro corresponds to a task waiting for a RWLock. */ #define STATES_WAITING_FOR_RWLOCK 0x20000 +/** This macro corresponds to a task waiting for a system event. */ +#define STATES_WAITING_FOR_SYSTEM_EVENT 0x40000 /** This macro corresponds to a task which is in an interruptible * blocking state. @@ -110,6 +112,7 @@ typedef uint32_t States_Control; STATES_WAITING_FOR_TIME | \ STATES_WAITING_FOR_PERIOD | \ STATES_WAITING_FOR_EVENT | \ + STATES_WAITING_FOR_SYSTEM_EVENT | \ STATES_WAITING_ON_THREAD_QUEUE | \ STATES_INTERRUPTIBLE_BY_SIGNAL ) diff --git a/cpukit/score/inline/rtems/score/states.inl b/cpukit/score/inline/rtems/score/states.inl index 7bad0c9f12..f5d816a8d3 100644 --- a/cpukit/score/inline/rtems/score/states.inl +++ b/cpukit/score/inline/rtems/score/states.inl @@ -212,6 +212,21 @@ RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_event ( return (the_states & STATES_WAITING_FOR_EVENT); } +/** + * This function returns true if the WAITING_FOR_SYSTEM_EVENT state is set in + * the_states, and false otherwise. + * + * @param[in] the_states is the task state set to test + * + * @return This method returns true if the desired state condition is set. + */ +RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_system_event ( + States_Control the_states +) +{ + return (the_states & STATES_WAITING_FOR_SYSTEM_EVENT); +} + /** * This function returns true if the WAITING_FOR_MUTEX state * is set in the_states, and false otherwise. diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am index a0dc24af36..dd79451dab 100644 --- a/testsuites/sptests/Makefile.am +++ b/testsuites/sptests/Makefile.am @@ -28,6 +28,8 @@ SUBDIRS = \ spsimplesched01 spsimplesched02 spsimplesched03 spnsext01 \ spedfsched01 spedfsched02 spedfsched03 \ spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01 +SUBDIRS += speventtransient01 +SUBDIRS += speventsystem01 include $(top_srcdir)/../automake/subdirs.am include $(top_srcdir)/../automake/local.am diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac index 32063e2221..5bee64c92d 100644 --- a/testsuites/sptests/configure.ac +++ b/testsuites/sptests/configure.ac @@ -27,6 +27,8 @@ AC_CHECK_SIZEOF([time_t]) # Explicitly list all Makefiles here AC_CONFIG_FILES([Makefile +speventsystem01/Makefile +speventtransient01/Makefile spintrcritical18/Makefile sp01/Makefile sp02/Makefile diff --git a/testsuites/sptests/speventsystem01/Makefile.am b/testsuites/sptests/speventsystem01/Makefile.am new file mode 100644 index 0000000000..f3a49ef8f9 --- /dev/null +++ b/testsuites/sptests/speventsystem01/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = speventsystem01 +speventsystem01_SOURCES = init.c + +dist_rtems_tests_DATA = speventsystem01.scn speventsystem01.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 = $(speventsystem01_OBJECTS) +LINK_LIBS = $(speventsystem01_LDLIBS) + +speventsystem01$(EXEEXT): $(speventsystem01_OBJECTS) $(speventsystem01_DEPENDENCIES) + @rm -f speventsystem01$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/sptests/speventsystem01/init.c b/testsuites/sptests/speventsystem01/init.c new file mode 100644 index 0000000000..4c919f70a8 --- /dev/null +++ b/testsuites/sptests/speventsystem01/init.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * 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 + +#include "tmacros.h" + +#define EVENT RTEMS_EVENT_0 + +static void test_with_normal_and_system_event(void) +{ + rtems_status_code sc; + rtems_event_set out; + + /* Assert no events pending */ + + sc = rtems_event_receive(EVENT, RTEMS_NO_WAIT, 0, &out); + rtems_test_assert(sc == RTEMS_UNSATISFIED); + + sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out); + rtems_test_assert(sc == RTEMS_UNSATISFIED); + + /* Send system event */ + + sc = rtems_event_system_send(rtems_task_self(), EVENT); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_event_receive(EVENT, RTEMS_NO_WAIT, 0, &out); + rtems_test_assert(sc == RTEMS_UNSATISFIED); + + out = 0; + sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(out == EVENT); + + /* Send normal event */ + + sc = rtems_event_send(rtems_task_self(), EVENT); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + out = 0; + sc = rtems_event_receive(EVENT, RTEMS_NO_WAIT, 0, &out); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + rtems_test_assert(out == EVENT); + + sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out); + rtems_test_assert(sc == RTEMS_UNSATISFIED); +} + +static void test_with_timeout(void) +{ + rtems_status_code sc; + rtems_event_set out; + + sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out); + rtems_test_assert(sc == RTEMS_UNSATISFIED); + + sc = rtems_event_system_receive(EVENT, RTEMS_WAIT, 1, &out); + rtems_test_assert(sc == RTEMS_TIMEOUT); + + sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out); + rtems_test_assert(sc == RTEMS_UNSATISFIED); +} + +static void Init(rtems_task_argument arg) +{ + puts("\n\n*** TEST SPEVENTSYSTEM 1 ***"); + + test_with_normal_and_system_event(); + test_with_timeout(); + + puts("*** END OF TEST SPEVENTSYSTEM 1 ***"); + + rtems_test_exit(0); +} + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 2 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT + +#include diff --git a/testsuites/sptests/speventsystem01/speventsystem01.doc b/testsuites/sptests/speventsystem01/speventsystem01.doc new file mode 100644 index 0000000000..1d27b1a871 --- /dev/null +++ b/testsuites/sptests/speventsystem01/speventsystem01.doc @@ -0,0 +1,14 @@ +This file describes the directives and concepts tested by this test set. + +test set name: speventsystem01 + +directives: + + - rtems_event_send() + - rtems_event_receive() + - rtems_event_system_send() + - rtems_event_system_receive() + +concepts: + + Ensure that the Classic System Events work. diff --git a/testsuites/sptests/speventsystem01/speventsystem01.scn b/testsuites/sptests/speventsystem01/speventsystem01.scn new file mode 100644 index 0000000000..90ddfe7203 --- /dev/null +++ b/testsuites/sptests/speventsystem01/speventsystem01.scn @@ -0,0 +1,2 @@ +*** TEST SPEVENTSYSTEM 1 *** +*** END OF TEST SPEVENTSYSTEM 1 *** diff --git a/testsuites/sptests/speventtransient01/Makefile.am b/testsuites/sptests/speventtransient01/Makefile.am new file mode 100644 index 0000000000..d8aa2b5250 --- /dev/null +++ b/testsuites/sptests/speventtransient01/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = speventtransient01 +speventtransient01_SOURCES = init.c + +dist_rtems_tests_DATA = speventtransient01.scn speventtransient01.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 = $(speventtransient01_OBJECTS) +LINK_LIBS = $(speventtransient01_LDLIBS) + +speventtransient01$(EXEEXT): $(speventtransient01_OBJECTS) $(speventtransient01_DEPENDENCIES) + @rm -f speventtransient01$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/sptests/speventtransient01/init.c b/testsuites/sptests/speventtransient01/init.c new file mode 100644 index 0000000000..b885ba6032 --- /dev/null +++ b/testsuites/sptests/speventtransient01/init.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * 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 + +#include "tmacros.h" + +typedef struct { + rtems_id client; + bool complete; +} request; + +static void server_task(rtems_task_argument arg) +{ + rtems_status_code sc; + request *req = (request *) arg; + + req->complete = true; + + sc = rtems_event_transient_send(req->client); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_delete(RTEMS_SELF); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + +static void test_with_request_server(void) +{ + rtems_status_code sc; + rtems_id id; + request req; + + sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0); + rtems_test_assert(sc == RTEMS_UNSATISFIED); + + req.client = rtems_task_self(); + req.complete = false; + + sc = rtems_task_create( + rtems_build_name('S', 'E', 'R', 'V'), + 1, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_start(id, server_task, (rtems_task_argument) &req); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(req.complete); +} + +static void test_with_request_self(void) +{ + rtems_status_code sc; + + sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0); + rtems_test_assert(sc == RTEMS_UNSATISFIED); + + sc = rtems_event_transient_send(rtems_task_self()); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_event_transient_clear(); + + sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0); + rtems_test_assert(sc == RTEMS_UNSATISFIED); +} + +static void test_with_timeout(void) +{ + rtems_status_code sc; + + sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0); + rtems_test_assert(sc == RTEMS_UNSATISFIED); + + sc = rtems_event_transient_receive(RTEMS_WAIT, 1); + rtems_test_assert(sc == RTEMS_TIMEOUT); + + sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0); + rtems_test_assert(sc == RTEMS_UNSATISFIED); +} + +static void Init(rtems_task_argument arg) +{ + puts("\n\n*** TEST SPEVENTTRANSIENT 1 ***"); + + test_with_request_server(); + test_with_request_self(); + test_with_timeout(); + + puts("*** END OF TEST SPEVENTTRANSIENT 1 ***"); + + rtems_test_exit(0); +} + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 2 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT + +#include diff --git a/testsuites/sptests/speventtransient01/speventtransient01.doc b/testsuites/sptests/speventtransient01/speventtransient01.doc new file mode 100644 index 0000000000..6b4190259c --- /dev/null +++ b/testsuites/sptests/speventtransient01/speventtransient01.doc @@ -0,0 +1,13 @@ +This file describes the directives and concepts tested by this test set. + +test set name: speventtransient01 + +directives: + + - rtems_event_transient_send() + - rtems_event_transient_receive() + - rtems_event_transient_clear() + +concepts: + + Ensure that the Classic Transient Event works. diff --git a/testsuites/sptests/speventtransient01/speventtransient01.scn b/testsuites/sptests/speventtransient01/speventtransient01.scn new file mode 100644 index 0000000000..03df8da9e1 --- /dev/null +++ b/testsuites/sptests/speventtransient01/speventtransient01.scn @@ -0,0 +1,2 @@ +*** TEST SPEVENTTRANSIENT 1 *** +*** END OF TEST SPEVENTTRANSIENT 1 *** -- cgit v1.2.3