diff options
Diffstat (limited to 'include/rtems/rtems/event.h')
-rw-r--r-- | include/rtems/rtems/event.h | 520 |
1 files changed, 520 insertions, 0 deletions
diff --git a/include/rtems/rtems/event.h b/include/rtems/rtems/event.h new file mode 100644 index 0000000000..4263a4b881 --- /dev/null +++ b/include/rtems/rtems/event.h @@ -0,0 +1,520 @@ +/** + * @file rtems/rtems/event.h + * + * @defgroup ClassicEvent Events + * + * @ingroup ClassicRTEMS + * @brief Information Related to Event Manager + * + * This include file contains the information pertaining to the Event + * Manager. This manager provides a high performance method of communication + * and synchronization. + * + * Directives provided are: + * + * - send an event set to a task + * - receive event condition + * + */ + +/* COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * 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_RTEMS_EVENT_H +#define _RTEMS_RTEMS_EVENT_H + +#include <rtems/rtems/status.h> +#include <rtems/rtems/types.h> +#include <rtems/rtems/options.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ClassicEventSet Event Set + * + * @ingroup ClassicEvent + * + * @{ + */ + +/** + * @brief Integer type to hold an event set of up to 32 events represented as + * a bit field. + */ +typedef uint32_t rtems_event_set; + +/** + * @brief Constant used to send or receive all events. + */ +#define RTEMS_ALL_EVENTS 0xFFFFFFFF + +/** @brief Defines the bit in the event set associated with event 0. */ +#define RTEMS_EVENT_0 0x00000001 +/** @brief Defines the bit in the event set associated with event 1. */ +#define RTEMS_EVENT_1 0x00000002 +/** @brief Defines the bit in the event set associated with event 2. */ +#define RTEMS_EVENT_2 0x00000004 +/** @brief Defines the bit in the event set associated with event 3. */ +#define RTEMS_EVENT_3 0x00000008 +/** @brief Defines the bit in the event set associated with event 4. */ +#define RTEMS_EVENT_4 0x00000010 +/** @brief Defines the bit in the event set associated with event 5. */ +#define RTEMS_EVENT_5 0x00000020 +/** @brief Defines the bit in the event set associated with event 6. */ +#define RTEMS_EVENT_6 0x00000040 +/** @brief Defines the bit in the event set associated with event 7. */ +#define RTEMS_EVENT_7 0x00000080 +/** @brief Defines the bit in the event set associated with event 8. */ +#define RTEMS_EVENT_8 0x00000100 +/** @brief Defines the bit in the event set associated with event 9. */ +#define RTEMS_EVENT_9 0x00000200 +/** @brief Defines the bit in the event set associated with event 10. */ +#define RTEMS_EVENT_10 0x00000400 +/** @brief Defines the bit in the event set associated with event 11. */ +#define RTEMS_EVENT_11 0x00000800 +/** @brief Defines the bit in the event set associated with event 12. */ +#define RTEMS_EVENT_12 0x00001000 +/** @brief Defines the bit in the event set associated with event 13. */ +#define RTEMS_EVENT_13 0x00002000 +/** @brief Defines the bit in the event set associated with event 14. */ +#define RTEMS_EVENT_14 0x00004000 +/** @brief Defines the bit in the event set associated with event 15. */ +#define RTEMS_EVENT_15 0x00008000 +/** @brief Defines the bit in the event set associated with event 16. */ +#define RTEMS_EVENT_16 0x00010000 +/** @brief Defines the bit in the event set associated with event 17. */ +#define RTEMS_EVENT_17 0x00020000 +/** @brief Defines the bit in the event set associated with event 18. */ +#define RTEMS_EVENT_18 0x00040000 +/** @brief Defines the bit in the event set associated with event 19. */ +#define RTEMS_EVENT_19 0x00080000 +/** @brief Defines the bit in the event set associated with event 20. */ +#define RTEMS_EVENT_20 0x00100000 +/** @brief Defines the bit in the event set associated with event 21. */ +#define RTEMS_EVENT_21 0x00200000 +/** @brief Defines the bit in the event set associated with event 22. */ +#define RTEMS_EVENT_22 0x00400000 +/** @brief Defines the bit in the event set associated with event 23. */ +#define RTEMS_EVENT_23 0x00800000 +/** @brief Defines the bit in the event set associated with event 24. */ +#define RTEMS_EVENT_24 0x01000000 +/** @brief Defines the bit in the event set associated with event 25. */ +#define RTEMS_EVENT_25 0x02000000 +/** @brief Defines the bit in the event set associated with event 26. */ +#define RTEMS_EVENT_26 0x04000000 +/** @brief Defines the bit in the event set associated with event 27. */ +#define RTEMS_EVENT_27 0x08000000 +/** @brief Defines the bit in the event set associated with event 29. */ +#define RTEMS_EVENT_28 0x10000000 +/** @brief Defines the bit in the event set associated with event 29. */ +#define RTEMS_EVENT_29 0x20000000 +/** @brief Defines the bit in the event set associated with event 30. */ +#define RTEMS_EVENT_30 0x40000000 +/** @brief Defines the bit in the event set associated with event 31. */ +#define RTEMS_EVENT_31 0x80000000 + +/** @} */ + +/** + * @defgroup ClassicEvent Events + * + * @ingroup ClassicRTEMS + * + * @brief The event manager provides a high performance method of intertask + * communication and synchronization. + * + * An event flag is used by a task (or ISR) to inform another task of the + * occurrence of a significant situation. Thirty-two event flags are + * associated with each task. A collection of one or more event flags is + * referred to as an event set. The data type rtems_event_set is used to + * manage event sets. + * + * The application developer should remember the following key characteristics + * of event operations when utilizing the event manager: + * + * - Events provide a simple synchronization facility. + * - Events are aimed at tasks. + * - Tasks can wait on more than one event simultaneously. + * - Events are independent of one another. + * - Events do not hold or transport data. + * - Events are not queued. In other words, if an event is sent more than once + * to a task before being received, the second and subsequent send + * operations to that same task have no effect. + * + * An event set is posted when it is directed (or sent) to a task. A pending + * event is an event that has been posted but not received. An event condition + * is used to specify the event set which the task desires to receive and the + * algorithm which will be used to determine when the request is satisfied. An + * event condition is satisfied based upon one of two algorithms which are + * selected by the user. The @ref RTEMS_EVENT_ANY algorithm states that an + * event condition is satisfied when at least a single requested event is + * posted. The @ref RTEMS_EVENT_ALL algorithm states that an event condition + * is satisfied when every requested event is posted. + * + * An event set or condition is built by a bitwise or of the desired events. + * The set of valid events is @ref RTEMS_EVENT_0 through @ref RTEMS_EVENT_31. + * If an event is not explicitly specified in the set or condition, then it is + * not present. Events are specifically designed to be mutually exclusive, + * therefore bitwise or and addition operations are equivalent as long as each + * event appears exactly once in the event set list. + * + * For example, when sending the event set consisting of @ref RTEMS_EVENT_6, + * @ref RTEMS_EVENT_15, and @ref RTEMS_EVENT_31, the event parameter to the + * rtems_event_send() directive should be @ref RTEMS_EVENT_6 | + * @ref RTEMS_EVENT_15 | @ref RTEMS_EVENT_31. + * + * @{ + */ + +/** + * @brief Constant used to receive the set of currently pending events in + * rtems_event_receive(). + */ +#define RTEMS_PENDING_EVENTS 0 + +/** + * @brief Sends an Event Set to the Target Task + * + * This directive sends an event set @a event_in to the task specified by + * @a id. + * + * Based upon the state of the target task, one of the following situations + * applies. The target task is + * - blocked waiting for events. + * If the waiting task's input event condition is + * - satisfied, then the task is made ready for execution. + * - not satisfied, then the event set is posted but left pending and the + * task remains blocked. + * - not waiting for events. + * - The event set is posted and left pending. + * + * Identical events sent to a task are not queued. In other words, the second, + * and subsequent, posting of an event to a task before it can perform an + * rtems_event_receive() has no effect. + * + * The calling task will be preempted if it has preemption enabled and a + * higher priority task is unblocked as the result of this directive. + * + * Sending an event set to a global task which does not reside on the local + * node will generate a request telling the remote node to send the event set + * to the appropriate task. + * + * @param[in] id Identifier of the target task. Specifying @ref RTEMS_SELF + * results in the event set being sent to the calling task. + * @param[in] event_in Event set sent to the target task. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID Invalid task identifier. + */ +rtems_status_code rtems_event_send ( + rtems_id id, + rtems_event_set event_in +); + +/** + * @brief Receives pending events. + * + * This directive attempts to receive the event condition specified in + * @a event_in. If @a event_in is set to @ref RTEMS_PENDING_EVENTS, then the + * current pending events are returned in @a event_out and left pending. The + * @ref RTEMS_WAIT and @ref RTEMS_NO_WAIT options in the @a option_set + * parameter are used to specify whether or not the task is willing to wait + * for the event condition to be satisfied. The @ref RTEMS_EVENT_ANY and @ref + * RTEMS_EVENT_ALL are used in the @a option_set parameter to specify whether + * at least a single event or the complete event set is necessary to satisfy + * the event condition. The @a event_out parameter is returned to the calling + * task with the value that corresponds to the events in @a event_in that were + * satisfied. + * + * A task can determine the pending event set by using a value of + * @ref RTEMS_PENDING_EVENTS for the input event set @a event_in. The pending + * events are returned to the calling task but the event set is left + * unaltered. + * + * A task can receive all of the currently pending events by using the a value + * of @ref RTEMS_ALL_EVENTS for the input event set @a event_in and + * @ref RTEMS_NO_WAIT | @ref RTEMS_EVENT_ANY for the option set @a option_set. + * The pending events are returned to the calling task and the event set is + * cleared. If no events are pending then the @ref RTEMS_UNSATISFIED status + * code will be returned. + * + * If pending events satisfy the event condition, then @a event_out is set to + * the satisfied events and the pending events in the event condition are + * cleared. If the event condition is not satisfied and @ref RTEMS_NO_WAIT is + * specified, then @a event_out is set to the currently satisfied events. If + * the calling task chooses to wait, then it will block waiting for the event + * condition. + * + * If the calling task must wait for the event condition to be satisfied, then + * the timeout parameter is used to specify the maximum interval to wait. If + * it is set to @ref RTEMS_NO_TIMEOUT, then the calling task will wait forever. + * + * This directive only affects the events specified in @a event_in. Any + * pending events that do not correspond to any of the events specified in + * @a event_in will be left pending. + * + * A clock tick is required to support the wait with time out functionality of + * this directive. + * + * @param[in] event_in Set of requested events (input events). + * @param[in] option_set Use a bitwise or of the following options + * - @ref RTEMS_WAIT - task will wait for event (default), + * - @ref RTEMS_NO_WAIT - task should not wait, + * - @ref RTEMS_EVENT_ALL - return after all events (default), and + * - @ref RTEMS_EVENT_ANY - return after any events. + * @param[in] ticks Time out in ticks. Use @ref RTEMS_NO_TIMEOUT to wait + * without a time out (potentially forever). + * @param[out] event_out Set of received events (output events). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_UNSATISFIED Input events not satisfied (only with the + * @ref RTEMS_NO_WAIT option). + * @retval RTEMS_INVALID_ADDRESS The @a event_out pointer is @c NULL. + * @retval RTEMS_TIMEOUT Timed out waiting for events. + */ +rtems_status_code rtems_event_receive ( + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +); + +/** @} */ + +/** + * @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 network SBWAIT usage. + */ +#define RTEMS_EVENT_SYSTEM_NETWORK_SBWAIT RTEMS_EVENT_24 + +/** + * @brief Reserved system event for network SOSLEEP usage. + */ +#define RTEMS_EVENT_SYSTEM_NETWORK_SOSLEEP RTEMS_EVENT_25 + +/** + * @brief Reserved system event for network socket close. + */ +#define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26 + +/** + * @brief Reserved system event for the server threads, e.g timer or interrupt + * server. + */ +#define RTEMS_EVENT_SYSTEM_SERVER RTEMS_EVENT_30 + +/** + * @brief Reserved system event for transient usage. + */ +#define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_31 + +/** + * @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\nrtems_event_transient_receive()"]; + * M=>>IDLE [label="blocking operation"]; + * IDLE=>>S [label="request completion"]; + * S box S [label="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="rtems_event_transient_send()"]; + * S=>>M [label="transient event is now pending"]; + * M box M [label="rtems_event_transient_receive()\nfinish request"]; + * |||; + * --- [label="sequence with timeout event"]; + * M box M [label="prepare request\nissue request\nrtems_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\nrtems_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 <assert.h> + * #include <rtems.h> + * + * 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 + ); +} + +/** @} */ + +typedef struct { + rtems_event_set pending_events; +} Event_Control; + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ |