chevents.h 10 KB

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