ChibiOS/RT
2.6.0
chevents.h
Go to the documentation of this file.
00001 /*
00002     ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
00003                  2011,2012,2013 Giovanni Di Sirio.
00004 
00005     This file is part of ChibiOS/RT.
00006 
00007     ChibiOS/RT is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     ChibiOS/RT is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 
00020                                       ---
00021 
00022     A special exception to the GPL can be applied should you wish to distribute
00023     a combined work that includes ChibiOS/RT, without being obliged to provide
00024     the source code for any proprietary components. See the file exception.txt
00025     for full details of how and when the exception can be applied.
00026 */
00027 /*
00028    Concepts and parts of this file have been contributed by Scott (skute).
00029  */
00030 
00031 /**
00032  * @file    chevents.h
00033  * @brief   Events macros and structures.
00034  *
00035  * @addtogroup events
00036  * @{
00037  */
00038 
00039 #ifndef _CHEVENTS_H_
00040 #define _CHEVENTS_H_
00041 
00042 #if CH_USE_EVENTS || defined(__DOXYGEN__)
00043 
00044 typedef struct EventListener EventListener;
00045 
00046 /**
00047  * @brief   Event Listener structure.
00048  */
00049 struct EventListener {
00050   EventListener         *el_next;       /**< @brief Next Event Listener
00051                                                     registered on the Event
00052                                                     Source.                 */
00053   Thread                *el_listener;   /**< @brief Thread interested in the
00054                                                     Event Source.           */
00055   eventmask_t           el_mask;        /**< @brief Event flags mask associated
00056                                                     by the thread to the Event
00057                                                     Source.                 */
00058   flagsmask_t           el_flags;       /**< @brief Flags added to the listener
00059                                                     by the event source.*/
00060 };
00061 
00062 /**
00063  * @brief   Event Source structure.
00064  */
00065 typedef struct EventSource {
00066   EventListener         *es_next;       /**< @brief First Event Listener
00067                                                     registered on the Event
00068                                                     Source.                 */
00069 } EventSource;
00070 
00071 /**
00072  * @brief   Event Handler callback function.
00073  */
00074 typedef void (*evhandler_t)(eventid_t);
00075 
00076 /**
00077  * @brief   Data part of a static event source initializer.
00078  * @details This macro should be used when statically initializing an event
00079  *          source that is part of a bigger structure.
00080  * @param name the name of the event source variable
00081  */
00082 #define _EVENTSOURCE_DATA(name) {(void *)(&name)}
00083 
00084 /**
00085  * @brief   Static event source initializer.
00086  * @details Statically initialized event sources require no explicit
00087  *          initialization using @p chEvtInit().
00088  *
00089  * @param name          the name of the event source variable
00090  */
00091 #define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name)
00092 
00093 /**
00094  * @brief   All events allowed mask.
00095  */
00096 #define ALL_EVENTS      ((eventmask_t)-1)
00097 
00098 /**
00099  * @brief   Returns an event mask from an event identifier.
00100  */
00101 #define EVENT_MASK(eid) ((eventmask_t)(1 << (eid)))
00102 
00103 /**
00104  * @name    Macro Functions
00105  * @{
00106  */
00107 /**
00108  * @brief   Registers an Event Listener on an Event Source.
00109  * @note    Multiple Event Listeners can use the same event identifier, the
00110  *          listener will share the callback function.
00111  *
00112  * @param[in] esp       pointer to the  @p EventSource structure
00113  * @param[out] elp      pointer to the @p EventListener structure
00114  * @param[in] eid       numeric identifier assigned to the Event Listener. The
00115  *                      identifier is used as index for the event callback
00116  *                      function.
00117  *                      The value must range between zero and the size, in bit,
00118  *                      of the @p eventid_t type minus one.
00119  *
00120  * @api
00121  */
00122 #define chEvtRegister(esp, elp, eid) \
00123   chEvtRegisterMask(esp, elp, EVENT_MASK(eid))
00124 
00125 /**
00126  * @brief   Initializes an Event Source.
00127  * @note    This function can be invoked before the kernel is initialized
00128  *          because it just prepares a @p EventSource structure.
00129  *
00130  * @param[in] esp       pointer to the @p EventSource structure
00131  *
00132  * @init
00133  */
00134 #define chEvtInit(esp) \
00135   ((esp)->es_next = (EventListener *)(void *)(esp))
00136 
00137 /**
00138  * @brief   Verifies if there is at least one @p EventListener registered.
00139  *
00140  * @param[in] esp       pointer to the @p EventSource structure
00141  *
00142  * @iclass
00143  */
00144 #define chEvtIsListeningI(esp) \
00145   ((void *)(esp) != (void *)(esp)->es_next)
00146 
00147 /**
00148  * @brief   Signals all the Event Listeners registered on the specified Event
00149  *          Source.
00150  *
00151  * @param[in] esp       pointer to the @p EventSource structure
00152  *
00153  * @api
00154  */
00155 #define chEvtBroadcast(esp) chEvtBroadcastFlags(esp, 0)
00156 
00157 /**
00158  * @brief   Signals all the Event Listeners registered on the specified Event
00159  *          Source.
00160  * @post    This function does not reschedule so a call to a rescheduling
00161  *          function must be performed before unlocking the kernel. Note that
00162  *          interrupt handlers always reschedule on exit so an explicit
00163  *          reschedule must not be performed in ISRs.
00164  *
00165  * @param[in] esp       pointer to the @p EventSource structure
00166  *
00167  * @iclass
00168  */
00169 #define chEvtBroadcastI(esp) chEvtBroadcastFlagsI(esp, 0)
00170 /** @} */
00171 
00172 #ifdef __cplusplus
00173 extern "C" {
00174 #endif
00175   void chEvtRegisterMask(EventSource *esp,
00176                          EventListener *elp,
00177                          eventmask_t mask);
00178   void chEvtUnregister(EventSource *esp, EventListener *elp);
00179   eventmask_t chEvtGetAndClearEvents(eventmask_t mask);
00180   eventmask_t chEvtAddEvents(eventmask_t mask);
00181   flagsmask_t chEvtGetAndClearFlags(EventListener *elp);
00182   flagsmask_t chEvtGetAndClearFlagsI(EventListener *elp);
00183   void chEvtSignal(Thread *tp, eventmask_t mask);
00184   void chEvtSignalI(Thread *tp, eventmask_t mask);
00185   void chEvtBroadcastFlags(EventSource *esp, flagsmask_t flags);
00186   void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags);
00187   void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask);
00188 #if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT
00189   eventmask_t chEvtWaitOne(eventmask_t mask);
00190   eventmask_t chEvtWaitAny(eventmask_t mask);
00191   eventmask_t chEvtWaitAll(eventmask_t mask);
00192 #endif
00193 #if CH_USE_EVENTS_TIMEOUT
00194   eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time);
00195   eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time);
00196   eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time);
00197 #endif
00198 #ifdef __cplusplus
00199 }
00200 #endif
00201 
00202 #if !CH_OPTIMIZE_SPEED && CH_USE_EVENTS_TIMEOUT
00203 #define chEvtWaitOne(mask) chEvtWaitOneTimeout(mask, TIME_INFINITE)
00204 #define chEvtWaitAny(mask) chEvtWaitAnyTimeout(mask, TIME_INFINITE)
00205 #define chEvtWaitAll(mask) chEvtWaitAllTimeout(mask, TIME_INFINITE)
00206 #endif
00207 
00208 #endif /* CH_USE_EVENTS */
00209 
00210 #endif /* _CHEVENTS_H_ */
00211 
00212 /** @} */