source: rtems/cpukit/include/rtems/rtems/event.h @ 21275b58

5
Last change on this file since 21275b58 was efc227cd, checked in by Sebastian Huber <sebastian.huber@…>, on 11/08/18 at 09:24:19

rtems: Move internal structures to eventdata.h

Update #3598.

  • Property mode set to 100644
File size: 18.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ClassicEvent
5 *
6 * @brief Classic Event Manager API
7 */
8
9/* COPYRIGHT (c) 1989-2008.
10 * On-Line Applications Research Corporation (OAR).
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#ifndef _RTEMS_RTEMS_EVENT_H
18#define _RTEMS_RTEMS_EVENT_H
19
20#include <rtems/rtems/options.h>
21#include <rtems/rtems/status.h>
22#include <rtems/rtems/types.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/**
29 *  @defgroup ClassicEventSet Event Set
30 *
31 *  @ingroup ClassicEvent
32 *
33 *  @{
34 */
35
36/**
37 *  @brief Integer type to hold an event set of up to 32 events represented as
38 *  a bit field.
39 */
40typedef uint32_t   rtems_event_set;
41
42/**
43 *  @brief Constant used to send or receive all events.
44 */
45#define RTEMS_ALL_EVENTS  0xFFFFFFFF
46
47/** @brief Defines the bit in the event set associated with event 0. */
48#define RTEMS_EVENT_0     0x00000001
49/** @brief Defines the bit in the event set associated with event 1. */
50#define RTEMS_EVENT_1     0x00000002
51/** @brief Defines the bit in the event set associated with event 2. */
52#define RTEMS_EVENT_2     0x00000004
53/** @brief Defines the bit in the event set associated with event 3. */
54#define RTEMS_EVENT_3     0x00000008
55/** @brief Defines the bit in the event set associated with event 4. */
56#define RTEMS_EVENT_4     0x00000010
57/** @brief Defines the bit in the event set associated with event 5. */
58#define RTEMS_EVENT_5     0x00000020
59/** @brief Defines the bit in the event set associated with event 6. */
60#define RTEMS_EVENT_6     0x00000040
61/** @brief Defines the bit in the event set associated with event 7. */
62#define RTEMS_EVENT_7     0x00000080
63/** @brief Defines the bit in the event set associated with event 8. */
64#define RTEMS_EVENT_8     0x00000100
65/** @brief Defines the bit in the event set associated with event 9. */
66#define RTEMS_EVENT_9     0x00000200
67/** @brief Defines the bit in the event set associated with event 10. */
68#define RTEMS_EVENT_10    0x00000400
69/** @brief Defines the bit in the event set associated with event 11. */
70#define RTEMS_EVENT_11    0x00000800
71/** @brief Defines the bit in the event set associated with event 12. */
72#define RTEMS_EVENT_12    0x00001000
73/** @brief Defines the bit in the event set associated with event 13. */
74#define RTEMS_EVENT_13    0x00002000
75/** @brief Defines the bit in the event set associated with event 14. */
76#define RTEMS_EVENT_14    0x00004000
77/** @brief Defines the bit in the event set associated with event 15. */
78#define RTEMS_EVENT_15    0x00008000
79/** @brief Defines the bit in the event set associated with event 16. */
80#define RTEMS_EVENT_16    0x00010000
81/** @brief Defines the bit in the event set associated with event 17. */
82#define RTEMS_EVENT_17    0x00020000
83/** @brief Defines the bit in the event set associated with event 18. */
84#define RTEMS_EVENT_18    0x00040000
85/** @brief Defines the bit in the event set associated with event 19. */
86#define RTEMS_EVENT_19    0x00080000
87/** @brief Defines the bit in the event set associated with event 20. */
88#define RTEMS_EVENT_20    0x00100000
89/** @brief Defines the bit in the event set associated with event 21. */
90#define RTEMS_EVENT_21    0x00200000
91/** @brief Defines the bit in the event set associated with event 22. */
92#define RTEMS_EVENT_22    0x00400000
93/** @brief Defines the bit in the event set associated with event 23. */
94#define RTEMS_EVENT_23    0x00800000
95/** @brief Defines the bit in the event set associated with event 24. */
96#define RTEMS_EVENT_24    0x01000000
97/** @brief Defines the bit in the event set associated with event 25. */
98#define RTEMS_EVENT_25    0x02000000
99/** @brief Defines the bit in the event set associated with event 26. */
100#define RTEMS_EVENT_26    0x04000000
101/** @brief Defines the bit in the event set associated with event 27. */
102#define RTEMS_EVENT_27    0x08000000
103/** @brief Defines the bit in the event set associated with event 29. */
104#define RTEMS_EVENT_28    0x10000000
105/** @brief Defines the bit in the event set associated with event 29. */
106#define RTEMS_EVENT_29    0x20000000
107/** @brief Defines the bit in the event set associated with event 30. */
108#define RTEMS_EVENT_30    0x40000000
109/** @brief Defines the bit in the event set associated with event 31. */
110#define RTEMS_EVENT_31    0x80000000
111
112/** @} */
113
114/**
115 *  @defgroup ClassicEvent Events
116 *
117 *  @ingroup ClassicRTEMS
118 *
119 *  @brief The event manager provides a high performance method of intertask
120 *  communication and synchronization.
121 *
122 *  An event flag is used by a task (or ISR) to inform another task of the
123 *  occurrence of a significant situation. Thirty-two event flags are
124 *  associated with each task. A collection of one or more event flags is
125 *  referred to as an event set. The data type rtems_event_set is used to
126 *  manage event sets.
127 *
128 *  The application developer should remember the following key characteristics
129 *  of event operations when utilizing the event manager:
130 *
131 *  - Events provide a simple synchronization facility.
132 *  - Events are aimed at tasks.
133 *  - Tasks can wait on more than one event simultaneously.
134 *  - Events are independent of one another.
135 *  - Events do not hold or transport data.
136 *  - Events are not queued. In other words, if an event is sent more than once
137 *    to a task before being received, the second and subsequent send
138 *    operations to that same task have no effect.
139 *
140 *  An event set is posted when it is directed (or sent) to a task. A pending
141 *  event is an event that has been posted but not received. An event condition
142 *  is used to specify the event set which the task desires to receive and the
143 *  algorithm which will be used to determine when the request is satisfied. An
144 *  event condition is satisfied based upon one of two algorithms which are
145 *  selected by the user. The @ref RTEMS_EVENT_ANY algorithm states that an
146 *  event condition is satisfied when at least a single requested event is
147 *  posted.  The @ref RTEMS_EVENT_ALL algorithm states that an event condition
148 *  is satisfied when every requested event is posted.
149 *
150 *  An event set or condition is built by a bitwise or of the desired events.
151 *  The set of valid events is @ref RTEMS_EVENT_0 through @ref RTEMS_EVENT_31.
152 *  If an event is not explicitly specified in the set or condition, then it is
153 *  not present. Events are specifically designed to be mutually exclusive,
154 *  therefore bitwise or and addition operations are equivalent as long as each
155 *  event appears exactly once in the event set list.
156 *
157 *  For example, when sending the event set consisting of @ref RTEMS_EVENT_6,
158 *  @ref RTEMS_EVENT_15, and @ref RTEMS_EVENT_31, the event parameter to the
159 *  rtems_event_send() directive should be @ref RTEMS_EVENT_6 |
160 *  @ref RTEMS_EVENT_15 | @ref RTEMS_EVENT_31.
161 *
162 *  @{
163 */
164
165/**
166 *  @brief Constant used to receive the set of currently pending events in
167 *  rtems_event_receive().
168 */
169#define RTEMS_PENDING_EVENTS      0
170
171/**
172 * @brief Sends an Event Set to the Target Task
173 *
174 * This directive sends an event set @a event_in to the task specified by
175 * @a id.
176 *
177 * Based upon the state of the target task, one of the following situations
178 * applies. The target task is
179 * - blocked waiting for events.
180 * If the waiting task's input event condition is
181 * - satisfied, then the task is made ready for execution.
182 * - not satisfied, then the event set is posted but left pending and the
183 * task remains blocked.
184 * - not waiting for events.
185 * - The event set is posted and left pending.
186 *
187 * Identical events sent to a task are not queued. In other words, the second,
188 * and subsequent, posting of an event to a task before it can perform an
189 * rtems_event_receive() has no effect.
190 *
191 * The calling task will be preempted if it has preemption enabled and a
192 * higher priority task is unblocked as the result of this directive.
193 *
194 * Sending an event set to a global task which does not reside on the local
195 * node will generate a request telling the remote node to send the event set
196 * to the appropriate task.
197 *
198 * @param[in] id Identifier of the target task. Specifying @ref RTEMS_SELF
199 * results in the event set being sent to the calling task.
200 * @param[in] event_in Event set sent to the target task.
201 *
202 * @retval RTEMS_SUCCESSFUL Successful operation.
203 * @retval RTEMS_INVALID_ID Invalid task identifier.
204 */
205rtems_status_code rtems_event_send (
206  rtems_id        id,
207  rtems_event_set event_in
208);
209
210/**
211 * @brief Receives pending events.
212 *
213 * This directive attempts to receive the event condition specified in
214 * @a event_in. If @a event_in is set to @ref RTEMS_PENDING_EVENTS, then the
215 * current pending events are returned in @a event_out and left pending. The
216 * @ref RTEMS_WAIT and @ref RTEMS_NO_WAIT options in the @a option_set
217 * parameter are used to specify whether or not the task is willing to wait
218 * for the event condition to be satisfied. The @ref RTEMS_EVENT_ANY and @ref
219 * RTEMS_EVENT_ALL are used in the @a option_set parameter to specify whether
220 * at least a single event or the complete event set is necessary to satisfy
221 * the event condition. The @a event_out parameter is returned to the calling
222 * task with the value that corresponds to the events in @a event_in that were
223 * satisfied.
224 *
225 * A task can determine the pending event set by using a value of
226 * @ref RTEMS_PENDING_EVENTS for the input event set @a event_in. The pending
227 * events are returned to the calling task but the event set is left
228 * unaltered.
229 *
230 * A task can receive all of the currently pending events by using the a value
231 * of @ref RTEMS_ALL_EVENTS for the input event set @a event_in and
232 * @ref RTEMS_NO_WAIT | @ref RTEMS_EVENT_ANY for the option set @a option_set.
233 * The pending events are returned to the calling task and the event set is
234 * cleared. If no events are pending then the @ref RTEMS_UNSATISFIED status
235 * code will be returned.
236 *
237 * If pending events satisfy the event condition, then @a event_out is set to
238 * the satisfied events and the pending events in the event condition are
239 * cleared.  If the event condition is not satisfied and @ref RTEMS_NO_WAIT is
240 * specified, then @a event_out is set to the currently satisfied events.  If
241 * the calling task chooses to wait, then it will block waiting for the event
242 * condition.
243 *
244 * If the calling task must wait for the event condition to be satisfied, then
245 * the timeout parameter is used to specify the maximum interval to wait. If
246 * it is set to @ref RTEMS_NO_TIMEOUT, then the calling task will wait forever.
247 *
248 * This directive only affects the events specified in @a event_in. Any
249 * pending events that do not correspond to any of the events specified in
250 * @a event_in will be left pending.
251 *
252 * A clock tick is required to support the wait with time out functionality of
253 * this directive.
254 *
255 * @param[in] event_in Set of requested events (input events).
256 * @param[in] option_set Use a bitwise or of the following options
257 * - @ref RTEMS_WAIT - task will wait for event (default),
258 * - @ref RTEMS_NO_WAIT - task should not wait,
259 * - @ref RTEMS_EVENT_ALL - return after all events (default), and
260 * - @ref RTEMS_EVENT_ANY - return after any events.
261 * @param[in] ticks Time out in ticks. Use @ref RTEMS_NO_TIMEOUT to wait
262 * without a time out (potentially forever).
263 * @param[out] event_out Set of received events (output events).
264 *
265 * @retval RTEMS_SUCCESSFUL Successful operation.
266 * @retval RTEMS_UNSATISFIED Input events not satisfied (only with the
267 * @ref RTEMS_NO_WAIT option).
268 * @retval RTEMS_INVALID_ADDRESS The @a event_out pointer is @c NULL.
269 * @retval RTEMS_TIMEOUT Timed out waiting for events.
270 */
271rtems_status_code rtems_event_receive (
272  rtems_event_set  event_in,
273  rtems_option     option_set,
274  rtems_interval   ticks,
275  rtems_event_set *event_out
276);
277
278/** @} */
279
280/**
281 * @defgroup ClassicEventSystem System Events
282 *
283 * @ingroup ClassicEvent
284 *
285 * System events are similar to normal events.  They offer a second set of
286 * events.  These events are intended for internal RTEMS use and should not be
287 * used by applications (with the exception of the transient system event).
288 *
289 * The event @ref RTEMS_EVENT_SYSTEM_TRANSIENT is used for transient usage.
290 * See also @ref ClassicEventTransient.  This event may be used by every entity
291 * that fulfils its usage pattern.
292 */
293/**@{**/
294
295/**
296 * @brief Reserved system event for network SBWAIT usage.
297 */
298#define RTEMS_EVENT_SYSTEM_NETWORK_SBWAIT RTEMS_EVENT_24
299
300/**
301 * @brief Reserved system event for network SOSLEEP usage.
302 */
303#define RTEMS_EVENT_SYSTEM_NETWORK_SOSLEEP RTEMS_EVENT_25
304
305/**
306 * @brief Reserved system event for network socket close.
307 */
308#define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26
309
310/**
311 * @brief Reserved system event to resume server threads, e.g timer or
312 * interrupt server.
313 */
314#define RTEMS_EVENT_SYSTEM_SERVER_RESUME RTEMS_EVENT_29
315
316/**
317 * @brief Reserved system event for the server threads, e.g timer or interrupt
318 * server.
319 */
320#define RTEMS_EVENT_SYSTEM_SERVER RTEMS_EVENT_30
321
322/**
323 * @brief Reserved system event for transient usage.
324 */
325#define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_31
326
327/**
328 * @brief See rtems_event_send().
329 */
330rtems_status_code rtems_event_system_send(
331  rtems_id id,
332  rtems_event_set event_in
333);
334
335/**
336 * @brief See rtems_event_receive().
337 */
338rtems_status_code rtems_event_system_receive(
339  rtems_event_set event_in,
340  rtems_option option_set,
341  rtems_interval ticks,
342  rtems_event_set *event_out
343);
344
345/** @} */
346
347/**
348 * @defgroup ClassicEventTransient Transient Event
349 *
350 * @ingroup ClassicEvent
351 *
352 * The transient event can be used by a client task to issue a request to
353 * another task or interrupt service (server).  The server can send the
354 * transient event to the client task to notify about a request completion, see
355 * rtems_event_transient_send().  The client task can wait for the transient
356 * event reception with rtems_event_transient_receive().
357 *
358 * The user of the transient event must ensure that this event is not pending
359 * once the request is finished or cancelled.  A successful reception of the
360 * transient event with rtems_event_transient_receive() will clear the
361 * transient event.  If a reception with timeout is used the transient event
362 * state is undefined after a timeout return status.  The transient event can
363 * be cleared unconditionally with the non-blocking
364 * rtems_event_transient_clear().
365 *
366 * @msc
367 *   hscale="1.6";
368 *   M [label="Main Task"], IDLE [label="Idle Task"], S [label="Server"], TIME [label="System Tick Handler"];
369 *   |||;
370 *   --- [label="sequence with request completion"];
371 *   M box M [label="prepare request\nissue request\nrtems_event_transient_receive()"];
372 *   M=>>IDLE [label="blocking operation"];
373 *   IDLE=>>S [label="request completion"];
374 *   S box S [label="rtems_event_transient_send()"];
375 *   S=>>M [label="task is ready again"];
376 *   M box M [label="finish request"];
377 *   |||;
378 *   --- [label="sequence with early request completion"];
379 *   M box M [label="prepare request\nissue request"];
380 *   M=>>S [label="request completion"];
381 *   S box S [label="rtems_event_transient_send()"];
382 *   S=>>M [label="transient event is now pending"];
383 *   M box M [label="rtems_event_transient_receive()\nfinish request"];
384 *   |||;
385 *   --- [label="sequence with timeout event"];
386 *   M box M [label="prepare request\nissue request\nrtems_event_transient_receive()"];
387 *   M=>>IDLE [label="blocking operation"];
388 *   IDLE=>>TIME [label="timeout expired"];
389 *   TIME box TIME [label="cancel blocking operation"];
390 *   TIME=>>M [label="task is ready again"];
391 *   M box M [label="cancel request\nrtems_event_transient_clear()"];
392 * @endmsc
393 *
394 * Suppose you have a task that wants to issue a certain request and then waits
395 * for request completion.  It can create a request structure and store its
396 * task identifier there.  Now it can place the request on a work queue of
397 * another task (or interrupt handler).  Afterwards the task waits for the
398 * reception of the transient event.  Once the server task is finished with the
399 * request it can send the transient event to the waiting task and wake it up.
400 *
401 * @code
402 * #include <assert.h>
403 * #include <rtems.h>
404 *
405 * typedef struct {
406 *   rtems_id task_id;
407 *   bool work_done;
408 * } request;
409 *
410 * void server(rtems_task_argument arg)
411 * {
412 *   rtems_status_code sc;
413 *   request *req = (request *) arg;
414 *
415 *   req->work_done = true;
416 *
417 *   sc = rtems_event_transient_send(req->task_id);
418 *   assert(sc == RTEMS_SUCCESSFUL);
419 *
420 *   rtems_task_exit();
421 * }
422 *
423 * void issue_request_and_wait_for_completion(void)
424 * {
425 *   rtems_status_code sc;
426 *   rtems_id id;
427 *   request req;
428 *
429 *   req.task_id = rtems_task_self();
430 *   req.work_done = false;
431 *
432 *   sc = rtems_task_create(
433 *     rtems_build_name('S', 'E', 'R', 'V'),
434 *     1,
435 *     RTEMS_MINIMUM_STACK_SIZE,
436 *     RTEMS_DEFAULT_MODES,
437 *     RTEMS_DEFAULT_ATTRIBUTES,
438 *     &id
439 *   );
440 *   assert(sc == RTEMS_SUCCESSFUL);
441 *
442 *   sc = rtems_task_start(id, server, (rtems_task_argument) &req);
443 *   assert(sc == RTEMS_SUCCESSFUL);
444 *
445 *   sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
446 *   assert(sc == RTEMS_SUCCESSFUL);
447 *
448 *   assert(req.work_done);
449 * }
450 * @endcode
451 */
452/**@{**/
453
454/**
455 * @brief See rtems_event_system_send().
456 *
457 * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be sent.
458 */
459RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_send(
460  rtems_id id
461)
462{
463  return rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TRANSIENT );
464}
465
466/**
467 * @brief See rtems_event_system_receive().
468 *
469 * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be received.
470 */
471RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_receive(
472  rtems_option option_set,
473  rtems_interval ticks
474)
475{
476  rtems_event_set event_out;
477
478  return rtems_event_system_receive(
479    RTEMS_EVENT_SYSTEM_TRANSIENT,
480    RTEMS_EVENT_ALL | option_set,
481    ticks,
482    &event_out
483  );
484}
485
486/**
487 * @brief See rtems_event_system_receive().
488 *
489 * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be cleared.
490 */
491RTEMS_INLINE_ROUTINE void rtems_event_transient_clear( void )
492{
493  rtems_event_set event_out;
494
495  rtems_event_system_receive(
496    RTEMS_EVENT_SYSTEM_TRANSIENT,
497    RTEMS_EVENT_ALL | RTEMS_NO_WAIT,
498    0,
499    &event_out
500  );
501}
502
503/** @} */
504
505#ifdef __cplusplus
506}
507#endif
508
509#endif
510/* end of include file */
Note: See TracBrowser for help on using the repository browser.