ChibiOS/RT  6.0.3
chevents.h
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio.
3 
4  This file is part of ChibiOS.
5 
6  ChibiOS is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 3 of the License, or
9  (at your option) any later version.
10 
11  ChibiOS is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 /*
20  Concepts and parts of this file have been contributed by Scott (skute).
21  */
22 
23 /**
24  * @file chevents.h
25  * @brief Events macros and structures.
26  *
27  * @addtogroup events
28  * @{
29  */
30 
31 #ifndef CHEVENTS_H
32 #define CHEVENTS_H
33 
34 #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
35 
36 /*===========================================================================*/
37 /* Module constants. */
38 /*===========================================================================*/
39 
40 /*===========================================================================*/
41 /* Module pre-compile time settings. */
42 /*===========================================================================*/
43 
44 /*===========================================================================*/
45 /* Derived constants and error checks. */
46 /*===========================================================================*/
47 
48 /*===========================================================================*/
49 /* Module data structures and types. */
50 /*===========================================================================*/
51 
52 typedef struct event_listener event_listener_t;
53 
54 /**
55  * @brief Event Listener structure.
56  */
58  event_listener_t *next; /**< @brief Next Event Listener
59  registered on the event
60  source. */
61  thread_t *listener; /**< @brief Thread interested in the
62  event source. */
63  eventmask_t events; /**< @brief Events to be set in
64  the listening thread. */
65  eventflags_t flags; /**< @brief Flags added to the listener
66  by the event source. */
67  eventflags_t wflags; /**< @brief Flags that this listener
68  interested in. */
69 };
70 
71 /**
72  * @brief Event Source structure.
73  */
74 typedef struct event_source {
75  event_listener_t *next; /**< @brief First Event Listener
76  registered on the Event
77  Source. */
79 
80 /**
81  * @brief Event Handler callback function.
82  */
83 typedef void (*evhandler_t)(eventid_t id);
84 
85 /*===========================================================================*/
86 /* Module macros. */
87 /*===========================================================================*/
88 
89 /**
90  * @brief All events allowed mask.
91  */
92 #define ALL_EVENTS ((eventmask_t)-1)
93 
94 /**
95  * @brief Returns an event mask from an event identifier.
96  */
97 #define EVENT_MASK(eid) ((eventmask_t)1 << (eventmask_t)(eid))
98 
99 /**
100  * @brief Data part of a static event source initializer.
101  * @details This macro should be used when statically initializing an event
102  * source that is part of a bigger structure.
103  * @param name the name of the event source variable
104  */
105 #define _EVENTSOURCE_DATA(name) {(event_listener_t *)(&name)}
106 
107 /**
108  * @brief Static event source initializer.
109  * @details Statically initialized event sources require no explicit
110  * initialization using @p chEvtInit().
111  *
112  * @param name the name of the event source variable
113  */
114 #define EVENTSOURCE_DECL(name) event_source_t name = _EVENTSOURCE_DATA(name)
115 
116 /*===========================================================================*/
117 /* External declarations. */
118 /*===========================================================================*/
119 
120 #ifdef __cplusplus
121 extern "C" {
122 #endif
124  event_listener_t *elp,
125  eventmask_t events,
126  eventflags_t wflags);
128  eventmask_t chEvtGetAndClearEventsI(eventmask_t events);
129  eventmask_t chEvtGetAndClearEvents(eventmask_t events);
130  eventmask_t chEvtAddEvents(eventmask_t events);
131  eventflags_t chEvtGetAndClearFlags(event_listener_t *elp);
132  eventflags_t chEvtGetAndClearFlagsI(event_listener_t *elp);
133  void chEvtSignal(thread_t *tp, eventmask_t events);
134  void chEvtSignalI(thread_t *tp, eventmask_t events);
135  void chEvtBroadcastFlags(event_source_t *esp, eventflags_t flags);
136  void chEvtBroadcastFlagsI(event_source_t *esp, eventflags_t flags);
137  void chEvtDispatch(const evhandler_t *handlers, eventmask_t events);
138 #if (CH_CFG_OPTIMIZE_SPEED == TRUE) || (CH_CFG_USE_EVENTS_TIMEOUT == FALSE)
139  eventmask_t chEvtWaitOne(eventmask_t events);
140  eventmask_t chEvtWaitAny(eventmask_t events);
141  eventmask_t chEvtWaitAll(eventmask_t events);
142 #endif
143 #if CH_CFG_USE_EVENTS_TIMEOUT == TRUE
144  eventmask_t chEvtWaitOneTimeout(eventmask_t events, sysinterval_t timeout);
145  eventmask_t chEvtWaitAnyTimeout(eventmask_t events, sysinterval_t timeout);
146  eventmask_t chEvtWaitAllTimeout(eventmask_t events, sysinterval_t timeout);
147 #endif
148 #ifdef __cplusplus
149 }
150 #endif
151 
152 #if (CH_CFG_OPTIMIZE_SPEED == FALSE) && (CH_CFG_USE_EVENTS_TIMEOUT == TRUE)
153 #define chEvtWaitOne(mask) chEvtWaitOneTimeout(mask, TIME_INFINITE)
154 #define chEvtWaitAny(mask) chEvtWaitAnyTimeout(mask, TIME_INFINITE)
155 #define chEvtWaitAll(mask) chEvtWaitAllTimeout(mask, TIME_INFINITE)
156 #endif
157 
158 /*===========================================================================*/
159 /* Module inline functions. */
160 /*===========================================================================*/
161 
162 /**
163  * @brief Initializes an Event Source.
164  * @note This function can be invoked before the kernel is initialized
165  * because it just prepares a @p event_source_t structure.
166  *
167  * @param[in] esp pointer to the @p event_source_t structure
168  *
169  * @init
170  */
171 static inline void chEvtObjectInit(event_source_t *esp) {
172 
173  esp->next = (event_listener_t *)esp;
174 }
175 
176 /**
177  * @brief Registers an Event Listener on an Event Source.
178  * @details Once a thread has registered as listener on an event source it
179  * will be notified of all events broadcasted there.
180  * @note Multiple Event Listeners can specify the same bits to be ORed to
181  * different threads.
182  *
183  * @param[in] esp pointer to the @p event_source_t structure
184  * @param[out] elp pointer to the @p event_listener_t structure
185  * @param[in] events the mask of events to be ORed to the thread when
186  * the event source is broadcasted
187  *
188  * @api
189  */
190 static inline void chEvtRegisterMask(event_source_t *esp,
191  event_listener_t *elp,
192  eventmask_t events) {
193 
194  chEvtRegisterMaskWithFlags(esp, elp, events, (eventflags_t)-1);
195 }
196 
197 /**
198  * @brief Registers an Event Listener on an Event Source.
199  * @note Multiple Event Listeners can use the same event identifier, the
200  * listener will share the callback function.
201  *
202  * @param[in] esp pointer to the @p event_source_t structure
203  * @param[out] elp pointer to the @p event_listener_t structure
204  * @param[in] event numeric identifier assigned to the Event Listener.
205  * The value must range between zero and the size, in bit,
206  * of the @p eventmask_t type minus one.
207  *
208  * @api
209  */
210 static inline void chEvtRegister(event_source_t *esp,
211  event_listener_t *elp,
212  eventid_t event) {
213 
214  chEvtRegisterMask(esp, elp, EVENT_MASK(event));
215 }
216 
217 /**
218  * @brief Verifies if there is at least one @p event_listener_t registered.
219  *
220  * @param[in] esp pointer to the @p event_source_t structure
221  * @return The event source status.
222  *
223  * @iclass
224  */
225 static inline bool chEvtIsListeningI(event_source_t *esp) {
226 
227  return (bool)(esp != (event_source_t *)esp->next);
228 }
229 
230 /**
231  * @brief Signals all the Event Listeners registered on the specified Event
232  * Source.
233  *
234  * @param[in] esp pointer to the @p event_source_t structure
235  *
236  * @api
237  */
238 static inline void chEvtBroadcast(event_source_t *esp) {
239 
240  chEvtBroadcastFlags(esp, (eventflags_t)0);
241 }
242 
243 /**
244  * @brief Signals all the Event Listeners registered on the specified Event
245  * Source.
246  * @post This function does not reschedule so a call to a rescheduling
247  * function must be performed before unlocking the kernel. Note that
248  * interrupt handlers always reschedule on exit so an explicit
249  * reschedule must not be performed in ISRs.
250  *
251  * @param[in] esp pointer to the @p event_source_t structure
252  *
253  * @iclass
254  */
255 static inline void chEvtBroadcastI(event_source_t *esp) {
256 
257  chEvtBroadcastFlagsI(esp, (eventflags_t)0);
258 }
259 
260 /**
261  * @brief Adds (OR) a set of events to the current thread, this is
262  * @b much faster than using @p chEvtBroadcast() or @p chEvtSignal().
263  *
264  * @param[in] events the events to be added
265  * @return The mask of currently pending events.
266  *
267  * @iclass
268  */
269 static inline eventmask_t chEvtAddEventsI(eventmask_t events) {
270 
271  return currp->epending |= events;
272 }
273 
274 /**
275  * @brief Returns the events mask.
276  * @details The pending events mask is returned but not altered in any way.
277  *
278  * @return The pending events mask.
279  *
280  * @api
281  */
282 static inline eventmask_t chEvtGetEventsX(void) {
283 
284  return currp->epending;
285 }
286 
287 #endif /* CH_CFG_USE_EVENTS == TRUE */
288 
289 #endif /* CHEVENTS_H */
290 
291 /** @} */
eventmask_t chEvtWaitOne(eventmask_t events)
Waits for exactly one of the specified events.
Definition: chevents.c:399
void chEvtRegisterMaskWithFlags(event_source_t *esp, event_listener_t *elp, eventmask_t events, eventflags_t wflags)
Registers an Event Listener on an Event Source.
Definition: chevents.c:103
eventmask_t chEvtAddEvents(eventmask_t events)
Adds (OR) a set of events to the current thread, this is much faster than using chEvtBroadcast() or c...
Definition: chevents.c:198
eventmask_t chEvtGetAndClearEventsI(eventmask_t events)
Clears the pending events specified in the events mask.
Definition: chevents.c:162
eventflags_t wflags
Flags that this listener interested in.
Definition: chevents.h:67
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:119
Event Source structure.
Definition: chevents.h:74
eventmask_t events
Events to be set in the listening thread.
Definition: chevents.h:63
eventflags_t chEvtGetAndClearFlags(event_listener_t *elp)
Returns the flags associated to an event_listener_t.
Definition: chevents.c:257
#define EVENT_MASK(eid)
Returns an event mask from an event identifier.
Definition: chevents.h:97
#define currp
Current thread pointer access macro.
Definition: chschd.h:459
static void chEvtBroadcast(event_source_t *esp)
Signals all the Event Listeners registered on the specified Event Source.
Definition: chevents.h:238
void chEvtBroadcastFlags(event_source_t *esp, eventflags_t flags)
Signals all the Event Listeners registered on the specified Event Source.
Definition: chevents.c:327
static void chEvtBroadcastI(event_source_t *esp)
Signals all the Event Listeners registered on the specified Event Source.
Definition: chevents.h:255
void chEvtSignal(thread_t *tp, eventmask_t events)
Adds a set of event flags directly to the specified thread_t.
Definition: chevents.c:276
thread_t * listener
Thread interested in the event source.
Definition: chevents.h:61
void chEvtUnregister(event_source_t *esp, event_listener_t *elp)
Unregisters an Event Listener from its Event Source.
Definition: chevents.c:133
void chEvtBroadcastFlagsI(event_source_t *esp, eventflags_t flags)
Signals all the Event Listeners registered on the specified Event Source.
Definition: chevents.c:225
event_listener_t * next
First Event Listener registered on the Event Source.
Definition: chevents.h:75
static eventmask_t chEvtAddEventsI(eventmask_t events)
Adds (OR) a set of events to the current thread, this is much faster than using chEvtBroadcast() or c...
Definition: chevents.h:269
void chEvtSignalI(thread_t *tp, eventmask_t events)
Adds a set of event flags directly to the specified thread_t.
Definition: chevents.c:298
Event Listener structure.
Definition: chevents.h:57
event_listener_t * next
Next Event Listener registered on the event source.
Definition: chevents.h:58
eventmask_t chEvtWaitAny(eventmask_t events)
Waits for any of the specified events.
Definition: chevents.c:429
eventmask_t chEvtWaitAllTimeout(eventmask_t events, sysinterval_t timeout)
Waits for all the specified events.
Definition: chevents.c:579
void(* evhandler_t)(eventid_t id)
Event Handler callback function.
Definition: chevents.h:83
eventmask_t chEvtWaitAnyTimeout(eventmask_t events, sysinterval_t timeout)
Waits for any of the specified events.
Definition: chevents.c:538
struct event_source event_source_t
Event Source structure.
static eventmask_t chEvtGetEventsX(void)
Returns the events mask.
Definition: chevents.h:282
static void chEvtRegisterMask(event_source_t *esp, event_listener_t *elp, eventmask_t events)
Registers an Event Listener on an Event Source.
Definition: chevents.h:190
eventmask_t chEvtGetAndClearEvents(eventmask_t events)
Clears the pending events specified in the events mask.
Definition: chevents.c:179
eventmask_t chEvtWaitAll(eventmask_t events)
Waits for all the specified events.
Definition: chevents.c:457
eventflags_t flags
Flags added to the listener by the event source.
Definition: chevents.h:65
static void chEvtRegister(event_source_t *esp, event_listener_t *elp, eventid_t event)
Registers an Event Listener on an Event Source.
Definition: chevents.h:210
eventflags_t chEvtGetAndClearFlagsI(event_listener_t *elp)
Returns the unmasked flags associated to an event_listener_t.
Definition: chevents.c:346
void chEvtDispatch(const evhandler_t *handlers, eventmask_t events)
Invokes the event handlers associated to an event flags mask.
Definition: chevents.c:364
eventmask_t chEvtWaitOneTimeout(eventmask_t events, sysinterval_t timeout)
Waits for exactly one of the specified events.
Definition: chevents.c:495
Structure representing a thread.
Definition: chschd.h:153
static bool chEvtIsListeningI(event_source_t *esp)
Verifies if there is at least one event_listener_t registered.
Definition: chevents.h:225
static void chEvtObjectInit(event_source_t *esp)
Initializes an Event Source.
Definition: chevents.h:171