STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
semphr.h
Go to the documentation of this file.
1
/*
2
* FreeRTOS Kernel V10.6.2
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
29
#ifndef SEMAPHORE_H
30
#define SEMAPHORE_H
31
32
#ifndef INC_FREERTOS_H
33
#error "include FreeRTOS.h" must appear in source files before "include semphr.h"
34
#endif
35
36
#include "
queue.h
"
37
38
typedef
QueueHandle_t
SemaphoreHandle_t
;
39
40
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U )
41
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )
42
#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U )
43
44
45
/**
46
* semphr. h
47
* @code{c}
48
* vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore );
49
* @endcode
50
*
51
* In many usage scenarios it is faster and more memory efficient to use a
52
* direct to task notification in place of a binary semaphore!
53
* https://www.FreeRTOS.org/RTOS-task-notifications.html
54
*
55
* This old vSemaphoreCreateBinary() macro is now deprecated in favour of the
56
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
57
* the vSemaphoreCreateBinary() macro are created in a state such that the
58
* first call to 'take' the semaphore would pass, whereas binary semaphores
59
* created using xSemaphoreCreateBinary() are created in a state such that the
60
* the semaphore must first be 'given' before it can be 'taken'.
61
*
62
* <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
63
* The queue length is 1 as this is a binary semaphore. The data size is 0
64
* as we don't want to actually store any data - we just want to know if the
65
* queue is empty or full.
66
*
67
* This type of semaphore can be used for pure synchronisation between tasks or
68
* between an interrupt and a task. The semaphore need not be given back once
69
* obtained, so one task/interrupt can continuously 'give' the semaphore while
70
* another continuously 'takes' the semaphore. For this reason this type of
71
* semaphore does not use a priority inheritance mechanism. For an alternative
72
* that does use priority inheritance see xSemaphoreCreateMutex().
73
*
74
* @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t.
75
*
76
* Example usage:
77
* @code{c}
78
* SemaphoreHandle_t xSemaphore = NULL;
79
*
80
* void vATask( void * pvParameters )
81
* {
82
* // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
83
* // This is a macro so pass the variable in directly.
84
* vSemaphoreCreateBinary( xSemaphore );
85
*
86
* if( xSemaphore != NULL )
87
* {
88
* // The semaphore was created successfully.
89
* // The semaphore can now be used.
90
* }
91
* }
92
* @endcode
93
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
94
* \ingroup Semaphores
95
*/
96
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
97
#define vSemaphoreCreateBinary( xSemaphore ) \
98
do { \
99
( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
100
if( ( xSemaphore ) != NULL ) \
101
{ \
102
( void ) xSemaphoreGive( ( xSemaphore ) ); \
103
} \
104
} while( 0 )
105
#endif
106
107
/**
108
* semphr. h
109
* @code{c}
110
* SemaphoreHandle_t xSemaphoreCreateBinary( void );
111
* @endcode
112
*
113
* Creates a new binary semaphore instance, and returns a handle by which the
114
* new semaphore can be referenced.
115
*
116
* In many usage scenarios it is faster and more memory efficient to use a
117
* direct to task notification in place of a binary semaphore!
118
* https://www.FreeRTOS.org/RTOS-task-notifications.html
119
*
120
* Internally, within the FreeRTOS implementation, binary semaphores use a block
121
* of memory, in which the semaphore structure is stored. If a binary semaphore
122
* is created using xSemaphoreCreateBinary() then the required memory is
123
* automatically dynamically allocated inside the xSemaphoreCreateBinary()
124
* function. (see https://www.FreeRTOS.org/a00111.html). If a binary semaphore
125
* is created using xSemaphoreCreateBinaryStatic() then the application writer
126
* must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a
127
* binary semaphore to be created without using any dynamic memory allocation.
128
*
129
* The old vSemaphoreCreateBinary() macro is now deprecated in favour of this
130
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
131
* the vSemaphoreCreateBinary() macro are created in a state such that the
132
* first call to 'take' the semaphore would pass, whereas binary semaphores
133
* created using xSemaphoreCreateBinary() are created in a state such that the
134
* the semaphore must first be 'given' before it can be 'taken'.
135
*
136
* This type of semaphore can be used for pure synchronisation between tasks or
137
* between an interrupt and a task. The semaphore need not be given back once
138
* obtained, so one task/interrupt can continuously 'give' the semaphore while
139
* another continuously 'takes' the semaphore. For this reason this type of
140
* semaphore does not use a priority inheritance mechanism. For an alternative
141
* that does use priority inheritance see xSemaphoreCreateMutex().
142
*
143
* @return Handle to the created semaphore, or NULL if the memory required to
144
* hold the semaphore's data structures could not be allocated.
145
*
146
* Example usage:
147
* @code{c}
148
* SemaphoreHandle_t xSemaphore = NULL;
149
*
150
* void vATask( void * pvParameters )
151
* {
152
* // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
153
* // This is a macro so pass the variable in directly.
154
* xSemaphore = xSemaphoreCreateBinary();
155
*
156
* if( xSemaphore != NULL )
157
* {
158
* // The semaphore was created successfully.
159
* // The semaphore can now be used.
160
* }
161
* }
162
* @endcode
163
* \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary
164
* \ingroup Semaphores
165
*/
166
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
167
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
168
#endif
169
170
/**
171
* semphr. h
172
* @code{c}
173
* SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer );
174
* @endcode
175
*
176
* Creates a new binary semaphore instance, and returns a handle by which the
177
* new semaphore can be referenced.
178
*
179
* NOTE: In many usage scenarios it is faster and more memory efficient to use a
180
* direct to task notification in place of a binary semaphore!
181
* https://www.FreeRTOS.org/RTOS-task-notifications.html
182
*
183
* Internally, within the FreeRTOS implementation, binary semaphores use a block
184
* of memory, in which the semaphore structure is stored. If a binary semaphore
185
* is created using xSemaphoreCreateBinary() then the required memory is
186
* automatically dynamically allocated inside the xSemaphoreCreateBinary()
187
* function. (see https://www.FreeRTOS.org/a00111.html). If a binary semaphore
188
* is created using xSemaphoreCreateBinaryStatic() then the application writer
189
* must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a
190
* binary semaphore to be created without using any dynamic memory allocation.
191
*
192
* This type of semaphore can be used for pure synchronisation between tasks or
193
* between an interrupt and a task. The semaphore need not be given back once
194
* obtained, so one task/interrupt can continuously 'give' the semaphore while
195
* another continuously 'takes' the semaphore. For this reason this type of
196
* semaphore does not use a priority inheritance mechanism. For an alternative
197
* that does use priority inheritance see xSemaphoreCreateMutex().
198
*
199
* @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,
200
* which will then be used to hold the semaphore's data structure, removing the
201
* need for the memory to be allocated dynamically.
202
*
203
* @return If the semaphore is created then a handle to the created semaphore is
204
* returned. If pxSemaphoreBuffer is NULL then NULL is returned.
205
*
206
* Example usage:
207
* @code{c}
208
* SemaphoreHandle_t xSemaphore = NULL;
209
* StaticSemaphore_t xSemaphoreBuffer;
210
*
211
* void vATask( void * pvParameters )
212
* {
213
* // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
214
* // The semaphore's data structures will be placed in the xSemaphoreBuffer
215
* // variable, the address of which is passed into the function. The
216
* // function's parameter is not NULL, so the function will not attempt any
217
* // dynamic memory allocation, and therefore the function will not return
218
* // return NULL.
219
* xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
220
*
221
* // Rest of task code goes here.
222
* }
223
* @endcode
224
* \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic
225
* \ingroup Semaphores
226
*/
227
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
228
#define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, ( pxStaticSemaphore ), queueQUEUE_TYPE_BINARY_SEMAPHORE )
229
#endif
/* configSUPPORT_STATIC_ALLOCATION */
230
231
/**
232
* semphr. h
233
* @code{c}
234
* xSemaphoreTake(
235
* SemaphoreHandle_t xSemaphore,
236
* TickType_t xBlockTime
237
* );
238
* @endcode
239
*
240
* <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
241
* created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
242
* xSemaphoreCreateCounting().
243
*
244
* @param xSemaphore A handle to the semaphore being taken - obtained when
245
* the semaphore was created.
246
*
247
* @param xBlockTime The time in ticks to wait for the semaphore to become
248
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
249
* real time. A block time of zero can be used to poll the semaphore. A block
250
* time of portMAX_DELAY can be used to block indefinitely (provided
251
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
252
*
253
* @return pdTRUE if the semaphore was obtained. pdFALSE
254
* if xBlockTime expired without the semaphore becoming available.
255
*
256
* Example usage:
257
* @code{c}
258
* SemaphoreHandle_t xSemaphore = NULL;
259
*
260
* // A task that creates a semaphore.
261
* void vATask( void * pvParameters )
262
* {
263
* // Create the semaphore to guard a shared resource.
264
* xSemaphore = xSemaphoreCreateBinary();
265
* }
266
*
267
* // A task that uses the semaphore.
268
* void vAnotherTask( void * pvParameters )
269
* {
270
* // ... Do other things.
271
*
272
* if( xSemaphore != NULL )
273
* {
274
* // See if we can obtain the semaphore. If the semaphore is not available
275
* // wait 10 ticks to see if it becomes free.
276
* if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
277
* {
278
* // We were able to obtain the semaphore and can now access the
279
* // shared resource.
280
*
281
* // ...
282
*
283
* // We have finished accessing the shared resource. Release the
284
* // semaphore.
285
* xSemaphoreGive( xSemaphore );
286
* }
287
* else
288
* {
289
* // We could not obtain the semaphore and can therefore not access
290
* // the shared resource safely.
291
* }
292
* }
293
* }
294
* @endcode
295
* \defgroup xSemaphoreTake xSemaphoreTake
296
* \ingroup Semaphores
297
*/
298
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
299
300
/**
301
* semphr. h
302
* @code{c}
303
* xSemaphoreTakeRecursive(
304
* SemaphoreHandle_t xMutex,
305
* TickType_t xBlockTime
306
* );
307
* @endcode
308
*
309
* <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
310
* The mutex must have previously been created using a call to
311
* xSemaphoreCreateRecursiveMutex();
312
*
313
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
314
* macro to be available.
315
*
316
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
317
*
318
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
319
* doesn't become available again until the owner has called
320
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
321
* if a task successfully 'takes' the same mutex 5 times then the mutex will
322
* not be available to any other task until it has also 'given' the mutex back
323
* exactly five times.
324
*
325
* @param xMutex A handle to the mutex being obtained. This is the
326
* handle returned by xSemaphoreCreateRecursiveMutex();
327
*
328
* @param xBlockTime The time in ticks to wait for the semaphore to become
329
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
330
* real time. A block time of zero can be used to poll the semaphore. If
331
* the task already owns the semaphore then xSemaphoreTakeRecursive() will
332
* return immediately no matter what the value of xBlockTime.
333
*
334
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
335
* expired without the semaphore becoming available.
336
*
337
* Example usage:
338
* @code{c}
339
* SemaphoreHandle_t xMutex = NULL;
340
*
341
* // A task that creates a mutex.
342
* void vATask( void * pvParameters )
343
* {
344
* // Create the mutex to guard a shared resource.
345
* xMutex = xSemaphoreCreateRecursiveMutex();
346
* }
347
*
348
* // A task that uses the mutex.
349
* void vAnotherTask( void * pvParameters )
350
* {
351
* // ... Do other things.
352
*
353
* if( xMutex != NULL )
354
* {
355
* // See if we can obtain the mutex. If the mutex is not available
356
* // wait 10 ticks to see if it becomes free.
357
* if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
358
* {
359
* // We were able to obtain the mutex and can now access the
360
* // shared resource.
361
*
362
* // ...
363
* // For some reason due to the nature of the code further calls to
364
* // xSemaphoreTakeRecursive() are made on the same mutex. In real
365
* // code these would not be just sequential calls as this would make
366
* // no sense. Instead the calls are likely to be buried inside
367
* // a more complex call structure.
368
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
369
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
370
*
371
* // The mutex has now been 'taken' three times, so will not be
372
* // available to another task until it has also been given back
373
* // three times. Again it is unlikely that real code would have
374
* // these calls sequentially, but instead buried in a more complex
375
* // call structure. This is just for illustrative purposes.
376
* xSemaphoreGiveRecursive( xMutex );
377
* xSemaphoreGiveRecursive( xMutex );
378
* xSemaphoreGiveRecursive( xMutex );
379
*
380
* // Now the mutex can be taken by other tasks.
381
* }
382
* else
383
* {
384
* // We could not obtain the mutex and can therefore not access
385
* // the shared resource safely.
386
* }
387
* }
388
* }
389
* @endcode
390
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
391
* \ingroup Semaphores
392
*/
393
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
394
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
395
#endif
396
397
/**
398
* semphr. h
399
* @code{c}
400
* xSemaphoreGive( SemaphoreHandle_t xSemaphore );
401
* @endcode
402
*
403
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
404
* created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
405
* xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
406
*
407
* This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
408
* an alternative which can be used from an ISR.
409
*
410
* This macro must also not be used on semaphores created using
411
* xSemaphoreCreateRecursiveMutex().
412
*
413
* @param xSemaphore A handle to the semaphore being released. This is the
414
* handle returned when the semaphore was created.
415
*
416
* @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
417
* Semaphores are implemented using queues. An error can occur if there is
418
* no space on the queue to post a message - indicating that the
419
* semaphore was not first obtained correctly.
420
*
421
* Example usage:
422
* @code{c}
423
* SemaphoreHandle_t xSemaphore = NULL;
424
*
425
* void vATask( void * pvParameters )
426
* {
427
* // Create the semaphore to guard a shared resource.
428
* xSemaphore = vSemaphoreCreateBinary();
429
*
430
* if( xSemaphore != NULL )
431
* {
432
* if( xSemaphoreGive( xSemaphore ) != pdTRUE )
433
* {
434
* // We would expect this call to fail because we cannot give
435
* // a semaphore without first "taking" it!
436
* }
437
*
438
* // Obtain the semaphore - don't block if the semaphore is not
439
* // immediately available.
440
* if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
441
* {
442
* // We now have the semaphore and can access the shared resource.
443
*
444
* // ...
445
*
446
* // We have finished accessing the shared resource so can free the
447
* // semaphore.
448
* if( xSemaphoreGive( xSemaphore ) != pdTRUE )
449
* {
450
* // We would not expect this call to fail because we must have
451
* // obtained the semaphore to get here.
452
* }
453
* }
454
* }
455
* }
456
* @endcode
457
* \defgroup xSemaphoreGive xSemaphoreGive
458
* \ingroup Semaphores
459
*/
460
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
461
462
/**
463
* semphr. h
464
* @code{c}
465
* xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex );
466
* @endcode
467
*
468
* <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
469
* The mutex must have previously been created using a call to
470
* xSemaphoreCreateRecursiveMutex();
471
*
472
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
473
* macro to be available.
474
*
475
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
476
*
477
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
478
* doesn't become available again until the owner has called
479
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
480
* if a task successfully 'takes' the same mutex 5 times then the mutex will
481
* not be available to any other task until it has also 'given' the mutex back
482
* exactly five times.
483
*
484
* @param xMutex A handle to the mutex being released, or 'given'. This is the
485
* handle returned by xSemaphoreCreateMutex();
486
*
487
* @return pdTRUE if the semaphore was given.
488
*
489
* Example usage:
490
* @code{c}
491
* SemaphoreHandle_t xMutex = NULL;
492
*
493
* // A task that creates a mutex.
494
* void vATask( void * pvParameters )
495
* {
496
* // Create the mutex to guard a shared resource.
497
* xMutex = xSemaphoreCreateRecursiveMutex();
498
* }
499
*
500
* // A task that uses the mutex.
501
* void vAnotherTask( void * pvParameters )
502
* {
503
* // ... Do other things.
504
*
505
* if( xMutex != NULL )
506
* {
507
* // See if we can obtain the mutex. If the mutex is not available
508
* // wait 10 ticks to see if it becomes free.
509
* if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
510
* {
511
* // We were able to obtain the mutex and can now access the
512
* // shared resource.
513
*
514
* // ...
515
* // For some reason due to the nature of the code further calls to
516
* // xSemaphoreTakeRecursive() are made on the same mutex. In real
517
* // code these would not be just sequential calls as this would make
518
* // no sense. Instead the calls are likely to be buried inside
519
* // a more complex call structure.
520
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
521
* xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
522
*
523
* // The mutex has now been 'taken' three times, so will not be
524
* // available to another task until it has also been given back
525
* // three times. Again it is unlikely that real code would have
526
* // these calls sequentially, it would be more likely that the calls
527
* // to xSemaphoreGiveRecursive() would be called as a call stack
528
* // unwound. This is just for demonstrative purposes.
529
* xSemaphoreGiveRecursive( xMutex );
530
* xSemaphoreGiveRecursive( xMutex );
531
* xSemaphoreGiveRecursive( xMutex );
532
*
533
* // Now the mutex can be taken by other tasks.
534
* }
535
* else
536
* {
537
* // We could not obtain the mutex and can therefore not access
538
* // the shared resource safely.
539
* }
540
* }
541
* }
542
* @endcode
543
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
544
* \ingroup Semaphores
545
*/
546
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
547
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
548
#endif
549
550
/**
551
* semphr. h
552
* @code{c}
553
* xSemaphoreGiveFromISR(
554
* SemaphoreHandle_t xSemaphore,
555
* BaseType_t *pxHigherPriorityTaskWoken
556
* );
557
* @endcode
558
*
559
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
560
* created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting().
561
*
562
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
563
* must not be used with this macro.
564
*
565
* This macro can be used from an ISR.
566
*
567
* @param xSemaphore A handle to the semaphore being released. This is the
568
* handle returned when the semaphore was created.
569
*
570
* @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
571
* *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
572
* to unblock, and the unblocked task has a priority higher than the currently
573
* running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then
574
* a context switch should be requested before the interrupt is exited.
575
*
576
* @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
577
*
578
* Example usage:
579
* @code{c}
580
\#define LONG_TIME 0xffff
581
\#define TICKS_TO_WAIT 10
582
* SemaphoreHandle_t xSemaphore = NULL;
583
*
584
* // Repetitive task.
585
* void vATask( void * pvParameters )
586
* {
587
* for( ;; )
588
* {
589
* // We want this task to run every 10 ticks of a timer. The semaphore
590
* // was created before this task was started.
591
*
592
* // Block waiting for the semaphore to become available.
593
* if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
594
* {
595
* // It is time to execute.
596
*
597
* // ...
598
*
599
* // We have finished our task. Return to the top of the loop where
600
* // we will block on the semaphore until it is time to execute
601
* // again. Note when using the semaphore for synchronisation with an
602
* // ISR in this manner there is no need to 'give' the semaphore back.
603
* }
604
* }
605
* }
606
*
607
* // Timer ISR
608
* void vTimerISR( void * pvParameters )
609
* {
610
* static uint8_t ucLocalTickCount = 0;
611
* static BaseType_t xHigherPriorityTaskWoken;
612
*
613
* // A timer tick has occurred.
614
*
615
* // ... Do other time functions.
616
*
617
* // Is it time for vATask () to run?
618
* xHigherPriorityTaskWoken = pdFALSE;
619
* ucLocalTickCount++;
620
* if( ucLocalTickCount >= TICKS_TO_WAIT )
621
* {
622
* // Unblock the task by releasing the semaphore.
623
* xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
624
*
625
* // Reset the count so we release the semaphore again in 10 ticks time.
626
* ucLocalTickCount = 0;
627
* }
628
*
629
* if( xHigherPriorityTaskWoken != pdFALSE )
630
* {
631
* // We can force a context switch here. Context switching from an
632
* // ISR uses port specific syntax. Check the demo task for your port
633
* // to find the syntax required.
634
* }
635
* }
636
* @endcode
637
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
638
* \ingroup Semaphores
639
*/
640
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) )
641
642
/**
643
* semphr. h
644
* @code{c}
645
* xSemaphoreTakeFromISR(
646
* SemaphoreHandle_t xSemaphore,
647
* BaseType_t *pxHigherPriorityTaskWoken
648
* );
649
* @endcode
650
*
651
* <i>Macro</i> to take a semaphore from an ISR. The semaphore must have
652
* previously been created with a call to xSemaphoreCreateBinary() or
653
* xSemaphoreCreateCounting().
654
*
655
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
656
* must not be used with this macro.
657
*
658
* This macro can be used from an ISR, however taking a semaphore from an ISR
659
* is not a common operation. It is likely to only be useful when taking a
660
* counting semaphore when an interrupt is obtaining an object from a resource
661
* pool (when the semaphore count indicates the number of resources available).
662
*
663
* @param xSemaphore A handle to the semaphore being taken. This is the
664
* handle returned when the semaphore was created.
665
*
666
* @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set
667
* *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task
668
* to unblock, and the unblocked task has a priority higher than the currently
669
* running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then
670
* a context switch should be requested before the interrupt is exited.
671
*
672
* @return pdTRUE if the semaphore was successfully taken, otherwise
673
* pdFALSE
674
*/
675
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )
676
677
/**
678
* semphr. h
679
* @code{c}
680
* SemaphoreHandle_t xSemaphoreCreateMutex( void );
681
* @endcode
682
*
683
* Creates a new mutex type semaphore instance, and returns a handle by which
684
* the new mutex can be referenced.
685
*
686
* Internally, within the FreeRTOS implementation, mutex semaphores use a block
687
* of memory, in which the mutex structure is stored. If a mutex is created
688
* using xSemaphoreCreateMutex() then the required memory is automatically
689
* dynamically allocated inside the xSemaphoreCreateMutex() function. (see
690
* https://www.FreeRTOS.org/a00111.html). If a mutex is created using
691
* xSemaphoreCreateMutexStatic() then the application writer must provided the
692
* memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created
693
* without using any dynamic memory allocation.
694
*
695
* Mutexes created using this function can be accessed using the xSemaphoreTake()
696
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
697
* xSemaphoreGiveRecursive() macros must not be used.
698
*
699
* This type of semaphore uses a priority inheritance mechanism so a task
700
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
701
* semaphore it is no longer required.
702
*
703
* Mutex type semaphores cannot be used from within interrupt service routines.
704
*
705
* See xSemaphoreCreateBinary() for an alternative implementation that can be
706
* used for pure synchronisation (where one task or interrupt always 'gives' the
707
* semaphore and another always 'takes' the semaphore) and from within interrupt
708
* service routines.
709
*
710
* @return If the mutex was successfully created then a handle to the created
711
* semaphore is returned. If there was not enough heap to allocate the mutex
712
* data structures then NULL is returned.
713
*
714
* Example usage:
715
* @code{c}
716
* SemaphoreHandle_t xSemaphore;
717
*
718
* void vATask( void * pvParameters )
719
* {
720
* // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
721
* // This is a macro so pass the variable in directly.
722
* xSemaphore = xSemaphoreCreateMutex();
723
*
724
* if( xSemaphore != NULL )
725
* {
726
* // The semaphore was created successfully.
727
* // The semaphore can now be used.
728
* }
729
* }
730
* @endcode
731
* \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex
732
* \ingroup Semaphores
733
*/
734
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_MUTEXES == 1 ) )
735
#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
736
#endif
737
738
/**
739
* semphr. h
740
* @code{c}
741
* SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer );
742
* @endcode
743
*
744
* Creates a new mutex type semaphore instance, and returns a handle by which
745
* the new mutex can be referenced.
746
*
747
* Internally, within the FreeRTOS implementation, mutex semaphores use a block
748
* of memory, in which the mutex structure is stored. If a mutex is created
749
* using xSemaphoreCreateMutex() then the required memory is automatically
750
* dynamically allocated inside the xSemaphoreCreateMutex() function. (see
751
* https://www.FreeRTOS.org/a00111.html). If a mutex is created using
752
* xSemaphoreCreateMutexStatic() then the application writer must provided the
753
* memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created
754
* without using any dynamic memory allocation.
755
*
756
* Mutexes created using this function can be accessed using the xSemaphoreTake()
757
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
758
* xSemaphoreGiveRecursive() macros must not be used.
759
*
760
* This type of semaphore uses a priority inheritance mechanism so a task
761
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
762
* semaphore it is no longer required.
763
*
764
* Mutex type semaphores cannot be used from within interrupt service routines.
765
*
766
* See xSemaphoreCreateBinary() for an alternative implementation that can be
767
* used for pure synchronisation (where one task or interrupt always 'gives' the
768
* semaphore and another always 'takes' the semaphore) and from within interrupt
769
* service routines.
770
*
771
* @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,
772
* which will be used to hold the mutex's data structure, removing the need for
773
* the memory to be allocated dynamically.
774
*
775
* @return If the mutex was successfully created then a handle to the created
776
* mutex is returned. If pxMutexBuffer was NULL then NULL is returned.
777
*
778
* Example usage:
779
* @code{c}
780
* SemaphoreHandle_t xSemaphore;
781
* StaticSemaphore_t xMutexBuffer;
782
*
783
* void vATask( void * pvParameters )
784
* {
785
* // A mutex cannot be used before it has been created. xMutexBuffer is
786
* // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
787
* // attempted.
788
* xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
789
*
790
* // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
791
* // so there is no need to check it.
792
* }
793
* @endcode
794
* \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic
795
* \ingroup Semaphores
796
*/
797
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_MUTEXES == 1 ) )
798
#define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) )
799
#endif
800
801
802
/**
803
* semphr. h
804
* @code{c}
805
* SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void );
806
* @endcode
807
*
808
* Creates a new recursive mutex type semaphore instance, and returns a handle
809
* by which the new recursive mutex can be referenced.
810
*
811
* Internally, within the FreeRTOS implementation, recursive mutexes use a block
812
* of memory, in which the mutex structure is stored. If a recursive mutex is
813
* created using xSemaphoreCreateRecursiveMutex() then the required memory is
814
* automatically dynamically allocated inside the
815
* xSemaphoreCreateRecursiveMutex() function. (see
816
* https://www.FreeRTOS.org/a00111.html). If a recursive mutex is created using
817
* xSemaphoreCreateRecursiveMutexStatic() then the application writer must
818
* provide the memory that will get used by the mutex.
819
* xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to
820
* be created without using any dynamic memory allocation.
821
*
822
* Mutexes created using this macro can be accessed using the
823
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
824
* xSemaphoreTake() and xSemaphoreGive() macros must not be used.
825
*
826
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
827
* doesn't become available again until the owner has called
828
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
829
* if a task successfully 'takes' the same mutex 5 times then the mutex will
830
* not be available to any other task until it has also 'given' the mutex back
831
* exactly five times.
832
*
833
* This type of semaphore uses a priority inheritance mechanism so a task
834
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
835
* semaphore it is no longer required.
836
*
837
* Mutex type semaphores cannot be used from within interrupt service routines.
838
*
839
* See xSemaphoreCreateBinary() for an alternative implementation that can be
840
* used for pure synchronisation (where one task or interrupt always 'gives' the
841
* semaphore and another always 'takes' the semaphore) and from within interrupt
842
* service routines.
843
*
844
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
845
* SemaphoreHandle_t.
846
*
847
* Example usage:
848
* @code{c}
849
* SemaphoreHandle_t xSemaphore;
850
*
851
* void vATask( void * pvParameters )
852
* {
853
* // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
854
* // This is a macro so pass the variable in directly.
855
* xSemaphore = xSemaphoreCreateRecursiveMutex();
856
*
857
* if( xSemaphore != NULL )
858
* {
859
* // The semaphore was created successfully.
860
* // The semaphore can now be used.
861
* }
862
* }
863
* @endcode
864
* \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex
865
* \ingroup Semaphores
866
*/
867
#if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
868
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
869
#endif
870
871
/**
872
* semphr. h
873
* @code{c}
874
* SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer );
875
* @endcode
876
*
877
* Creates a new recursive mutex type semaphore instance, and returns a handle
878
* by which the new recursive mutex can be referenced.
879
*
880
* Internally, within the FreeRTOS implementation, recursive mutexes use a block
881
* of memory, in which the mutex structure is stored. If a recursive mutex is
882
* created using xSemaphoreCreateRecursiveMutex() then the required memory is
883
* automatically dynamically allocated inside the
884
* xSemaphoreCreateRecursiveMutex() function. (see
885
* https://www.FreeRTOS.org/a00111.html). If a recursive mutex is created using
886
* xSemaphoreCreateRecursiveMutexStatic() then the application writer must
887
* provide the memory that will get used by the mutex.
888
* xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to
889
* be created without using any dynamic memory allocation.
890
*
891
* Mutexes created using this macro can be accessed using the
892
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
893
* xSemaphoreTake() and xSemaphoreGive() macros must not be used.
894
*
895
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
896
* doesn't become available again until the owner has called
897
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
898
* if a task successfully 'takes' the same mutex 5 times then the mutex will
899
* not be available to any other task until it has also 'given' the mutex back
900
* exactly five times.
901
*
902
* This type of semaphore uses a priority inheritance mechanism so a task
903
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
904
* semaphore it is no longer required.
905
*
906
* Mutex type semaphores cannot be used from within interrupt service routines.
907
*
908
* See xSemaphoreCreateBinary() for an alternative implementation that can be
909
* used for pure synchronisation (where one task or interrupt always 'gives' the
910
* semaphore and another always 'takes' the semaphore) and from within interrupt
911
* service routines.
912
*
913
* @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t,
914
* which will then be used to hold the recursive mutex's data structure,
915
* removing the need for the memory to be allocated dynamically.
916
*
917
* @return If the recursive mutex was successfully created then a handle to the
918
* created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is
919
* returned.
920
*
921
* Example usage:
922
* @code{c}
923
* SemaphoreHandle_t xSemaphore;
924
* StaticSemaphore_t xMutexBuffer;
925
*
926
* void vATask( void * pvParameters )
927
* {
928
* // A recursive semaphore cannot be used before it is created. Here a
929
* // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
930
* // The address of xMutexBuffer is passed into the function, and will hold
931
* // the mutexes data structures - so no dynamic memory allocation will be
932
* // attempted.
933
* xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
934
*
935
* // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
936
* // so there is no need to check it.
937
* }
938
* @endcode
939
* \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic
940
* \ingroup Semaphores
941
*/
942
#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) )
943
#define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, ( pxStaticSemaphore ) )
944
#endif
/* configSUPPORT_STATIC_ALLOCATION */
945
946
/**
947
* semphr. h
948
* @code{c}
949
* SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount );
950
* @endcode
951
*
952
* Creates a new counting semaphore instance, and returns a handle by which the
953
* new counting semaphore can be referenced.
954
*
955
* In many usage scenarios it is faster and more memory efficient to use a
956
* direct to task notification in place of a counting semaphore!
957
* https://www.FreeRTOS.org/RTOS-task-notifications.html
958
*
959
* Internally, within the FreeRTOS implementation, counting semaphores use a
960
* block of memory, in which the counting semaphore structure is stored. If a
961
* counting semaphore is created using xSemaphoreCreateCounting() then the
962
* required memory is automatically dynamically allocated inside the
963
* xSemaphoreCreateCounting() function. (see
964
* https://www.FreeRTOS.org/a00111.html). If a counting semaphore is created
965
* using xSemaphoreCreateCountingStatic() then the application writer can
966
* instead optionally provide the memory that will get used by the counting
967
* semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting
968
* semaphore to be created without using any dynamic memory allocation.
969
*
970
* Counting semaphores are typically used for two things:
971
*
972
* 1) Counting events.
973
*
974
* In this usage scenario an event handler will 'give' a semaphore each time
975
* an event occurs (incrementing the semaphore count value), and a handler
976
* task will 'take' a semaphore each time it processes an event
977
* (decrementing the semaphore count value). The count value is therefore
978
* the difference between the number of events that have occurred and the
979
* number that have been processed. In this case it is desirable for the
980
* initial count value to be zero.
981
*
982
* 2) Resource management.
983
*
984
* In this usage scenario the count value indicates the number of resources
985
* available. To obtain control of a resource a task must first obtain a
986
* semaphore - decrementing the semaphore count value. When the count value
987
* reaches zero there are no free resources. When a task finishes with the
988
* resource it 'gives' the semaphore back - incrementing the semaphore count
989
* value. In this case it is desirable for the initial count value to be
990
* equal to the maximum count value, indicating that all resources are free.
991
*
992
* @param uxMaxCount The maximum count value that can be reached. When the
993
* semaphore reaches this value it can no longer be 'given'.
994
*
995
* @param uxInitialCount The count value assigned to the semaphore when it is
996
* created.
997
*
998
* @return Handle to the created semaphore. Null if the semaphore could not be
999
* created.
1000
*
1001
* Example usage:
1002
* @code{c}
1003
* SemaphoreHandle_t xSemaphore;
1004
*
1005
* void vATask( void * pvParameters )
1006
* {
1007
* SemaphoreHandle_t xSemaphore = NULL;
1008
*
1009
* // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
1010
* // The max value to which the semaphore can count should be 10, and the
1011
* // initial value assigned to the count should be 0.
1012
* xSemaphore = xSemaphoreCreateCounting( 10, 0 );
1013
*
1014
* if( xSemaphore != NULL )
1015
* {
1016
* // The semaphore was created successfully.
1017
* // The semaphore can now be used.
1018
* }
1019
* }
1020
* @endcode
1021
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
1022
* \ingroup Semaphores
1023
*/
1024
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
1025
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
1026
#endif
1027
1028
/**
1029
* semphr. h
1030
* @code{c}
1031
* SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer );
1032
* @endcode
1033
*
1034
* Creates a new counting semaphore instance, and returns a handle by which the
1035
* new counting semaphore can be referenced.
1036
*
1037
* In many usage scenarios it is faster and more memory efficient to use a
1038
* direct to task notification in place of a counting semaphore!
1039
* https://www.FreeRTOS.org/RTOS-task-notifications.html
1040
*
1041
* Internally, within the FreeRTOS implementation, counting semaphores use a
1042
* block of memory, in which the counting semaphore structure is stored. If a
1043
* counting semaphore is created using xSemaphoreCreateCounting() then the
1044
* required memory is automatically dynamically allocated inside the
1045
* xSemaphoreCreateCounting() function. (see
1046
* https://www.FreeRTOS.org/a00111.html). If a counting semaphore is created
1047
* using xSemaphoreCreateCountingStatic() then the application writer must
1048
* provide the memory. xSemaphoreCreateCountingStatic() therefore allows a
1049
* counting semaphore to be created without using any dynamic memory allocation.
1050
*
1051
* Counting semaphores are typically used for two things:
1052
*
1053
* 1) Counting events.
1054
*
1055
* In this usage scenario an event handler will 'give' a semaphore each time
1056
* an event occurs (incrementing the semaphore count value), and a handler
1057
* task will 'take' a semaphore each time it processes an event
1058
* (decrementing the semaphore count value). The count value is therefore
1059
* the difference between the number of events that have occurred and the
1060
* number that have been processed. In this case it is desirable for the
1061
* initial count value to be zero.
1062
*
1063
* 2) Resource management.
1064
*
1065
* In this usage scenario the count value indicates the number of resources
1066
* available. To obtain control of a resource a task must first obtain a
1067
* semaphore - decrementing the semaphore count value. When the count value
1068
* reaches zero there are no free resources. When a task finishes with the
1069
* resource it 'gives' the semaphore back - incrementing the semaphore count
1070
* value. In this case it is desirable for the initial count value to be
1071
* equal to the maximum count value, indicating that all resources are free.
1072
*
1073
* @param uxMaxCount The maximum count value that can be reached. When the
1074
* semaphore reaches this value it can no longer be 'given'.
1075
*
1076
* @param uxInitialCount The count value assigned to the semaphore when it is
1077
* created.
1078
*
1079
* @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t,
1080
* which will then be used to hold the semaphore's data structure, removing the
1081
* need for the memory to be allocated dynamically.
1082
*
1083
* @return If the counting semaphore was successfully created then a handle to
1084
* the created counting semaphore is returned. If pxSemaphoreBuffer was NULL
1085
* then NULL is returned.
1086
*
1087
* Example usage:
1088
* @code{c}
1089
* SemaphoreHandle_t xSemaphore;
1090
* StaticSemaphore_t xSemaphoreBuffer;
1091
*
1092
* void vATask( void * pvParameters )
1093
* {
1094
* SemaphoreHandle_t xSemaphore = NULL;
1095
*
1096
* // Counting semaphore cannot be used before they have been created. Create
1097
* // a counting semaphore using xSemaphoreCreateCountingStatic(). The max
1098
* // value to which the semaphore can count is 10, and the initial value
1099
* // assigned to the count will be 0. The address of xSemaphoreBuffer is
1100
* // passed in and will be used to hold the semaphore structure, so no dynamic
1101
* // memory allocation will be used.
1102
* xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
1103
*
1104
* // No memory allocation was attempted so xSemaphore cannot be NULL, so there
1105
* // is no need to check its value.
1106
* }
1107
* @endcode
1108
* \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic
1109
* \ingroup Semaphores
1110
*/
1111
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
1112
#define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) )
1113
#endif
/* configSUPPORT_STATIC_ALLOCATION */
1114
1115
/**
1116
* semphr. h
1117
* @code{c}
1118
* void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
1119
* @endcode
1120
*
1121
* Delete a semaphore. This function must be used with care. For example,
1122
* do not delete a mutex type semaphore if the mutex is held by a task.
1123
*
1124
* @param xSemaphore A handle to the semaphore to be deleted.
1125
*
1126
* \defgroup vSemaphoreDelete vSemaphoreDelete
1127
* \ingroup Semaphores
1128
*/
1129
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )
1130
1131
/**
1132
* semphr.h
1133
* @code{c}
1134
* TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
1135
* @endcode
1136
*
1137
* If xMutex is indeed a mutex type semaphore, return the current mutex holder.
1138
* If xMutex is not a mutex type semaphore, or the mutex is available (not held
1139
* by a task), return NULL.
1140
*
1141
* Note: This is a good way of determining if the calling task is the mutex
1142
* holder, but not a good way of determining the identity of the mutex holder as
1143
* the holder may change between the function exiting and the returned value
1144
* being tested.
1145
*/
1146
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
1147
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
1148
#endif
1149
1150
/**
1151
* semphr.h
1152
* @code{c}
1153
* TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );
1154
* @endcode
1155
*
1156
* If xMutex is indeed a mutex type semaphore, return the current mutex holder.
1157
* If xMutex is not a mutex type semaphore, or the mutex is available (not held
1158
* by a task), return NULL.
1159
*
1160
*/
1161
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
1162
#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) )
1163
#endif
1164
1165
/**
1166
* semphr.h
1167
* @code{c}
1168
* UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
1169
* @endcode
1170
*
1171
* If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns
1172
* its current count value. If the semaphore is a binary semaphore then
1173
* uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the
1174
* semaphore is not available.
1175
*
1176
*/
1177
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
1178
1179
/**
1180
* semphr.h
1181
* @code{c}
1182
* UBaseType_t uxSemaphoreGetCountFromISR( SemaphoreHandle_t xSemaphore );
1183
* @endcode
1184
*
1185
* If the semaphore is a counting semaphore then uxSemaphoreGetCountFromISR() returns
1186
* its current count value. If the semaphore is a binary semaphore then
1187
* uxSemaphoreGetCountFromISR() returns 1 if the semaphore is available, and 0 if the
1188
* semaphore is not available.
1189
*
1190
*/
1191
#define uxSemaphoreGetCountFromISR( xSemaphore ) uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) ( xSemaphore ) )
1192
1193
/**
1194
* semphr.h
1195
* @code{c}
1196
* BaseType_t xSemaphoreGetStaticBuffer( SemaphoreHandle_t xSemaphore );
1197
* @endcode
1198
*
1199
* Retrieve pointer to a statically created binary semaphore, counting semaphore,
1200
* or mutex semaphore's data structure buffer. This is the same buffer that is
1201
* supplied at the time of creation.
1202
*
1203
* @param xSemaphore The semaphore for which to retrieve the buffer.
1204
*
1205
* @param ppxSemaphoreBuffer Used to return a pointer to the semaphore's
1206
* data structure buffer.
1207
*
1208
* @return pdTRUE if buffer was retrieved, pdFALSE otherwise.
1209
*/
1210
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
1211
#define xSemaphoreGetStaticBuffer( xSemaphore, ppxSemaphoreBuffer ) xQueueGenericGetStaticBuffers( ( QueueHandle_t ) ( xSemaphore ), NULL, ( ppxSemaphoreBuffer ) )
1212
#endif
/* configSUPPORT_STATIC_ALLOCATION */
1213
1214
#endif
/* SEMAPHORE_H */
queue.h
QueueHandle_t
struct QueueDefinition * QueueHandle_t
Definition
queue.h:51
SemaphoreHandle_t
QueueHandle_t SemaphoreHandle_t
Definition
semphr.h:38
firmware
Flight_Computer
Middlewares
Third_Party
FreeRTOS
Source
include
semphr.h
Generated by
1.15.0