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