ChibiOS/RT
2.5.1
chevents.h
Go to the documentation of this file.
00001 /*
00002     ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
00003                  2011,2012 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    Concepts and parts of this file have been contributed by Scott (skute).
00022  */
00023 
00024 /**
00025  * @file    chevents.h
00026  * @brief   Events macros and structures.
00027  *
00028  * @addtogroup events
00029  * @{
00030  */
00031 
00032 #ifndef _CHEVENTS_H_
00033 #define _CHEVENTS_H_
00034 
00035 #if CH_USE_EVENTS || defined(__DOXYGEN__)
00036 
00037 typedef struct EventListener EventListener;
00038 
00039 /**
00040  * @brief   Event Listener structure.
00041  */
00042 struct EventListener {
00043   EventListener         *el_next;       /**< @brief Next Event Listener
00044                                                     registered on the Event
00045                                                     Source.                 */
00046   Thread                *el_listener;   /**< @brief Thread interested in the
00047                                                     Event Source.           */
00048   eventmask_t           el_mask;        /**< @brief Event flags mask associated
00049                                                     by the thread to the Event
00050                                                     Source.                 */
00051   flagsmask_t           el_flags;       /**< @brief Flags added to the listener
00052                                                     bu the event source.*/
00053 };
00054 
00055 /**
00056  * @brief   Event Source structure.
00057  */
00058 typedef struct EventSource {
00059   EventListener         *es_next;       /**< @brief First Event Listener
00060                                                     registered on the Event
00061                                                     Source.                 */
00062 } EventSource;
00063 
00064 /**
00065  * @brief   Event Handler callback function.
00066  */
00067 typedef void (*evhandler_t)(eventid_t);
00068 
00069 /**
00070  * @brief   Data part of a static event source initializer.
00071  * @details This macro should be used when statically initializing an event
00072  *          source that is part of a bigger structure.
00073  * @param name the name of the event source variable
00074  */
00075 #define _EVENTSOURCE_DATA(name) {(void *)(&name)}
00076 
00077 /**
00078  * @brief   Static event source initializer.
00079  * @details Statically initialized event sources require no explicit
00080  *          initialization using @p chEvtInit().
00081  *
00082  * @param name          the name of the event source variable
00083  */
00084 #define EVENTSOURCE_DECL(name) EventSource name = _EVENTSOURCE_DATA(name)
00085 
00086 /**
00087  * @brief   All events allowed mask.
00088  */
00089 #define ALL_EVENTS      ((eventmask_t)-1)
00090 
00091 /**
00092  * @brief   Returns an event mask from an event identifier.
00093  */
00094 #define EVENT_MASK(eid) ((eventmask_t)(1 << (eid)))
00095 
00096 /**
00097  * @name    Macro Functions
00098  * @{
00099  */
00100 /**
00101  * @brief   Registers an Event Listener on an Event Source.
00102  * @note    Multiple Event Listeners can use the same event identifier, the
00103  *          listener will share the callback function.
00104  *
00105  * @param[in] esp       pointer to the  @p EventSource structure
00106  * @param[out] elp      pointer to the @p EventListener structure
00107  * @param[in] eid       numeric identifier assigned to the Event Listener. The
00108  *                      identifier is used as index for the event callback
00109  *                      function.
00110  *                      The value must range between zero and the size, in bit,
00111  *                      of the @p eventid_t type minus one.
00112  *
00113  * @api
00114  */
00115 #define chEvtRegister(esp, elp, eid) \
00116   chEvtRegisterMask(esp, elp, EVENT_MASK(eid))
00117 
00118 /**
00119  * @brief   Initializes an Event Source.
00120  * @note    This function can be invoked before the kernel is initialized
00121  *          because it just prepares a @p EventSource structure.
00122  *
00123  * @param[in] esp       pointer to the @p EventSource structure
00124  *
00125  * @init
00126  */
00127 #define chEvtInit(esp) \
00128   ((esp)->es_next = (EventListener *)(void *)(esp))
00129 
00130 /**
00131  * @brief   Verifies if there is at least one @p EventListener registered.
00132  *
00133  * @param[in] esp       pointer to the @p EventSource structure
00134  *
00135  * @iclass
00136  */
00137 #define chEvtIsListeningI(esp) \
00138   ((void *)(esp) != (void *)(esp)->es_next)
00139 
00140 /**
00141  * @brief   Signals all the Event Listeners registered on the specified Event
00142  *          Source.
00143  *
00144  * @param[in] esp       pointer to the @p EventSource structure
00145  *
00146  * @api
00147  */
00148 #define chEvtBroadcast(esp) chEvtBroadcastFlags(esp, 0)
00149 
00150 /**
00151  * @brief   Signals all the Event Listeners registered on the specified Event
00152  *          Source.
00153  * @post    This function does not reschedule so a call to a rescheduling
00154  *          function must be performed before unlocking the kernel. Note that
00155  *          interrupt handlers always reschedule on exit so an explicit
00156  *          reschedule must not be performed in ISRs.
00157  *
00158  * @param[in] esp       pointer to the @p EventSource structure
00159  *
00160  * @iclass
00161  */
00162 #define chEvtBroadcastI(esp) chEvtBroadcastFlagsI(esp, 0)
00163 /** @} */
00164 
00165 #ifdef __cplusplus
00166 extern "C" {
00167 #endif
00168   void chEvtRegisterMask(EventSource *esp,
00169                          EventListener *elp,
00170                          eventmask_t mask);
00171   void chEvtUnregister(EventSource *esp, EventListener *elp);
00172   eventmask_t chEvtGetAndClearEvents(eventmask_t mask);
00173   eventmask_t chEvtAddEvents(eventmask_t mask);
00174   flagsmask_t chEvtGetAndClearFlags(EventListener *elp);
00175   flagsmask_t chEvtGetAndClearFlagsI(EventListener *elp);
00176   void chEvtSignal(Thread *tp, eventmask_t mask);
00177   void chEvtSignalI(Thread *tp, eventmask_t mask);
00178   void chEvtBroadcastFlags(EventSource *esp, flagsmask_t flags);
00179   void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags);
00180   void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask);
00181 #if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT
00182   eventmask_t chEvtWaitOne(eventmask_t mask);
00183   eventmask_t chEvtWaitAny(eventmask_t mask);
00184   eventmask_t chEvtWaitAll(eventmask_t mask);
00185 #endif
00186 #if CH_USE_EVENTS_TIMEOUT
00187   eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time);
00188   eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time);
00189   eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time);
00190 #endif
00191 #ifdef __cplusplus
00192 }
00193 #endif
00194 
00195 #if !CH_OPTIMIZE_SPEED && CH_USE_EVENTS_TIMEOUT
00196 #define chEvtWaitOne(mask) chEvtWaitOneTimeout(mask, TIME_INFINITE)
00197 #define chEvtWaitAny(mask) chEvtWaitAnyTimeout(mask, TIME_INFINITE)
00198 #define chEvtWaitAll(mask) chEvtWaitAllTimeout(mask, TIME_INFINITE)
00199 #endif
00200 
00201 #endif /* CH_USE_EVENTS */
00202 
00203 #endif /* _CHEVENTS_H_ */
00204 
00205 /** @} */