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