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