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 */ 1215