event_groups.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. /*
  2. * FreeRTOS Kernel V10.2.1
  3. * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. * this software and associated documentation files (the "Software"), to deal in
  7. * the Software without restriction, including without limitation the rights to
  8. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9. * the Software, and to permit persons to whom the Software is furnished to do so,
  10. * subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in all
  13. * copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  18. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * http://www.FreeRTOS.org
  23. * http://aws.amazon.com/freertos
  24. *
  25. * 1 tab == 4 spaces!
  26. */
  27. #ifndef EVENT_GROUPS_H
  28. #define EVENT_GROUPS_H
  29. #ifndef INC_FREERTOS_H
  30. #error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
  31. #endif
  32. /* FreeRTOS includes. */
  33. #include "timers.h"
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif
  37. /**
  38. * An event group is a collection of bits to which an application can assign a
  39. * meaning. For example, an application may create an event group to convey
  40. * the status of various CAN bus related events in which bit 0 might mean "A CAN
  41. * message has been received and is ready for processing", bit 1 might mean "The
  42. * application has queued a message that is ready for sending onto the CAN
  43. * network", and bit 2 might mean "It is time to send a SYNC message onto the
  44. * CAN network" etc. A task can then test the bit values to see which events
  45. * are active, and optionally enter the Blocked state to wait for a specified
  46. * bit or a group of specified bits to be active. To continue the CAN bus
  47. * example, a CAN controlling task can enter the Blocked state (and therefore
  48. * not consume any processing time) until either bit 0, bit 1 or bit 2 are
  49. * active, at which time the bit that was actually active would inform the task
  50. * which action it had to take (process a received message, send a message, or
  51. * send a SYNC).
  52. *
  53. * The event groups implementation contains intelligence to avoid race
  54. * conditions that would otherwise occur were an application to use a simple
  55. * variable for the same purpose. This is particularly important with respect
  56. * to when a bit within an event group is to be cleared, and when bits have to
  57. * be set and then tested atomically - as is the case where event groups are
  58. * used to create a synchronisation point between multiple tasks (a
  59. * 'rendezvous').
  60. *
  61. * \defgroup EventGroup
  62. */
  63. /**
  64. * event_groups.h
  65. *
  66. * Type by which event groups are referenced. For example, a call to
  67. * xEventGroupCreate() returns an EventGroupHandle_t variable that can then
  68. * be used as a parameter to other event group functions.
  69. *
  70. * \defgroup EventGroupHandle_t EventGroupHandle_t
  71. * \ingroup EventGroup
  72. */
  73. struct EventGroupDef_t;
  74. typedef struct EventGroupDef_t * EventGroupHandle_t;
  75. /*
  76. * The type that holds event bits always matches TickType_t - therefore the
  77. * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
  78. * 32 bits if set to 0.
  79. *
  80. * \defgroup EventBits_t EventBits_t
  81. * \ingroup EventGroup
  82. */
  83. typedef TickType_t EventBits_t;
  84. /**
  85. * event_groups.h
  86. *<pre>
  87. EventGroupHandle_t xEventGroupCreate( void );
  88. </pre>
  89. *
  90. * Create a new event group.
  91. *
  92. * Internally, within the FreeRTOS implementation, event groups use a [small]
  93. * block of memory, in which the event group's structure is stored. If an event
  94. * groups is created using xEventGropuCreate() then the required memory is
  95. * automatically dynamically allocated inside the xEventGroupCreate() function.
  96. * (see http://www.freertos.org/a00111.html). If an event group is created
  97. * using xEventGropuCreateStatic() then the application writer must instead
  98. * provide the memory that will get used by the event group.
  99. * xEventGroupCreateStatic() therefore allows an event group to be created
  100. * without using any dynamic memory allocation.
  101. *
  102. * Although event groups are not related to ticks, for internal implementation
  103. * reasons the number of bits available for use in an event group is dependent
  104. * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
  105. * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
  106. * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
  107. * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
  108. * event bits within an event group.
  109. *
  110. * @return If the event group was created then a handle to the event group is
  111. * returned. If there was insufficient FreeRTOS heap available to create the
  112. * event group then NULL is returned. See http://www.freertos.org/a00111.html
  113. *
  114. * Example usage:
  115. <pre>
  116. // Declare a variable to hold the created event group.
  117. EventGroupHandle_t xCreatedEventGroup;
  118. // Attempt to create the event group.
  119. xCreatedEventGroup = xEventGroupCreate();
  120. // Was the event group created successfully?
  121. if( xCreatedEventGroup == NULL )
  122. {
  123. // The event group was not created because there was insufficient
  124. // FreeRTOS heap available.
  125. }
  126. else
  127. {
  128. // The event group was created.
  129. }
  130. </pre>
  131. * \defgroup xEventGroupCreate xEventGroupCreate
  132. * \ingroup EventGroup
  133. */
  134. #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
  135. EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
  136. #endif
  137. /**
  138. * event_groups.h
  139. *<pre>
  140. EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
  141. </pre>
  142. *
  143. * Create a new event group.
  144. *
  145. * Internally, within the FreeRTOS implementation, event groups use a [small]
  146. * block of memory, in which the event group's structure is stored. If an event
  147. * groups is created using xEventGropuCreate() then the required memory is
  148. * automatically dynamically allocated inside the xEventGroupCreate() function.
  149. * (see http://www.freertos.org/a00111.html). If an event group is created
  150. * using xEventGropuCreateStatic() then the application writer must instead
  151. * provide the memory that will get used by the event group.
  152. * xEventGroupCreateStatic() therefore allows an event group to be created
  153. * without using any dynamic memory allocation.
  154. *
  155. * Although event groups are not related to ticks, for internal implementation
  156. * reasons the number of bits available for use in an event group is dependent
  157. * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
  158. * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
  159. * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
  160. * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
  161. * event bits within an event group.
  162. *
  163. * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
  164. * StaticEventGroup_t, which will be then be used to hold the event group's data
  165. * structures, removing the need for the memory to be allocated dynamically.
  166. *
  167. * @return If the event group was created then a handle to the event group is
  168. * returned. If pxEventGroupBuffer was NULL then NULL is returned.
  169. *
  170. * Example usage:
  171. <pre>
  172. // StaticEventGroup_t is a publicly accessible structure that has the same
  173. // size and alignment requirements as the real event group structure. It is
  174. // provided as a mechanism for applications to know the size of the event
  175. // group (which is dependent on the architecture and configuration file
  176. // settings) without breaking the strict data hiding policy by exposing the
  177. // real event group internals. This StaticEventGroup_t variable is passed
  178. // into the xSemaphoreCreateEventGroupStatic() function and is used to store
  179. // the event group's data structures
  180. StaticEventGroup_t xEventGroupBuffer;
  181. // Create the event group without dynamically allocating any memory.
  182. xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
  183. </pre>
  184. */
  185. #if( configSUPPORT_STATIC_ALLOCATION == 1 )
  186. EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
  187. #endif
  188. /**
  189. * event_groups.h
  190. *<pre>
  191. EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
  192. const EventBits_t uxBitsToWaitFor,
  193. const BaseType_t xClearOnExit,
  194. const BaseType_t xWaitForAllBits,
  195. const TickType_t xTicksToWait );
  196. </pre>
  197. *
  198. * [Potentially] block to wait for one or more bits to be set within a
  199. * previously created event group.
  200. *
  201. * This function cannot be called from an interrupt.
  202. *
  203. * @param xEventGroup The event group in which the bits are being tested. The
  204. * event group must have previously been created using a call to
  205. * xEventGroupCreate().
  206. *
  207. * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
  208. * inside the event group. For example, to wait for bit 0 and/or bit 2 set
  209. * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set
  210. * uxBitsToWaitFor to 0x07. Etc.
  211. *
  212. * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
  213. * uxBitsToWaitFor that are set within the event group will be cleared before
  214. * xEventGroupWaitBits() returns if the wait condition was met (if the function
  215. * returns for a reason other than a timeout). If xClearOnExit is set to
  216. * pdFALSE then the bits set in the event group are not altered when the call to
  217. * xEventGroupWaitBits() returns.
  218. *
  219. * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
  220. * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
  221. * are set or the specified block time expires. If xWaitForAllBits is set to
  222. * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
  223. * in uxBitsToWaitFor is set or the specified block time expires. The block
  224. * time is specified by the xTicksToWait parameter.
  225. *
  226. * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
  227. * for one/all (depending on the xWaitForAllBits value) of the bits specified by
  228. * uxBitsToWaitFor to become set.
  229. *
  230. * @return The value of the event group at the time either the bits being waited
  231. * for became set, or the block time expired. Test the return value to know
  232. * which bits were set. If xEventGroupWaitBits() returned because its timeout
  233. * expired then not all the bits being waited for will be set. If
  234. * xEventGroupWaitBits() returned because the bits it was waiting for were set
  235. * then the returned value is the event group value before any bits were
  236. * automatically cleared in the case that xClearOnExit parameter was set to
  237. * pdTRUE.
  238. *
  239. * Example usage:
  240. <pre>
  241. #define BIT_0 ( 1 << 0 )
  242. #define BIT_4 ( 1 << 4 )
  243. void aFunction( EventGroupHandle_t xEventGroup )
  244. {
  245. EventBits_t uxBits;
  246. const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
  247. // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
  248. // the event group. Clear the bits before exiting.
  249. uxBits = xEventGroupWaitBits(
  250. xEventGroup, // The event group being tested.
  251. BIT_0 | BIT_4, // The bits within the event group to wait for.
  252. pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
  253. pdFALSE, // Don't wait for both bits, either bit will do.
  254. xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
  255. if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
  256. {
  257. // xEventGroupWaitBits() returned because both bits were set.
  258. }
  259. else if( ( uxBits & BIT_0 ) != 0 )
  260. {
  261. // xEventGroupWaitBits() returned because just BIT_0 was set.
  262. }
  263. else if( ( uxBits & BIT_4 ) != 0 )
  264. {
  265. // xEventGroupWaitBits() returned because just BIT_4 was set.
  266. }
  267. else
  268. {
  269. // xEventGroupWaitBits() returned because xTicksToWait ticks passed
  270. // without either BIT_0 or BIT_4 becoming set.
  271. }
  272. }
  273. </pre>
  274. * \defgroup xEventGroupWaitBits xEventGroupWaitBits
  275. * \ingroup EventGroup
  276. */
  277. EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
  278. /**
  279. * event_groups.h
  280. *<pre>
  281. EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
  282. </pre>
  283. *
  284. * Clear bits within an event group. This function cannot be called from an
  285. * interrupt.
  286. *
  287. * @param xEventGroup The event group in which the bits are to be cleared.
  288. *
  289. * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
  290. * in the event group. For example, to clear bit 3 only, set uxBitsToClear to
  291. * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
  292. *
  293. * @return The value of the event group before the specified bits were cleared.
  294. *
  295. * Example usage:
  296. <pre>
  297. #define BIT_0 ( 1 << 0 )
  298. #define BIT_4 ( 1 << 4 )
  299. void aFunction( EventGroupHandle_t xEventGroup )
  300. {
  301. EventBits_t uxBits;
  302. // Clear bit 0 and bit 4 in xEventGroup.
  303. uxBits = xEventGroupClearBits(
  304. xEventGroup, // The event group being updated.
  305. BIT_0 | BIT_4 );// The bits being cleared.
  306. if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
  307. {
  308. // Both bit 0 and bit 4 were set before xEventGroupClearBits() was
  309. // called. Both will now be clear (not set).
  310. }
  311. else if( ( uxBits & BIT_0 ) != 0 )
  312. {
  313. // Bit 0 was set before xEventGroupClearBits() was called. It will
  314. // now be clear.
  315. }
  316. else if( ( uxBits & BIT_4 ) != 0 )
  317. {
  318. // Bit 4 was set before xEventGroupClearBits() was called. It will
  319. // now be clear.
  320. }
  321. else
  322. {
  323. // Neither bit 0 nor bit 4 were set in the first place.
  324. }
  325. }
  326. </pre>
  327. * \defgroup xEventGroupClearBits xEventGroupClearBits
  328. * \ingroup EventGroup
  329. */
  330. EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
  331. /**
  332. * event_groups.h
  333. *<pre>
  334. BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
  335. </pre>
  336. *
  337. * A version of xEventGroupClearBits() that can be called from an interrupt.
  338. *
  339. * Setting bits in an event group is not a deterministic operation because there
  340. * are an unknown number of tasks that may be waiting for the bit or bits being
  341. * set. FreeRTOS does not allow nondeterministic operations to be performed
  342. * while interrupts are disabled, so protects event groups that are accessed
  343. * from tasks by suspending the scheduler rather than disabling interrupts. As
  344. * a result event groups cannot be accessed directly from an interrupt service
  345. * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the
  346. * timer task to have the clear operation performed in the context of the timer
  347. * task.
  348. *
  349. * @param xEventGroup The event group in which the bits are to be cleared.
  350. *
  351. * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
  352. * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3
  353. * and bit 0 set uxBitsToClear to 0x09.
  354. *
  355. * @return If the request to execute the function was posted successfully then
  356. * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
  357. * if the timer service queue was full.
  358. *
  359. * Example usage:
  360. <pre>
  361. #define BIT_0 ( 1 << 0 )
  362. #define BIT_4 ( 1 << 4 )
  363. // An event group which it is assumed has already been created by a call to
  364. // xEventGroupCreate().
  365. EventGroupHandle_t xEventGroup;
  366. void anInterruptHandler( void )
  367. {
  368. // Clear bit 0 and bit 4 in xEventGroup.
  369. xResult = xEventGroupClearBitsFromISR(
  370. xEventGroup, // The event group being updated.
  371. BIT_0 | BIT_4 ); // The bits being set.
  372. if( xResult == pdPASS )
  373. {
  374. // The message was posted successfully.
  375. }
  376. }
  377. </pre>
  378. * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
  379. * \ingroup EventGroup
  380. */
  381. #if( configUSE_TRACE_FACILITY == 1 )
  382. BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
  383. #else
  384. #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
  385. #endif
  386. /**
  387. * event_groups.h
  388. *<pre>
  389. EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
  390. </pre>
  391. *
  392. * Set bits within an event group.
  393. * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
  394. * is a version that can be called from an interrupt.
  395. *
  396. * Setting bits in an event group will automatically unblock tasks that are
  397. * blocked waiting for the bits.
  398. *
  399. * @param xEventGroup The event group in which the bits are to be set.
  400. *
  401. * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
  402. * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
  403. * and bit 0 set uxBitsToSet to 0x09.
  404. *
  405. * @return The value of the event group at the time the call to
  406. * xEventGroupSetBits() returns. There are two reasons why the returned value
  407. * might have the bits specified by the uxBitsToSet parameter cleared. First,
  408. * if setting a bit results in a task that was waiting for the bit leaving the
  409. * blocked state then it is possible the bit will be cleared automatically
  410. * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any
  411. * unblocked (or otherwise Ready state) task that has a priority above that of
  412. * the task that called xEventGroupSetBits() will execute and may change the
  413. * event group value before the call to xEventGroupSetBits() returns.
  414. *
  415. * Example usage:
  416. <pre>
  417. #define BIT_0 ( 1 << 0 )
  418. #define BIT_4 ( 1 << 4 )
  419. void aFunction( EventGroupHandle_t xEventGroup )
  420. {
  421. EventBits_t uxBits;
  422. // Set bit 0 and bit 4 in xEventGroup.
  423. uxBits = xEventGroupSetBits(
  424. xEventGroup, // The event group being updated.
  425. BIT_0 | BIT_4 );// The bits being set.
  426. if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
  427. {
  428. // Both bit 0 and bit 4 remained set when the function returned.
  429. }
  430. else if( ( uxBits & BIT_0 ) != 0 )
  431. {
  432. // Bit 0 remained set when the function returned, but bit 4 was
  433. // cleared. It might be that bit 4 was cleared automatically as a
  434. // task that was waiting for bit 4 was removed from the Blocked
  435. // state.
  436. }
  437. else if( ( uxBits & BIT_4 ) != 0 )
  438. {
  439. // Bit 4 remained set when the function returned, but bit 0 was
  440. // cleared. It might be that bit 0 was cleared automatically as a
  441. // task that was waiting for bit 0 was removed from the Blocked
  442. // state.
  443. }
  444. else
  445. {
  446. // Neither bit 0 nor bit 4 remained set. It might be that a task
  447. // was waiting for both of the bits to be set, and the bits were
  448. // cleared as the task left the Blocked state.
  449. }
  450. }
  451. </pre>
  452. * \defgroup xEventGroupSetBits xEventGroupSetBits
  453. * \ingroup EventGroup
  454. */
  455. EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
  456. /**
  457. * event_groups.h
  458. *<pre>
  459. BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
  460. </pre>
  461. *
  462. * A version of xEventGroupSetBits() that can be called from an interrupt.
  463. *
  464. * Setting bits in an event group is not a deterministic operation because there
  465. * are an unknown number of tasks that may be waiting for the bit or bits being
  466. * set. FreeRTOS does not allow nondeterministic operations to be performed in
  467. * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR()
  468. * sends a message to the timer task to have the set operation performed in the
  469. * context of the timer task - where a scheduler lock is used in place of a
  470. * critical section.
  471. *
  472. * @param xEventGroup The event group in which the bits are to be set.
  473. *
  474. * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
  475. * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
  476. * and bit 0 set uxBitsToSet to 0x09.
  477. *
  478. * @param pxHigherPriorityTaskWoken As mentioned above, calling this function
  479. * will result in a message being sent to the timer daemon task. If the
  480. * priority of the timer daemon task is higher than the priority of the
  481. * currently running task (the task the interrupt interrupted) then
  482. * *pxHigherPriorityTaskWoken will be set to pdTRUE by
  483. * xEventGroupSetBitsFromISR(), indicating that a context switch should be
  484. * requested before the interrupt exits. For that reason
  485. * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the
  486. * example code below.
  487. *
  488. * @return If the request to execute the function was posted successfully then
  489. * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
  490. * if the timer service queue was full.
  491. *
  492. * Example usage:
  493. <pre>
  494. #define BIT_0 ( 1 << 0 )
  495. #define BIT_4 ( 1 << 4 )
  496. // An event group which it is assumed has already been created by a call to
  497. // xEventGroupCreate().
  498. EventGroupHandle_t xEventGroup;
  499. void anInterruptHandler( void )
  500. {
  501. BaseType_t xHigherPriorityTaskWoken, xResult;
  502. // xHigherPriorityTaskWoken must be initialised to pdFALSE.
  503. xHigherPriorityTaskWoken = pdFALSE;
  504. // Set bit 0 and bit 4 in xEventGroup.
  505. xResult = xEventGroupSetBitsFromISR(
  506. xEventGroup, // The event group being updated.
  507. BIT_0 | BIT_4 // The bits being set.
  508. &xHigherPriorityTaskWoken );
  509. // Was the message posted successfully?
  510. if( xResult == pdPASS )
  511. {
  512. // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
  513. // switch should be requested. The macro used is port specific and
  514. // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
  515. // refer to the documentation page for the port being used.
  516. portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
  517. }
  518. }
  519. </pre>
  520. * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
  521. * \ingroup EventGroup
  522. */
  523. #if( configUSE_TRACE_FACILITY == 1 )
  524. BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
  525. #else
  526. #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
  527. #endif
  528. /**
  529. * event_groups.h
  530. *<pre>
  531. EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
  532. const EventBits_t uxBitsToSet,
  533. const EventBits_t uxBitsToWaitFor,
  534. TickType_t xTicksToWait );
  535. </pre>
  536. *
  537. * Atomically set bits within an event group, then wait for a combination of
  538. * bits to be set within the same event group. This functionality is typically
  539. * used to synchronise multiple tasks, where each task has to wait for the other
  540. * tasks to reach a synchronisation point before proceeding.
  541. *
  542. * This function cannot be used from an interrupt.
  543. *
  544. * The function will return before its block time expires if the bits specified
  545. * by the uxBitsToWait parameter are set, or become set within that time. In
  546. * this case all the bits specified by uxBitsToWait will be automatically
  547. * cleared before the function returns.
  548. *
  549. * @param xEventGroup The event group in which the bits are being tested. The
  550. * event group must have previously been created using a call to
  551. * xEventGroupCreate().
  552. *
  553. * @param uxBitsToSet The bits to set in the event group before determining
  554. * if, and possibly waiting for, all the bits specified by the uxBitsToWait
  555. * parameter are set.
  556. *
  557. * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
  558. * inside the event group. For example, to wait for bit 0 and bit 2 set
  559. * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set
  560. * uxBitsToWaitFor to 0x07. Etc.
  561. *
  562. * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
  563. * for all of the bits specified by uxBitsToWaitFor to become set.
  564. *
  565. * @return The value of the event group at the time either the bits being waited
  566. * for became set, or the block time expired. Test the return value to know
  567. * which bits were set. If xEventGroupSync() returned because its timeout
  568. * expired then not all the bits being waited for will be set. If
  569. * xEventGroupSync() returned because all the bits it was waiting for were
  570. * set then the returned value is the event group value before any bits were
  571. * automatically cleared.
  572. *
  573. * Example usage:
  574. <pre>
  575. // Bits used by the three tasks.
  576. #define TASK_0_BIT ( 1 << 0 )
  577. #define TASK_1_BIT ( 1 << 1 )
  578. #define TASK_2_BIT ( 1 << 2 )
  579. #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
  580. // Use an event group to synchronise three tasks. It is assumed this event
  581. // group has already been created elsewhere.
  582. EventGroupHandle_t xEventBits;
  583. void vTask0( void *pvParameters )
  584. {
  585. EventBits_t uxReturn;
  586. TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
  587. for( ;; )
  588. {
  589. // Perform task functionality here.
  590. // Set bit 0 in the event flag to note this task has reached the
  591. // sync point. The other two tasks will set the other two bits defined
  592. // by ALL_SYNC_BITS. All three tasks have reached the synchronisation
  593. // point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
  594. // for this to happen.
  595. uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
  596. if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
  597. {
  598. // All three tasks reached the synchronisation point before the call
  599. // to xEventGroupSync() timed out.
  600. }
  601. }
  602. }
  603. void vTask1( void *pvParameters )
  604. {
  605. for( ;; )
  606. {
  607. // Perform task functionality here.
  608. // Set bit 1 in the event flag to note this task has reached the
  609. // synchronisation point. The other two tasks will set the other two
  610. // bits defined by ALL_SYNC_BITS. All three tasks have reached the
  611. // synchronisation point when all the ALL_SYNC_BITS are set. Wait
  612. // indefinitely for this to happen.
  613. xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
  614. // xEventGroupSync() was called with an indefinite block time, so
  615. // this task will only reach here if the syncrhonisation was made by all
  616. // three tasks, so there is no need to test the return value.
  617. }
  618. }
  619. void vTask2( void *pvParameters )
  620. {
  621. for( ;; )
  622. {
  623. // Perform task functionality here.
  624. // Set bit 2 in the event flag to note this task has reached the
  625. // synchronisation point. The other two tasks will set the other two
  626. // bits defined by ALL_SYNC_BITS. All three tasks have reached the
  627. // synchronisation point when all the ALL_SYNC_BITS are set. Wait
  628. // indefinitely for this to happen.
  629. xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
  630. // xEventGroupSync() was called with an indefinite block time, so
  631. // this task will only reach here if the syncrhonisation was made by all
  632. // three tasks, so there is no need to test the return value.
  633. }
  634. }
  635. </pre>
  636. * \defgroup xEventGroupSync xEventGroupSync
  637. * \ingroup EventGroup
  638. */
  639. EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
  640. /**
  641. * event_groups.h
  642. *<pre>
  643. EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
  644. </pre>
  645. *
  646. * Returns the current value of the bits in an event group. This function
  647. * cannot be used from an interrupt.
  648. *
  649. * @param xEventGroup The event group being queried.
  650. *
  651. * @return The event group bits at the time xEventGroupGetBits() was called.
  652. *
  653. * \defgroup xEventGroupGetBits xEventGroupGetBits
  654. * \ingroup EventGroup
  655. */
  656. #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
  657. /**
  658. * event_groups.h
  659. *<pre>
  660. EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
  661. </pre>
  662. *
  663. * A version of xEventGroupGetBits() that can be called from an ISR.
  664. *
  665. * @param xEventGroup The event group being queried.
  666. *
  667. * @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
  668. *
  669. * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
  670. * \ingroup EventGroup
  671. */
  672. EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
  673. /**
  674. * event_groups.h
  675. *<pre>
  676. void xEventGroupDelete( EventGroupHandle_t xEventGroup );
  677. </pre>
  678. *
  679. * Delete an event group that was previously created by a call to
  680. * xEventGroupCreate(). Tasks that are blocked on the event group will be
  681. * unblocked and obtain 0 as the event group's value.
  682. *
  683. * @param xEventGroup The event group being deleted.
  684. */
  685. void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
  686. /* For internal use only. */
  687. void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
  688. void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
  689. #if (configUSE_TRACE_FACILITY == 1)
  690. UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION;
  691. void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
  692. #endif
  693. #ifdef __cplusplus
  694. }
  695. #endif
  696. #endif /* EVENT_GROUPS_H */