|
ChibiOS/RT
2.5.1 |
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 /** @} */