event_groups.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. /*
  2. * FreeRTOS Kernel V10.4.6
  3. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * SPDX-License-Identifier: MIT
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  8. * this software and associated documentation files (the "Software"), to deal in
  9. * the Software without restriction, including without limitation the rights to
  10. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  11. * the Software, and to permit persons to whom the Software is furnished to do so,
  12. * subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  19. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  20. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  21. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. *
  24. * https://www.FreeRTOS.org
  25. * https://github.com/FreeRTOS
  26. *
  27. */
  28. #ifndef EVENT_GROUPS_H
  29. #define EVENT_GROUPS_H
  30. #ifndef INC_FREERTOS_H
  31. #error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
  32. #endif
  33. /* *INDENT-OFF* */
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif
  37. /* *INDENT-ON* */
  38. /**
  39. * An event group is a collection of bits to which an application can assign a
  40. * meaning. For example, an application may create an event group to convey
  41. * the status of various CAN bus related events in which bit 0 might mean "A CAN
  42. * message has been received and is ready for processing", bit 1 might mean "The
  43. * application has queued a message that is ready for sending onto the CAN
  44. * network", and bit 2 might mean "It is time to send a SYNC message onto the
  45. * CAN network" etc. A task can then test the bit values to see which events
  46. * are active, and optionally enter the Blocked state to wait for a specified
  47. * bit or a group of specified bits to be active. To continue the CAN bus
  48. * example, a CAN controlling task can enter the Blocked state (and therefore
  49. * not consume any processing time) until either bit 0, bit 1 or bit 2 are
  50. * active, at which time the bit that was actually active would inform the task
  51. * which action it had to take (process a received message, send a message, or
  52. * send a SYNC).
  53. *
  54. * The event groups implementation contains intelligence to avoid race
  55. * conditions that would otherwise occur were an application to use a simple
  56. * variable for the same purpose. This is particularly important with respect
  57. * to when a bit within an event group is to be cleared, and when bits have to
  58. * be set and then tested atomically - as is the case where event groups are
  59. * used to create a synchronisation point between multiple tasks (a
  60. * 'rendezvous').
  61. *
  62. * \defgroup EventGroup
  63. */
  64. /**
  65. * event_groups.h
  66. *
  67. * Type by which event groups are referenced. For example, a call to
  68. * xEventGroupCreate() returns an EventGroupHandle_t variable that can then
  69. * be used as a parameter to other event group functions.
  70. *
  71. * \defgroup EventGroupHandle_t EventGroupHandle_t
  72. * \ingroup EventGroup
  73. */
  74. struct EventGroupDef_t;
  75. typedef struct EventGroupDef_t * EventGroupHandle_t;
  76. /*
  77. * The type that holds event bits always matches TickType_t - therefore the
  78. * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
  79. * 32 bits if set to 0.
  80. *
  81. * \defgroup EventBits_t EventBits_t
  82. * \ingroup EventGroup
  83. */
  84. typedef TickType_t EventBits_t;
  85. /**
  86. * event_groups.h
  87. * @code{c}
  88. * EventGroupHandle_t xEventGroupCreate( void );
  89. * @endcode
  90. *
  91. * Create a new event group.
  92. *
  93. * Internally, within the FreeRTOS implementation, event groups use a [small]
  94. * block of memory, in which the event group's structure is stored. If an event
  95. * groups is created using xEventGroupCreate() then the required memory is
  96. * automatically dynamically allocated inside the xEventGroupCreate() function.
  97. * (see https://www.FreeRTOS.org/a00111.html). If an event group is created
  98. * using xEventGroupCreateStatic() then the application writer must instead
  99. * provide the memory that will get used by the event group.
  100. * xEventGroupCreateStatic() therefore allows an event group to be created
  101. * without using any dynamic memory allocation.
  102. *
  103. * Although event groups are not related to ticks, for internal implementation
  104. * reasons the number of bits available for use in an event group is dependent
  105. * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
  106. * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
  107. * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
  108. * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
  109. * event bits within an event group.
  110. *
  111. * @return If the event group was created then a handle to the event group is
  112. * returned. If there was insufficient FreeRTOS heap available to create the
  113. * event group then NULL is returned. See https://www.FreeRTOS.org/a00111.html
  114. *
  115. * Example usage:
  116. * @code{c}
  117. * // Declare a variable to hold the created event group.
  118. * EventGroupHandle_t xCreatedEventGroup;
  119. *
  120. * // Attempt to create the event group.
  121. * xCreatedEventGroup = xEventGroupCreate();
  122. *
  123. * // Was the event group created successfully?
  124. * if( xCreatedEventGroup == NULL )
  125. * {
  126. * // The event group was not created because there was insufficient
  127. * // FreeRTOS heap available.
  128. * }
  129. * else
  130. * {
  131. * // The event group was created.
  132. * }
  133. * @endcode
  134. * \defgroup xEventGroupCreate xEventGroupCreate
  135. * \ingroup EventGroup
  136. */
  137. #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
  138. EventGroupHandle_t xEventGroupCreate( void );
  139. #endif
  140. /**
  141. * event_groups.h
  142. * @code{c}
  143. * EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
  144. * @endcode
  145. *
  146. * Create a new event group.
  147. *
  148. * Internally, within the FreeRTOS implementation, event groups use a [small]
  149. * block of memory, in which the event group's structure is stored. If an event
  150. * groups is created using xEventGroupCreate() then the required memory is
  151. * automatically dynamically allocated inside the xEventGroupCreate() function.
  152. * (see https://www.FreeRTOS.org/a00111.html). If an event group is created
  153. * using xEventGroupCreateStatic() then the application writer must instead
  154. * provide the memory that will get used by the event group.
  155. * xEventGroupCreateStatic() therefore allows an event group to be created
  156. * without using any dynamic memory allocation.
  157. *
  158. * Although event groups are not related to ticks, for internal implementation
  159. * reasons the number of bits available for use in an event group is dependent
  160. * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
  161. * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
  162. * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
  163. * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
  164. * event bits within an event group.
  165. *
  166. * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
  167. * StaticEventGroup_t, which will be then be used to hold the event group's data
  168. * structures, removing the need for the memory to be allocated dynamically.
  169. *
  170. * @return If the event group was created then a handle to the event group is
  171. * returned. If pxEventGroupBuffer was NULL then NULL is returned.
  172. *
  173. * Example usage:
  174. * @code{c}
  175. * // StaticEventGroup_t is a publicly accessible structure that has the same
  176. * // size and alignment requirements as the real event group structure. It is
  177. * // provided as a mechanism for applications to know the size of the event
  178. * // group (which is dependent on the architecture and configuration file
  179. * // settings) without breaking the strict data hiding policy by exposing the
  180. * // real event group internals. This StaticEventGroup_t variable is passed
  181. * // into the xSemaphoreCreateEventGroupStatic() function and is used to store
  182. * // the event group's data structures
  183. * StaticEventGroup_t xEventGroupBuffer;
  184. *
  185. * // Create the event group without dynamically allocating any memory.
  186. * xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
  187. * @endcode
  188. */
  189. #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
  190. EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer );
  191. #endif
  192. /**
  193. * event_groups.h
  194. * @code{c}
  195. * EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
  196. * const EventBits_t uxBitsToWaitFor,
  197. * const BaseType_t xClearOnExit,
  198. * const BaseType_t xWaitForAllBits,
  199. * const TickType_t xTicksToWait );
  200. * @endcode
  201. *
  202. * [Potentially] block to wait for one or more bits to be set within a
  203. * previously created event group.
  204. *
  205. * This function cannot be called from an interrupt.
  206. *
  207. * @param xEventGroup The event group in which the bits are being tested. The
  208. * event group must have previously been created using a call to
  209. * xEventGroupCreate().
  210. *
  211. * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
  212. * inside the event group. For example, to wait for bit 0 and/or bit 2 set
  213. * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set
  214. * uxBitsToWaitFor to 0x07. Etc.
  215. *
  216. * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
  217. * uxBitsToWaitFor that are set within the event group will be cleared before
  218. * xEventGroupWaitBits() returns if the wait condition was met (if the function
  219. * returns for a reason other than a timeout). If xClearOnExit is set to
  220. * pdFALSE then the bits set in the event group are not altered when the call to
  221. * xEventGroupWaitBits() returns.
  222. *
  223. * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
  224. * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
  225. * are set or the specified block time expires. If xWaitForAllBits is set to
  226. * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
  227. * in uxBitsToWaitFor is set or the specified block time expires. The block
  228. * time is specified by the xTicksToWait parameter.
  229. *
  230. * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
  231. * for one/all (depending on the xWaitForAllBits value) of the bits specified by
  232. * uxBitsToWaitFor to become set.
  233. *
  234. * @return The value of the event group at the time either the bits being waited
  235. * for became set, or the block time expired. Test the return value to know
  236. * which bits were set. If xEventGroupWaitBits() returned because its timeout
  237. * expired then not all the bits being waited for will be set. If
  238. * xEventGroupWaitBits() returned because the bits it was waiting for were set
  239. * then the returned value is the event group value before any bits were
  240. * automatically cleared in the case that xClearOnExit parameter was set to
  241. * pdTRUE.
  242. *
  243. * Example usage:
  244. * @code{c}
  245. * #define BIT_0 ( 1 << 0 )
  246. * #define BIT_4 ( 1 << 4 )
  247. *
  248. * void aFunction( EventGroupHandle_t xEventGroup )
  249. * {
  250. * EventBits_t uxBits;
  251. * const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
  252. *
  253. * // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
  254. * // the event group. Clear the bits before exiting.
  255. * uxBits = xEventGroupWaitBits(
  256. * xEventGroup, // The event group being tested.
  257. * BIT_0 | BIT_4, // The bits within the event group to wait for.
  258. * pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
  259. * pdFALSE, // Don't wait for both bits, either bit will do.
  260. * xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
  261. *
  262. * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
  263. * {
  264. * // xEventGroupWaitBits() returned because both bits were set.
  265. * }
  266. * else if( ( uxBits & BIT_0 ) != 0 )
  267. * {
  268. * // xEventGroupWaitBits() returned because just BIT_0 was set.
  269. * }
  270. * else if( ( uxBits & BIT_4 ) != 0 )
  271. * {
  272. * // xEventGroupWaitBits() returned because just BIT_4 was set.
  273. * }
  274. * else
  275. * {
  276. * // xEventGroupWaitBits() returned because xTicksToWait ticks passed
  277. * // without either BIT_0 or BIT_4 becoming set.
  278. * }
  279. * }
  280. * @endcode
  281. * \defgroup xEventGroupWaitBits xEventGroupWaitBits
  282. * \ingroup EventGroup
  283. */
  284. EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
  285. const EventBits_t uxBitsToWaitFor,
  286. const BaseType_t xClearOnExit,
  287. const BaseType_t xWaitForAllBits,
  288. TickType_t xTicksToWait );
  289. /**
  290. * event_groups.h
  291. * @code{c}
  292. * EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
  293. * @endcode
  294. *
  295. * Set bits within an event group.
  296. * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
  297. * is a version that can be called from an interrupt.
  298. *
  299. * Setting bits in an event group will automatically unblock tasks that are
  300. * blocked waiting for the bits.
  301. *
  302. * @param xEventGroup The event group in which the bits are to be set.
  303. *
  304. * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
  305. * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
  306. * and bit 0 set uxBitsToSet to 0x09.
  307. *
  308. * @return The value of the event group at the time the call to
  309. * xEventGroupSetBits() returns. There are two reasons why the returned value
  310. * might have the bits specified by the uxBitsToSet parameter cleared. First,
  311. * if setting a bit results in a task that was waiting for the bit leaving the
  312. * blocked state then it is possible the bit will be cleared automatically
  313. * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any
  314. * unblocked (or otherwise Ready state) task that has a priority above that of
  315. * the task that called xEventGroupSetBits() will execute and may change the
  316. * event group value before the call to xEventGroupSetBits() returns.
  317. *
  318. * Example usage:
  319. * @code{c}
  320. * #define BIT_0 ( 1 << 0 )
  321. * #define BIT_4 ( 1 << 4 )
  322. *
  323. * void aFunction( EventGroupHandle_t xEventGroup )
  324. * {
  325. * EventBits_t uxBits;
  326. *
  327. * // Set bit 0 and bit 4 in xEventGroup.
  328. * uxBits = xEventGroupSetBits(
  329. * xEventGroup, // The event group being updated.
  330. * BIT_0 | BIT_4 );// The bits being set.
  331. *
  332. * if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
  333. * {
  334. * // Both bit 0 and bit 4 remained set when the function returned.
  335. * }
  336. * else if( ( uxBits & BIT_0 ) != 0 )
  337. * {
  338. * // Bit 0 remained set when the function returned, but bit 4 was
  339. * // cleared. It might be that bit 4 was cleared automatically as a
  340. * // task that was waiting for bit 4 was removed from the Blocked
  341. * // state.
  342. * }
  343. * else if( ( uxBits & BIT_4 ) != 0 )
  344. * {
  345. * // Bit 4 remained set when the function returned, but bit 0 was
  346. * // cleared. It might be that bit 0 was cleared automatically as a
  347. * // task that was waiting for bit 0 was removed from the Blocked
  348. * // state.
  349. * }
  350. * else
  351. * {
  352. * // Neither bit 0 nor bit 4 remained set. It might be that a task
  353. * // was waiting for both of the bits to be set, and the bits were
  354. * // cleared as the task left the Blocked state.
  355. * }
  356. * }
  357. * @endcode
  358. * \defgroup xEventGroupSetBits xEventGroupSetBits
  359. * \ingroup EventGroup
  360. */
  361. EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
  362. const EventBits_t uxBitsToSet );
  363. /**
  364. * event_groups.h
  365. * @code{c}
  366. * BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
  367. * @endcode
  368. *
  369. * A version of xEventGroupSetBits() that can be called from an interrupt.
  370. *
  371. * Setting bits in an event group is not a deterministic operation because there
  372. * are an unknown number of tasks that may be waiting for the bit or bits being
  373. * set. FreeRTOS does not allow nondeterministic operations to be performed in
  374. * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR()
  375. * sends a message to the timer task to have the set operation performed in the
  376. * context of the timer task - where a scheduler lock is used in place of a
  377. * critical section.
  378. *
  379. * @param xEventGroup The event group in which the bits are to be set.
  380. *
  381. * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
  382. * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
  383. * and bit 0 set uxBitsToSet to 0x09.
  384. *
  385. * @param pxHigherPriorityTaskWoken As mentioned above, calling this function
  386. * will result in a message being sent to the timer daemon task. If the
  387. * priority of the timer daemon task is higher than the priority of the
  388. * currently running task (the task the interrupt interrupted) then
  389. * *pxHigherPriorityTaskWoken will be set to pdTRUE by
  390. * xEventGroupSetBitsFromISR(), indicating that a context switch should be
  391. * requested before the interrupt exits. For that reason
  392. * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the
  393. * example code below.
  394. *
  395. * @return If the request to execute the function was posted successfully then
  396. * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
  397. * if the timer service queue was full.
  398. *
  399. * Example usage:
  400. * @code{c}
  401. * #define BIT_0 ( 1 << 0 )
  402. * #define BIT_4 ( 1 << 4 )
  403. *
  404. * // An event group which it is assumed has already been created by a call to
  405. * // xEventGroupCreate().
  406. * EventGroupHandle_t xEventGroup;
  407. *
  408. * void anInterruptHandler( void )
  409. * {
  410. * BaseType_t xHigherPriorityTaskWoken, xResult;
  411. *
  412. * // xHigherPriorityTaskWoken must be initialised to pdFALSE.
  413. * xHigherPriorityTaskWoken = pdFALSE;
  414. *
  415. * // Set bit 0 and bit 4 in xEventGroup.
  416. * xResult = xEventGroupSetBitsFromISR(
  417. * xEventGroup, // The event group being updated.
  418. * BIT_0 | BIT_4 // The bits being set.
  419. * &xHigherPriorityTaskWoken );
  420. *
  421. * // Was the message posted successfully?
  422. * if( xResult == pdPASS )
  423. * {
  424. * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
  425. * // switch should be requested. The macro used is port specific and
  426. * // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
  427. * // refer to the documentation page for the port being used.
  428. * portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
  429. * }
  430. * }
  431. * @endcode
  432. * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
  433. * \ingroup EventGroup
  434. */
  435. BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
  436. const EventBits_t uxBitsToSet,
  437. BaseType_t * pxHigherPriorityTaskWoken );
  438. /**
  439. * event_groups.h
  440. * @code{c}
  441. * void xEventGroupDelete( EventGroupHandle_t xEventGroup );
  442. * @endcode
  443. *
  444. * Delete an event group that was previously created by a call to
  445. * xEventGroupCreate(). Tasks that are blocked on the event group will be
  446. * unblocked and obtain 0 as the event group's value.
  447. *
  448. * @param xEventGroup The event group being deleted.
  449. */
  450. void vEventGroupDelete( EventGroupHandle_t xEventGroup );
  451. /* *INDENT-OFF* */
  452. #ifdef __cplusplus
  453. }
  454. #endif
  455. /* *INDENT-ON* */
  456. #endif /* EVENT_GROUPS_H */