FreeRTOS Real Time Operating System, Modified from Kenji Arai's initial port. See freertos.org for full documentation.
Fork of FreeRTOS_on_mbed_v1 by
semphr.h
00001 /* 00002 FreeRTOS V6.0.3 - Copyright (C) 2010 Real Time Engineers Ltd. 00003 00004 *************************************************************************** 00005 * * 00006 * If you are: * 00007 * * 00008 * + New to FreeRTOS, * 00009 * + Wanting to learn FreeRTOS or multitasking in general quickly * 00010 * + Looking for basic training, * 00011 * + Wanting to improve your FreeRTOS skills and productivity * 00012 * * 00013 * then take a look at the FreeRTOS eBook * 00014 * * 00015 * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * 00016 * http://www.FreeRTOS.org/Documentation * 00017 * * 00018 * A pdf reference manual is also available. Both are usually delivered * 00019 * to your inbox within 20 minutes to two hours when purchased between 8am * 00020 * and 8pm GMT (although please allow up to 24 hours in case of * 00021 * exceptional circumstances). Thank you for your support! * 00022 * * 00023 *************************************************************************** 00024 00025 This file is part of the FreeRTOS distribution. 00026 00027 FreeRTOS is free software; you can redistribute it and/or modify it under 00028 the terms of the GNU General Public License (version 2) as published by the 00029 Free Software Foundation AND MODIFIED BY the FreeRTOS exception. 00030 ***NOTE*** The exception to the GPL is included to allow you to distribute 00031 a combined work that includes FreeRTOS without being obliged to provide the 00032 source code for proprietary components outside of the FreeRTOS kernel. 00033 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT 00034 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00035 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 00036 more details. You should have received a copy of the GNU General Public 00037 License and the FreeRTOS license exception along with FreeRTOS; if not it 00038 can be viewed here: http://www.freertos.org/a00114.html and also obtained 00039 by writing to Richard Barry, contact details for whom are available on the 00040 FreeRTOS WEB site. 00041 00042 1 tab == 4 spaces! 00043 00044 http://www.FreeRTOS.org - Documentation, latest information, license and 00045 contact details. 00046 00047 http://www.SafeRTOS.com - A version that is certified for use in safety 00048 critical systems. 00049 00050 http://www.OpenRTOS.com - Commercial support, development, porting, 00051 licensing and training services. 00052 */ 00053 00054 #ifndef INC_FREERTOS_H 00055 #error "#include FreeRTOS.h" must appear in source files before "#include semphr.h" 00056 #endif 00057 00058 #ifndef SEMAPHORE_H 00059 #define SEMAPHORE_H 00060 00061 #include "queue.h" 00062 00063 typedef xQueueHandle xSemaphoreHandle; 00064 00065 #define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1 ) 00066 #define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0 ) 00067 #define semGIVE_BLOCK_TIME ( ( portTickType ) 0 ) 00068 00069 00070 /** 00071 * semphr. h 00072 * <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre> 00073 * 00074 * <i>Macro</i> that implements a semaphore by using the existing queue mechanism. 00075 * The queue length is 1 as this is a binary semaphore. The data size is 0 00076 * as we don't want to actually store any data - we just want to know if the 00077 * queue is empty or full. 00078 * 00079 * This type of semaphore can be used for pure synchronisation between tasks or 00080 * between an interrupt and a task. The semaphore need not be given back once 00081 * obtained, so one task/interrupt can continuously 'give' the semaphore while 00082 * another continuously 'takes' the semaphore. For this reason this type of 00083 * semaphore does not use a priority inheritance mechanism. For an alternative 00084 * that does use priority inheritance see xSemaphoreCreateMutex(). 00085 * 00086 * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle. 00087 * 00088 * Example usage: 00089 <pre> 00090 xSemaphoreHandle xSemaphore; 00091 00092 void vATask( void * pvParameters ) 00093 { 00094 // Semaphore cannot be used before a call to vSemaphoreCreateBinary (). 00095 // This is a macro so pass the variable in directly. 00096 vSemaphoreCreateBinary( xSemaphore ); 00097 00098 if( xSemaphore != NULL ) 00099 { 00100 // The semaphore was created successfully. 00101 // The semaphore can now be used. 00102 } 00103 } 00104 </pre> 00105 * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary 00106 * \ingroup Semaphores 00107 */ 00108 #define vSemaphoreCreateBinary( xSemaphore ) { \ 00109 xSemaphore = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \ 00110 if( xSemaphore != NULL ) \ 00111 { \ 00112 xSemaphoreGive( xSemaphore ); \ 00113 } \ 00114 } 00115 00116 /** 00117 * semphr. h 00118 * <pre>xSemaphoreTake( 00119 * xSemaphoreHandle xSemaphore, 00120 * portTickType xBlockTime 00121 * )</pre> 00122 * 00123 * <i>Macro</i> to obtain a semaphore. The semaphore must have previously been 00124 * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or 00125 * xSemaphoreCreateCounting(). 00126 * 00127 * @param xSemaphore A handle to the semaphore being taken - obtained when 00128 * the semaphore was created. 00129 * 00130 * @param xBlockTime The time in ticks to wait for the semaphore to become 00131 * available. The macro portTICK_RATE_MS can be used to convert this to a 00132 * real time. A block time of zero can be used to poll the semaphore. A block 00133 * time of portMAX_DELAY can be used to block indefinitely (provided 00134 * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). 00135 * 00136 * @return pdTRUE if the semaphore was obtained. pdFALSE 00137 * if xBlockTime expired without the semaphore becoming available. 00138 * 00139 * Example usage: 00140 <pre> 00141 xSemaphoreHandle xSemaphore = NULL; 00142 00143 // A task that creates a semaphore. 00144 void vATask( void * pvParameters ) 00145 { 00146 // Create the semaphore to guard a shared resource. 00147 vSemaphoreCreateBinary( xSemaphore ); 00148 } 00149 00150 // A task that uses the semaphore. 00151 void vAnotherTask( void * pvParameters ) 00152 { 00153 // ... Do other things. 00154 00155 if( xSemaphore != NULL ) 00156 { 00157 // See if we can obtain the semaphore. If the semaphore is not available 00158 // wait 10 ticks to see if it becomes free. 00159 if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE ) 00160 { 00161 // We were able to obtain the semaphore and can now access the 00162 // shared resource. 00163 00164 // ... 00165 00166 // We have finished accessing the shared resource. Release the 00167 // semaphore. 00168 xSemaphoreGive( xSemaphore ); 00169 } 00170 else 00171 { 00172 // We could not obtain the semaphore and can therefore not access 00173 // the shared resource safely. 00174 } 00175 } 00176 } 00177 </pre> 00178 * \defgroup xSemaphoreTake xSemaphoreTake 00179 * \ingroup Semaphores 00180 */ 00181 #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE ) 00182 00183 /** 00184 * semphr. h 00185 * xSemaphoreTakeRecursive( 00186 * xSemaphoreHandle xMutex, 00187 * portTickType xBlockTime 00188 * ) 00189 * 00190 * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore. 00191 * The mutex must have previously been created using a call to 00192 * xSemaphoreCreateRecursiveMutex(); 00193 * 00194 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this 00195 * macro to be available. 00196 * 00197 * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). 00198 * 00199 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex 00200 * doesn't become available again until the owner has called 00201 * xSemaphoreGiveRecursive() for each successful 'take' request. For example, 00202 * if a task successfully 'takes' the same mutex 5 times then the mutex will 00203 * not be available to any other task until it has also 'given' the mutex back 00204 * exactly five times. 00205 * 00206 * @param xMutex A handle to the mutex being obtained. This is the 00207 * handle returned by xSemaphoreCreateRecursiveMutex(); 00208 * 00209 * @param xBlockTime The time in ticks to wait for the semaphore to become 00210 * available. The macro portTICK_RATE_MS can be used to convert this to a 00211 * real time. A block time of zero can be used to poll the semaphore. If 00212 * the task already owns the semaphore then xSemaphoreTakeRecursive() will 00213 * return immediately no matter what the value of xBlockTime. 00214 * 00215 * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime 00216 * expired without the semaphore becoming available. 00217 * 00218 * Example usage: 00219 <pre> 00220 xSemaphoreHandle xMutex = NULL; 00221 00222 // A task that creates a mutex. 00223 void vATask( void * pvParameters ) 00224 { 00225 // Create the mutex to guard a shared resource. 00226 xMutex = xSemaphoreCreateRecursiveMutex(); 00227 } 00228 00229 // A task that uses the mutex. 00230 void vAnotherTask( void * pvParameters ) 00231 { 00232 // ... Do other things. 00233 00234 if( xMutex != NULL ) 00235 { 00236 // See if we can obtain the mutex. If the mutex is not available 00237 // wait 10 ticks to see if it becomes free. 00238 if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE ) 00239 { 00240 // We were able to obtain the mutex and can now access the 00241 // shared resource. 00242 00243 // ... 00244 // For some reason due to the nature of the code further calls to 00245 // xSemaphoreTakeRecursive() are made on the same mutex. In real 00246 // code these would not be just sequential calls as this would make 00247 // no sense. Instead the calls are likely to be buried inside 00248 // a more complex call structure. 00249 xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ); 00250 xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ); 00251 00252 // The mutex has now been 'taken' three times, so will not be 00253 // available to another task until it has also been given back 00254 // three times. Again it is unlikely that real code would have 00255 // these calls sequentially, but instead buried in a more complex 00256 // call structure. This is just for illustrative purposes. 00257 xSemaphoreGiveRecursive( xMutex ); 00258 xSemaphoreGiveRecursive( xMutex ); 00259 xSemaphoreGiveRecursive( xMutex ); 00260 00261 // Now the mutex can be taken by other tasks. 00262 } 00263 else 00264 { 00265 // We could not obtain the mutex and can therefore not access 00266 // the shared resource safely. 00267 } 00268 } 00269 } 00270 </pre> 00271 * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive 00272 * \ingroup Semaphores 00273 */ 00274 #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( xMutex, xBlockTime ) 00275 00276 00277 /* 00278 * xSemaphoreAltTake() is an alternative version of xSemaphoreTake(). 00279 * 00280 * The source code that implements the alternative (Alt) API is much 00281 * simpler because it executes everything from within a critical section. 00282 * This is the approach taken by many other RTOSes, but FreeRTOS.org has the 00283 * preferred fully featured API too. The fully featured API has more 00284 * complex code that takes longer to execute, but makes much less use of 00285 * critical sections. Therefore the alternative API sacrifices interrupt 00286 * responsiveness to gain execution speed, whereas the fully featured API 00287 * sacrifices execution speed to ensure better interrupt responsiveness. 00288 */ 00289 #define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) xSemaphore, NULL, xBlockTime, pdFALSE ) 00290 00291 /** 00292 * semphr. h 00293 * <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre> 00294 * 00295 * <i>Macro</i> to release a semaphore. The semaphore must have previously been 00296 * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or 00297 * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). 00298 * 00299 * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for 00300 * an alternative which can be used from an ISR. 00301 * 00302 * This macro must also not be used on semaphores created using 00303 * xSemaphoreCreateRecursiveMutex(). 00304 * 00305 * @param xSemaphore A handle to the semaphore being released. This is the 00306 * handle returned when the semaphore was created. 00307 * 00308 * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. 00309 * Semaphores are implemented using queues. An error can occur if there is 00310 * no space on the queue to post a message - indicating that the 00311 * semaphore was not first obtained correctly. 00312 * 00313 * Example usage: 00314 <pre> 00315 xSemaphoreHandle xSemaphore = NULL; 00316 00317 void vATask( void * pvParameters ) 00318 { 00319 // Create the semaphore to guard a shared resource. 00320 vSemaphoreCreateBinary( xSemaphore ); 00321 00322 if( xSemaphore != NULL ) 00323 { 00324 if( xSemaphoreGive( xSemaphore ) != pdTRUE ) 00325 { 00326 // We would expect this call to fail because we cannot give 00327 // a semaphore without first "taking" it! 00328 } 00329 00330 // Obtain the semaphore - don't block if the semaphore is not 00331 // immediately available. 00332 if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) ) 00333 { 00334 // We now have the semaphore and can access the shared resource. 00335 00336 // ... 00337 00338 // We have finished accessing the shared resource so can free the 00339 // semaphore. 00340 if( xSemaphoreGive( xSemaphore ) != pdTRUE ) 00341 { 00342 // We would not expect this call to fail because we must have 00343 // obtained the semaphore to get here. 00344 } 00345 } 00346 } 00347 } 00348 </pre> 00349 * \defgroup xSemaphoreGive xSemaphoreGive 00350 * \ingroup Semaphores 00351 */ 00352 #define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) 00353 00354 /** 00355 * semphr. h 00356 * <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre> 00357 * 00358 * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore. 00359 * The mutex must have previously been created using a call to 00360 * xSemaphoreCreateRecursiveMutex(); 00361 * 00362 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this 00363 * macro to be available. 00364 * 00365 * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). 00366 * 00367 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex 00368 * doesn't become available again until the owner has called 00369 * xSemaphoreGiveRecursive() for each successful 'take' request. For example, 00370 * if a task successfully 'takes' the same mutex 5 times then the mutex will 00371 * not be available to any other task until it has also 'given' the mutex back 00372 * exactly five times. 00373 * 00374 * @param xMutex A handle to the mutex being released, or 'given'. This is the 00375 * handle returned by xSemaphoreCreateMutex(); 00376 * 00377 * @return pdTRUE if the semaphore was given. 00378 * 00379 * Example usage: 00380 <pre> 00381 xSemaphoreHandle xMutex = NULL; 00382 00383 // A task that creates a mutex. 00384 void vATask( void * pvParameters ) 00385 { 00386 // Create the mutex to guard a shared resource. 00387 xMutex = xSemaphoreCreateRecursiveMutex(); 00388 } 00389 00390 // A task that uses the mutex. 00391 void vAnotherTask( void * pvParameters ) 00392 { 00393 // ... Do other things. 00394 00395 if( xMutex != NULL ) 00396 { 00397 // See if we can obtain the mutex. If the mutex is not available 00398 // wait 10 ticks to see if it becomes free. 00399 if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE ) 00400 { 00401 // We were able to obtain the mutex and can now access the 00402 // shared resource. 00403 00404 // ... 00405 // For some reason due to the nature of the code further calls to 00406 // xSemaphoreTakeRecursive() are made on the same mutex. In real 00407 // code these would not be just sequential calls as this would make 00408 // no sense. Instead the calls are likely to be buried inside 00409 // a more complex call structure. 00410 xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ); 00411 xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ); 00412 00413 // The mutex has now been 'taken' three times, so will not be 00414 // available to another task until it has also been given back 00415 // three times. Again it is unlikely that real code would have 00416 // these calls sequentially, it would be more likely that the calls 00417 // to xSemaphoreGiveRecursive() would be called as a call stack 00418 // unwound. This is just for demonstrative purposes. 00419 xSemaphoreGiveRecursive( xMutex ); 00420 xSemaphoreGiveRecursive( xMutex ); 00421 xSemaphoreGiveRecursive( xMutex ); 00422 00423 // Now the mutex can be taken by other tasks. 00424 } 00425 else 00426 { 00427 // We could not obtain the mutex and can therefore not access 00428 // the shared resource safely. 00429 } 00430 } 00431 } 00432 </pre> 00433 * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive 00434 * \ingroup Semaphores 00435 */ 00436 #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( xMutex ) 00437 00438 /* 00439 * xSemaphoreAltGive() is an alternative version of xSemaphoreGive(). 00440 * 00441 * The source code that implements the alternative (Alt) API is much 00442 * simpler because it executes everything from within a critical section. 00443 * This is the approach taken by many other RTOSes, but FreeRTOS.org has the 00444 * preferred fully featured API too. The fully featured API has more 00445 * complex code that takes longer to execute, but makes much less use of 00446 * critical sections. Therefore the alternative API sacrifices interrupt 00447 * responsiveness to gain execution speed, whereas the fully featured API 00448 * sacrifices execution speed to ensure better interrupt responsiveness. 00449 */ 00450 #define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) 00451 00452 /** 00453 * semphr. h 00454 * <pre> 00455 xSemaphoreGiveFromISR( 00456 xSemaphoreHandle xSemaphore, 00457 signed portBASE_TYPE *pxHigherPriorityTaskWoken 00458 )</pre> 00459 * 00460 * <i>Macro</i> to release a semaphore. The semaphore must have previously been 00461 * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). 00462 * 00463 * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) 00464 * must not be used with this macro. 00465 * 00466 * This macro can be used from an ISR. 00467 * 00468 * @param xSemaphore A handle to the semaphore being released. This is the 00469 * handle returned when the semaphore was created. 00470 * 00471 * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set 00472 * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task 00473 * to unblock, and the unblocked task has a priority higher than the currently 00474 * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then 00475 * a context switch should be requested before the interrupt is exited. 00476 * 00477 * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. 00478 * 00479 * Example usage: 00480 <pre> 00481 \#define LONG_TIME 0xffff 00482 \#define TICKS_TO_WAIT 10 00483 xSemaphoreHandle xSemaphore = NULL; 00484 00485 // Repetitive task. 00486 void vATask( void * pvParameters ) 00487 { 00488 for( ;; ) 00489 { 00490 // We want this task to run every 10 ticks of a timer. The semaphore 00491 // was created before this task was started. 00492 00493 // Block waiting for the semaphore to become available. 00494 if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE ) 00495 { 00496 // It is time to execute. 00497 00498 // ... 00499 00500 // We have finished our task. Return to the top of the loop where 00501 // we will block on the semaphore until it is time to execute 00502 // again. Note when using the semaphore for synchronisation with an 00503 // ISR in this manner there is no need to 'give' the semaphore back. 00504 } 00505 } 00506 } 00507 00508 // Timer ISR 00509 void vTimerISR( void * pvParameters ) 00510 { 00511 static unsigned char ucLocalTickCount = 0; 00512 static signed portBASE_TYPE xHigherPriorityTaskWoken; 00513 00514 // A timer tick has occurred. 00515 00516 // ... Do other time functions. 00517 00518 // Is it time for vATask () to run? 00519 xHigherPriorityTaskWoken = pdFALSE; 00520 ucLocalTickCount++; 00521 if( ucLocalTickCount >= TICKS_TO_WAIT ) 00522 { 00523 // Unblock the task by releasing the semaphore. 00524 xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken ); 00525 00526 // Reset the count so we release the semaphore again in 10 ticks time. 00527 ucLocalTickCount = 0; 00528 } 00529 00530 if( xHigherPriorityTaskWoken != pdFALSE ) 00531 { 00532 // We can force a context switch here. Context switching from an 00533 // ISR uses port specific syntax. Check the demo task for your port 00534 // to find the syntax required. 00535 } 00536 } 00537 </pre> 00538 * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR 00539 * \ingroup Semaphores 00540 */ 00541 #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) xSemaphore, NULL, pxHigherPriorityTaskWoken, queueSEND_TO_BACK ) 00542 00543 /** 00544 * semphr. h 00545 * <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre> 00546 * 00547 * <i>Macro</i> that implements a mutex semaphore by using the existing queue 00548 * mechanism. 00549 * 00550 * Mutexes created using this macro can be accessed using the xSemaphoreTake() 00551 * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and 00552 * xSemaphoreGiveRecursive() macros should not be used. 00553 * 00554 * This type of semaphore uses a priority inheritance mechanism so a task 00555 * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the 00556 * semaphore it is no longer required. 00557 * 00558 * Mutex type semaphores cannot be used from within interrupt service routines. 00559 * 00560 * See vSemaphoreCreateBinary() for an alternative implementation that can be 00561 * used for pure synchronisation (where one task or interrupt always 'gives' the 00562 * semaphore and another always 'takes' the semaphore) and from within interrupt 00563 * service routines. 00564 * 00565 * @return xSemaphore Handle to the created mutex semaphore. Should be of type 00566 * xSemaphoreHandle. 00567 * 00568 * Example usage: 00569 <pre> 00570 xSemaphoreHandle xSemaphore; 00571 00572 void vATask( void * pvParameters ) 00573 { 00574 // Semaphore cannot be used before a call to xSemaphoreCreateMutex(). 00575 // This is a macro so pass the variable in directly. 00576 xSemaphore = xSemaphoreCreateMutex(); 00577 00578 if( xSemaphore != NULL ) 00579 { 00580 // The semaphore was created successfully. 00581 // The semaphore can now be used. 00582 } 00583 } 00584 </pre> 00585 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex 00586 * \ingroup Semaphores 00587 */ 00588 #define xSemaphoreCreateMutex() xQueueCreateMutex() 00589 00590 00591 /** 00592 * semphr. h 00593 * <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre> 00594 * 00595 * <i>Macro</i> that implements a recursive mutex by using the existing queue 00596 * mechanism. 00597 * 00598 * Mutexes created using this macro can be accessed using the 00599 * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The 00600 * xSemaphoreTake() and xSemaphoreGive() macros should not be used. 00601 * 00602 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex 00603 * doesn't become available again until the owner has called 00604 * xSemaphoreGiveRecursive() for each successful 'take' request. For example, 00605 * if a task successfully 'takes' the same mutex 5 times then the mutex will 00606 * not be available to any other task until it has also 'given' the mutex back 00607 * exactly five times. 00608 * 00609 * This type of semaphore uses a priority inheritance mechanism so a task 00610 * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the 00611 * semaphore it is no longer required. 00612 * 00613 * Mutex type semaphores cannot be used from within interrupt service routines. 00614 * 00615 * See vSemaphoreCreateBinary() for an alternative implementation that can be 00616 * used for pure synchronisation (where one task or interrupt always 'gives' the 00617 * semaphore and another always 'takes' the semaphore) and from within interrupt 00618 * service routines. 00619 * 00620 * @return xSemaphore Handle to the created mutex semaphore. Should be of type 00621 * xSemaphoreHandle. 00622 * 00623 * Example usage: 00624 <pre> 00625 xSemaphoreHandle xSemaphore; 00626 00627 void vATask( void * pvParameters ) 00628 { 00629 // Semaphore cannot be used before a call to xSemaphoreCreateMutex(). 00630 // This is a macro so pass the variable in directly. 00631 xSemaphore = xSemaphoreCreateRecursiveMutex(); 00632 00633 if( xSemaphore != NULL ) 00634 { 00635 // The semaphore was created successfully. 00636 // The semaphore can now be used. 00637 } 00638 } 00639 </pre> 00640 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex 00641 * \ingroup Semaphores 00642 */ 00643 #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex() 00644 00645 /** 00646 * semphr. h 00647 * <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre> 00648 * 00649 * <i>Macro</i> that creates a counting semaphore by using the existing 00650 * queue mechanism. 00651 * 00652 * Counting semaphores are typically used for two things: 00653 * 00654 * 1) Counting events. 00655 * 00656 * In this usage scenario an event handler will 'give' a semaphore each time 00657 * an event occurs (incrementing the semaphore count value), and a handler 00658 * task will 'take' a semaphore each time it processes an event 00659 * (decrementing the semaphore count value). The count value is therefore 00660 * the difference between the number of events that have occurred and the 00661 * number that have been processed. In this case it is desirable for the 00662 * initial count value to be zero. 00663 * 00664 * 2) Resource management. 00665 * 00666 * In this usage scenario the count value indicates the number of resources 00667 * available. To obtain control of a resource a task must first obtain a 00668 * semaphore - decrementing the semaphore count value. When the count value 00669 * reaches zero there are no free resources. When a task finishes with the 00670 * resource it 'gives' the semaphore back - incrementing the semaphore count 00671 * value. In this case it is desirable for the initial count value to be 00672 * equal to the maximum count value, indicating that all resources are free. 00673 * 00674 * @param uxMaxCount The maximum count value that can be reached. When the 00675 * semaphore reaches this value it can no longer be 'given'. 00676 * 00677 * @param uxInitialCount The count value assigned to the semaphore when it is 00678 * created. 00679 * 00680 * @return Handle to the created semaphore. Null if the semaphore could not be 00681 * created. 00682 * 00683 * Example usage: 00684 <pre> 00685 xSemaphoreHandle xSemaphore; 00686 00687 void vATask( void * pvParameters ) 00688 { 00689 xSemaphoreHandle xSemaphore = NULL; 00690 00691 // Semaphore cannot be used before a call to xSemaphoreCreateCounting(). 00692 // The max value to which the semaphore can count should be 10, and the 00693 // initial value assigned to the count should be 0. 00694 xSemaphore = xSemaphoreCreateCounting( 10, 0 ); 00695 00696 if( xSemaphore != NULL ) 00697 { 00698 // The semaphore was created successfully. 00699 // The semaphore can now be used. 00700 } 00701 } 00702 </pre> 00703 * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting 00704 * \ingroup Semaphores 00705 */ 00706 #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( uxMaxCount, uxInitialCount ) 00707 00708 00709 #endif /* SEMAPHORE_H */ 00710 00711
Generated on Fri Jul 15 2022 10:21:25 by
1.7.2
