TI's CC3100 websocket camera demo with Arducam mini ov5642 and freertos. Should work with other M3's. Work in progress test demo.
semphr.h
00001 /* 00002 FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd. 00003 All rights reserved 00004 00005 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. 00006 00007 This file is part of the FreeRTOS distribution. 00008 00009 FreeRTOS is free software; you can redistribute it and/or modify it under 00010 the terms of the GNU General Public License (version 2) as published by the 00011 Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. 00012 00013 *************************************************************************** 00014 >>! NOTE: The modification to the GPL is included to allow you to !<< 00015 >>! distribute a combined work that includes FreeRTOS without being !<< 00016 >>! obliged to provide the source code for proprietary components !<< 00017 >>! outside of the FreeRTOS kernel. !<< 00018 *************************************************************************** 00019 00020 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY 00021 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00022 FOR A PARTICULAR PURPOSE. Full license text is available on the following 00023 link: http://www.freertos.org/a00114.html 00024 00025 *************************************************************************** 00026 * * 00027 * FreeRTOS provides completely free yet professionally developed, * 00028 * robust, strictly quality controlled, supported, and cross * 00029 * platform software that is more than just the market leader, it * 00030 * is the industry's de facto standard. * 00031 * * 00032 * Help yourself get started quickly while simultaneously helping * 00033 * to support the FreeRTOS project by purchasing a FreeRTOS * 00034 * tutorial book, reference manual, or both: * 00035 * http://www.FreeRTOS.org/Documentation * 00036 * * 00037 *************************************************************************** 00038 00039 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading 00040 the FAQ page "My application does not run, what could be wrong?". Have you 00041 defined configASSERT()? 00042 00043 http://www.FreeRTOS.org/support - In return for receiving this top quality 00044 embedded software for free we request you assist our global community by 00045 participating in the support forum. 00046 00047 http://www.FreeRTOS.org/training - Investing in training allows your team to 00048 be as productive as possible as early as possible. Now you can receive 00049 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers 00050 Ltd, and the world's leading authority on the world's leading RTOS. 00051 00052 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, 00053 including FreeRTOS+Trace - an indispensable productivity tool, a DOS 00054 compatible FAT file system, and our tiny thread aware UDP/IP stack. 00055 00056 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. 00057 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. 00058 00059 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High 00060 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS 00061 licenses offer ticketed support, indemnification and commercial middleware. 00062 00063 http://www.SafeRTOS.com - High Integrity Systems also provide a safety 00064 engineered and independently SIL3 certified version for use in safety and 00065 mission critical applications that require provable dependability. 00066 00067 1 tab == 4 spaces! 00068 */ 00069 00070 #ifndef SEMAPHORE_H 00071 #define SEMAPHORE_H 00072 00073 #ifndef INC_FREERTOS_H 00074 #error "include FreeRTOS.h" must appear in source files before "include semphr.h" 00075 #endif 00076 00077 #include "queue.h" 00078 00079 typedef QueueHandle_t SemaphoreHandle_t; 00080 00081 #define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) 00082 #define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) 00083 #define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) 00084 00085 00086 /** 00087 * semphr. h 00088 * <pre>vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )</pre> 00089 * 00090 * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the 00091 * xSemaphoreCreateBinary() function. Note that binary semaphores created using 00092 * the vSemaphoreCreateBinary() macro are created in a state such that the 00093 * first call to 'take' the semaphore would pass, whereas binary semaphores 00094 * created using xSemaphoreCreateBinary() are created in a state such that the 00095 * the semaphore must first be 'given' before it can be 'taken'. 00096 * 00097 * <i>Macro</i> that implements a semaphore by using the existing queue mechanism. 00098 * The queue length is 1 as this is a binary semaphore. The data size is 0 00099 * as we don't want to actually store any data - we just want to know if the 00100 * queue is empty or full. 00101 * 00102 * This type of semaphore can be used for pure synchronisation between tasks or 00103 * between an interrupt and a task. The semaphore need not be given back once 00104 * obtained, so one task/interrupt can continuously 'give' the semaphore while 00105 * another continuously 'takes' the semaphore. For this reason this type of 00106 * semaphore does not use a priority inheritance mechanism. For an alternative 00107 * that does use priority inheritance see xSemaphoreCreateMutex(). 00108 * 00109 * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. 00110 * 00111 * Example usage: 00112 <pre> 00113 SemaphoreHandle_t xSemaphore = NULL; 00114 00115 void vATask( void * pvParameters ) 00116 { 00117 // Semaphore cannot be used before a call to vSemaphoreCreateBinary (). 00118 // This is a macro so pass the variable in directly. 00119 vSemaphoreCreateBinary( xSemaphore ); 00120 00121 if( xSemaphore != NULL ) 00122 { 00123 // The semaphore was created successfully. 00124 // The semaphore can now be used. 00125 } 00126 } 00127 </pre> 00128 * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary 00129 * \ingroup Semaphores 00130 */ 00131 #define vSemaphoreCreateBinary( xSemaphore ) \ 00132 { \ 00133 ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ 00134 if( ( xSemaphore ) != NULL ) \ 00135 { \ 00136 ( void ) xSemaphoreGive( ( xSemaphore ) ); \ 00137 } \ 00138 } 00139 00140 /** 00141 * semphr. h 00142 * <pre>SemaphoreHandle_t xSemaphoreCreateBinary( void )</pre> 00143 * 00144 * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this 00145 * xSemaphoreCreateBinary() function. Note that binary semaphores created using 00146 * the vSemaphoreCreateBinary() macro are created in a state such that the 00147 * first call to 'take' the semaphore would pass, whereas binary semaphores 00148 * created using xSemaphoreCreateBinary() are created in a state such that the 00149 * the semaphore must first be 'given' before it can be 'taken'. 00150 * 00151 * Function that creates a semaphore by using the existing queue mechanism. 00152 * The queue length is 1 as this is a binary semaphore. The data size is 0 00153 * as nothing is actually stored - all that is important is whether the queue is 00154 * empty or full (the binary semaphore is available or not). 00155 * 00156 * This type of semaphore can be used for pure synchronisation between tasks or 00157 * between an interrupt and a task. The semaphore need not be given back once 00158 * obtained, so one task/interrupt can continuously 'give' the semaphore while 00159 * another continuously 'takes' the semaphore. For this reason this type of 00160 * semaphore does not use a priority inheritance mechanism. For an alternative 00161 * that does use priority inheritance see xSemaphoreCreateMutex(). 00162 * 00163 * @return Handle to the created semaphore. 00164 * 00165 * Example usage: 00166 <pre> 00167 SemaphoreHandle_t xSemaphore = NULL; 00168 00169 void vATask( void * pvParameters ) 00170 { 00171 // Semaphore cannot be used before a call to vSemaphoreCreateBinary (). 00172 // This is a macro so pass the variable in directly. 00173 xSemaphore = xSemaphoreCreateBinary(); 00174 00175 if( xSemaphore != NULL ) 00176 { 00177 // The semaphore was created successfully. 00178 // The semaphore can now be used. 00179 } 00180 } 00181 </pre> 00182 * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary 00183 * \ingroup Semaphores 00184 */ 00185 #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) 00186 00187 /** 00188 * semphr. h 00189 * <pre>xSemaphoreTake( 00190 * SemaphoreHandle_t xSemaphore, 00191 * TickType_t xBlockTime 00192 * )</pre> 00193 * 00194 * <i>Macro</i> to obtain a semaphore. The semaphore must have previously been 00195 * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or 00196 * xSemaphoreCreateCounting(). 00197 * 00198 * @param xSemaphore A handle to the semaphore being taken - obtained when 00199 * the semaphore was created. 00200 * 00201 * @param xBlockTime The time in ticks to wait for the semaphore to become 00202 * available. The macro portTICK_PERIOD_MS can be used to convert this to a 00203 * real time. A block time of zero can be used to poll the semaphore. A block 00204 * time of portMAX_DELAY can be used to block indefinitely (provided 00205 * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). 00206 * 00207 * @return pdTRUE if the semaphore was obtained. pdFALSE 00208 * if xBlockTime expired without the semaphore becoming available. 00209 * 00210 * Example usage: 00211 <pre> 00212 SemaphoreHandle_t xSemaphore = NULL; 00213 00214 // A task that creates a semaphore. 00215 void vATask( void * pvParameters ) 00216 { 00217 // Create the semaphore to guard a shared resource. 00218 vSemaphoreCreateBinary( xSemaphore ); 00219 } 00220 00221 // A task that uses the semaphore. 00222 void vAnotherTask( void * pvParameters ) 00223 { 00224 // ... Do other things. 00225 00226 if( xSemaphore != NULL ) 00227 { 00228 // See if we can obtain the semaphore. If the semaphore is not available 00229 // wait 10 ticks to see if it becomes free. 00230 if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE ) 00231 { 00232 // We were able to obtain the semaphore and can now access the 00233 // shared resource. 00234 00235 // ... 00236 00237 // We have finished accessing the shared resource. Release the 00238 // semaphore. 00239 xSemaphoreGive( xSemaphore ); 00240 } 00241 else 00242 { 00243 // We could not obtain the semaphore and can therefore not access 00244 // the shared resource safely. 00245 } 00246 } 00247 } 00248 </pre> 00249 * \defgroup xSemaphoreTake xSemaphoreTake 00250 * \ingroup Semaphores 00251 */ 00252 #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) 00253 00254 /** 00255 * semphr. h 00256 * xSemaphoreTakeRecursive( 00257 * SemaphoreHandle_t xMutex, 00258 * TickType_t xBlockTime 00259 * ) 00260 * 00261 * <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore. 00262 * The mutex must have previously been created using a call to 00263 * xSemaphoreCreateRecursiveMutex(); 00264 * 00265 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this 00266 * macro to be available. 00267 * 00268 * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). 00269 * 00270 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex 00271 * doesn't become available again until the owner has called 00272 * xSemaphoreGiveRecursive() for each successful 'take' request. For example, 00273 * if a task successfully 'takes' the same mutex 5 times then the mutex will 00274 * not be available to any other task until it has also 'given' the mutex back 00275 * exactly five times. 00276 * 00277 * @param xMutex A handle to the mutex being obtained. This is the 00278 * handle returned by xSemaphoreCreateRecursiveMutex(); 00279 * 00280 * @param xBlockTime The time in ticks to wait for the semaphore to become 00281 * available. The macro portTICK_PERIOD_MS can be used to convert this to a 00282 * real time. A block time of zero can be used to poll the semaphore. If 00283 * the task already owns the semaphore then xSemaphoreTakeRecursive() will 00284 * return immediately no matter what the value of xBlockTime. 00285 * 00286 * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime 00287 * expired without the semaphore becoming available. 00288 * 00289 * Example usage: 00290 <pre> 00291 SemaphoreHandle_t xMutex = NULL; 00292 00293 // A task that creates a mutex. 00294 void vATask( void * pvParameters ) 00295 { 00296 // Create the mutex to guard a shared resource. 00297 xMutex = xSemaphoreCreateRecursiveMutex(); 00298 } 00299 00300 // A task that uses the mutex. 00301 void vAnotherTask( void * pvParameters ) 00302 { 00303 // ... Do other things. 00304 00305 if( xMutex != NULL ) 00306 { 00307 // See if we can obtain the mutex. If the mutex is not available 00308 // wait 10 ticks to see if it becomes free. 00309 if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE ) 00310 { 00311 // We were able to obtain the mutex and can now access the 00312 // shared resource. 00313 00314 // ... 00315 // For some reason due to the nature of the code further calls to 00316 // xSemaphoreTakeRecursive() are made on the same mutex. In real 00317 // code these would not be just sequential calls as this would make 00318 // no sense. Instead the calls are likely to be buried inside 00319 // a more complex call structure. 00320 xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); 00321 xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); 00322 00323 // The mutex has now been 'taken' three times, so will not be 00324 // available to another task until it has also been given back 00325 // three times. Again it is unlikely that real code would have 00326 // these calls sequentially, but instead buried in a more complex 00327 // call structure. This is just for illustrative purposes. 00328 xSemaphoreGiveRecursive( xMutex ); 00329 xSemaphoreGiveRecursive( xMutex ); 00330 xSemaphoreGiveRecursive( xMutex ); 00331 00332 // Now the mutex can be taken by other tasks. 00333 } 00334 else 00335 { 00336 // We could not obtain the mutex and can therefore not access 00337 // the shared resource safely. 00338 } 00339 } 00340 } 00341 </pre> 00342 * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive 00343 * \ingroup Semaphores 00344 */ 00345 #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) 00346 00347 00348 /* 00349 * xSemaphoreAltTake() is an alternative version of xSemaphoreTake(). 00350 * 00351 * The source code that implements the alternative (Alt) API is much 00352 * simpler because it executes everything from within a critical section. 00353 * This is the approach taken by many other RTOSes, but FreeRTOS.org has the 00354 * preferred fully featured API too. The fully featured API has more 00355 * complex code that takes longer to execute, but makes much less use of 00356 * critical sections. Therefore the alternative API sacrifices interrupt 00357 * responsiveness to gain execution speed, whereas the fully featured API 00358 * sacrifices execution speed to ensure better interrupt responsiveness. 00359 */ 00360 #define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) 00361 00362 /** 00363 * semphr. h 00364 * <pre>xSemaphoreGive( SemaphoreHandle_t xSemaphore )</pre> 00365 * 00366 * <i>Macro</i> to release a semaphore. The semaphore must have previously been 00367 * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or 00368 * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). 00369 * 00370 * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for 00371 * an alternative which can be used from an ISR. 00372 * 00373 * This macro must also not be used on semaphores created using 00374 * xSemaphoreCreateRecursiveMutex(). 00375 * 00376 * @param xSemaphore A handle to the semaphore being released. This is the 00377 * handle returned when the semaphore was created. 00378 * 00379 * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. 00380 * Semaphores are implemented using queues. An error can occur if there is 00381 * no space on the queue to post a message - indicating that the 00382 * semaphore was not first obtained correctly. 00383 * 00384 * Example usage: 00385 <pre> 00386 SemaphoreHandle_t xSemaphore = NULL; 00387 00388 void vATask( void * pvParameters ) 00389 { 00390 // Create the semaphore to guard a shared resource. 00391 vSemaphoreCreateBinary( xSemaphore ); 00392 00393 if( xSemaphore != NULL ) 00394 { 00395 if( xSemaphoreGive( xSemaphore ) != pdTRUE ) 00396 { 00397 // We would expect this call to fail because we cannot give 00398 // a semaphore without first "taking" it! 00399 } 00400 00401 // Obtain the semaphore - don't block if the semaphore is not 00402 // immediately available. 00403 if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) ) 00404 { 00405 // We now have the semaphore and can access the shared resource. 00406 00407 // ... 00408 00409 // We have finished accessing the shared resource so can free the 00410 // semaphore. 00411 if( xSemaphoreGive( xSemaphore ) != pdTRUE ) 00412 { 00413 // We would not expect this call to fail because we must have 00414 // obtained the semaphore to get here. 00415 } 00416 } 00417 } 00418 } 00419 </pre> 00420 * \defgroup xSemaphoreGive xSemaphoreGive 00421 * \ingroup Semaphores 00422 */ 00423 #define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) 00424 00425 /** 00426 * semphr. h 00427 * <pre>xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )</pre> 00428 * 00429 * <i>Macro</i> to recursively release, or 'give', a mutex type semaphore. 00430 * The mutex must have previously been created using a call to 00431 * xSemaphoreCreateRecursiveMutex(); 00432 * 00433 * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this 00434 * macro to be available. 00435 * 00436 * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). 00437 * 00438 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex 00439 * doesn't become available again until the owner has called 00440 * xSemaphoreGiveRecursive() for each successful 'take' request. For example, 00441 * if a task successfully 'takes' the same mutex 5 times then the mutex will 00442 * not be available to any other task until it has also 'given' the mutex back 00443 * exactly five times. 00444 * 00445 * @param xMutex A handle to the mutex being released, or 'given'. This is the 00446 * handle returned by xSemaphoreCreateMutex(); 00447 * 00448 * @return pdTRUE if the semaphore was given. 00449 * 00450 * Example usage: 00451 <pre> 00452 SemaphoreHandle_t xMutex = NULL; 00453 00454 // A task that creates a mutex. 00455 void vATask( void * pvParameters ) 00456 { 00457 // Create the mutex to guard a shared resource. 00458 xMutex = xSemaphoreCreateRecursiveMutex(); 00459 } 00460 00461 // A task that uses the mutex. 00462 void vAnotherTask( void * pvParameters ) 00463 { 00464 // ... Do other things. 00465 00466 if( xMutex != NULL ) 00467 { 00468 // See if we can obtain the mutex. If the mutex is not available 00469 // wait 10 ticks to see if it becomes free. 00470 if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE ) 00471 { 00472 // We were able to obtain the mutex and can now access the 00473 // shared resource. 00474 00475 // ... 00476 // For some reason due to the nature of the code further calls to 00477 // xSemaphoreTakeRecursive() are made on the same mutex. In real 00478 // code these would not be just sequential calls as this would make 00479 // no sense. Instead the calls are likely to be buried inside 00480 // a more complex call structure. 00481 xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); 00482 xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ); 00483 00484 // The mutex has now been 'taken' three times, so will not be 00485 // available to another task until it has also been given back 00486 // three times. Again it is unlikely that real code would have 00487 // these calls sequentially, it would be more likely that the calls 00488 // to xSemaphoreGiveRecursive() would be called as a call stack 00489 // unwound. This is just for demonstrative purposes. 00490 xSemaphoreGiveRecursive( xMutex ); 00491 xSemaphoreGiveRecursive( xMutex ); 00492 xSemaphoreGiveRecursive( xMutex ); 00493 00494 // Now the mutex can be taken by other tasks. 00495 } 00496 else 00497 { 00498 // We could not obtain the mutex and can therefore not access 00499 // the shared resource safely. 00500 } 00501 } 00502 } 00503 </pre> 00504 * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive 00505 * \ingroup Semaphores 00506 */ 00507 #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) 00508 00509 /* 00510 * xSemaphoreAltGive() is an alternative version of xSemaphoreGive(). 00511 * 00512 * The source code that implements the alternative (Alt) API is much 00513 * simpler because it executes everything from within a critical section. 00514 * This is the approach taken by many other RTOSes, but FreeRTOS.org has the 00515 * preferred fully featured API too. The fully featured API has more 00516 * complex code that takes longer to execute, but makes much less use of 00517 * critical sections. Therefore the alternative API sacrifices interrupt 00518 * responsiveness to gain execution speed, whereas the fully featured API 00519 * sacrifices execution speed to ensure better interrupt responsiveness. 00520 */ 00521 #define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) 00522 00523 /** 00524 * semphr. h 00525 * <pre> 00526 xSemaphoreGiveFromISR( 00527 SemaphoreHandle_t xSemaphore, 00528 BaseType_t *pxHigherPriorityTaskWoken 00529 )</pre> 00530 * 00531 * <i>Macro</i> to release a semaphore. The semaphore must have previously been 00532 * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). 00533 * 00534 * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) 00535 * must not be used with this macro. 00536 * 00537 * This macro can be used from an ISR. 00538 * 00539 * @param xSemaphore A handle to the semaphore being released. This is the 00540 * handle returned when the semaphore was created. 00541 * 00542 * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set 00543 * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task 00544 * to unblock, and the unblocked task has a priority higher than the currently 00545 * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then 00546 * a context switch should be requested before the interrupt is exited. 00547 * 00548 * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. 00549 * 00550 * Example usage: 00551 <pre> 00552 \#define LONG_TIME 0xffff 00553 \#define TICKS_TO_WAIT 10 00554 SemaphoreHandle_t xSemaphore = NULL; 00555 00556 // Repetitive task. 00557 void vATask( void * pvParameters ) 00558 { 00559 for( ;; ) 00560 { 00561 // We want this task to run every 10 ticks of a timer. The semaphore 00562 // was created before this task was started. 00563 00564 // Block waiting for the semaphore to become available. 00565 if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE ) 00566 { 00567 // It is time to execute. 00568 00569 // ... 00570 00571 // We have finished our task. Return to the top of the loop where 00572 // we will block on the semaphore until it is time to execute 00573 // again. Note when using the semaphore for synchronisation with an 00574 // ISR in this manner there is no need to 'give' the semaphore back. 00575 } 00576 } 00577 } 00578 00579 // Timer ISR 00580 void vTimerISR( void * pvParameters ) 00581 { 00582 static uint8_t ucLocalTickCount = 0; 00583 static BaseType_t xHigherPriorityTaskWoken; 00584 00585 // A timer tick has occurred. 00586 00587 // ... Do other time functions. 00588 00589 // Is it time for vATask () to run? 00590 xHigherPriorityTaskWoken = pdFALSE; 00591 ucLocalTickCount++; 00592 if( ucLocalTickCount >= TICKS_TO_WAIT ) 00593 { 00594 // Unblock the task by releasing the semaphore. 00595 xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken ); 00596 00597 // Reset the count so we release the semaphore again in 10 ticks time. 00598 ucLocalTickCount = 0; 00599 } 00600 00601 if( xHigherPriorityTaskWoken != pdFALSE ) 00602 { 00603 // We can force a context switch here. Context switching from an 00604 // ISR uses port specific syntax. Check the demo task for your port 00605 // to find the syntax required. 00606 } 00607 } 00608 </pre> 00609 * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR 00610 * \ingroup Semaphores 00611 */ 00612 #define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) 00613 00614 /** 00615 * semphr. h 00616 * <pre> 00617 xSemaphoreTakeFromISR( 00618 SemaphoreHandle_t xSemaphore, 00619 BaseType_t *pxHigherPriorityTaskWoken 00620 )</pre> 00621 * 00622 * <i>Macro</i> to take a semaphore from an ISR. The semaphore must have 00623 * previously been created with a call to vSemaphoreCreateBinary() or 00624 * xSemaphoreCreateCounting(). 00625 * 00626 * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) 00627 * must not be used with this macro. 00628 * 00629 * This macro can be used from an ISR, however taking a semaphore from an ISR 00630 * is not a common operation. It is likely to only be useful when taking a 00631 * counting semaphore when an interrupt is obtaining an object from a resource 00632 * pool (when the semaphore count indicates the number of resources available). 00633 * 00634 * @param xSemaphore A handle to the semaphore being taken. This is the 00635 * handle returned when the semaphore was created. 00636 * 00637 * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set 00638 * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task 00639 * to unblock, and the unblocked task has a priority higher than the currently 00640 * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then 00641 * a context switch should be requested before the interrupt is exited. 00642 * 00643 * @return pdTRUE if the semaphore was successfully taken, otherwise 00644 * pdFALSE 00645 */ 00646 #define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) 00647 00648 /** 00649 * semphr. h 00650 * <pre>SemaphoreHandle_t xSemaphoreCreateMutex( void )</pre> 00651 * 00652 * <i>Macro</i> that implements a mutex semaphore by using the existing queue 00653 * mechanism. 00654 * 00655 * Mutexes created using this macro can be accessed using the xSemaphoreTake() 00656 * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and 00657 * xSemaphoreGiveRecursive() macros should not be used. 00658 * 00659 * This type of semaphore uses a priority inheritance mechanism so a task 00660 * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the 00661 * semaphore it is no longer required. 00662 * 00663 * Mutex type semaphores cannot be used from within interrupt service routines. 00664 * 00665 * See vSemaphoreCreateBinary() for an alternative implementation that can be 00666 * used for pure synchronisation (where one task or interrupt always 'gives' the 00667 * semaphore and another always 'takes' the semaphore) and from within interrupt 00668 * service routines. 00669 * 00670 * @return xSemaphore Handle to the created mutex semaphore. Should be of type 00671 * SemaphoreHandle_t. 00672 * 00673 * Example usage: 00674 <pre> 00675 SemaphoreHandle_t xSemaphore; 00676 00677 void vATask( void * pvParameters ) 00678 { 00679 // Semaphore cannot be used before a call to xSemaphoreCreateMutex(). 00680 // This is a macro so pass the variable in directly. 00681 xSemaphore = xSemaphoreCreateMutex(); 00682 00683 if( xSemaphore != NULL ) 00684 { 00685 // The semaphore was created successfully. 00686 // The semaphore can now be used. 00687 } 00688 } 00689 </pre> 00690 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex 00691 * \ingroup Semaphores 00692 */ 00693 #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) 00694 00695 00696 /** 00697 * semphr. h 00698 * <pre>SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )</pre> 00699 * 00700 * <i>Macro</i> that implements a recursive mutex by using the existing queue 00701 * mechanism. 00702 * 00703 * Mutexes created using this macro can be accessed using the 00704 * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The 00705 * xSemaphoreTake() and xSemaphoreGive() macros should not be used. 00706 * 00707 * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex 00708 * doesn't become available again until the owner has called 00709 * xSemaphoreGiveRecursive() for each successful 'take' request. For example, 00710 * if a task successfully 'takes' the same mutex 5 times then the mutex will 00711 * not be available to any other task until it has also 'given' the mutex back 00712 * exactly five times. 00713 * 00714 * This type of semaphore uses a priority inheritance mechanism so a task 00715 * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the 00716 * semaphore it is no longer required. 00717 * 00718 * Mutex type semaphores cannot be used from within interrupt service routines. 00719 * 00720 * See vSemaphoreCreateBinary() for an alternative implementation that can be 00721 * used for pure synchronisation (where one task or interrupt always 'gives' the 00722 * semaphore and another always 'takes' the semaphore) and from within interrupt 00723 * service routines. 00724 * 00725 * @return xSemaphore Handle to the created mutex semaphore. Should be of type 00726 * SemaphoreHandle_t. 00727 * 00728 * Example usage: 00729 <pre> 00730 SemaphoreHandle_t xSemaphore; 00731 00732 void vATask( void * pvParameters ) 00733 { 00734 // Semaphore cannot be used before a call to xSemaphoreCreateMutex(). 00735 // This is a macro so pass the variable in directly. 00736 xSemaphore = xSemaphoreCreateRecursiveMutex(); 00737 00738 if( xSemaphore != NULL ) 00739 { 00740 // The semaphore was created successfully. 00741 // The semaphore can now be used. 00742 } 00743 } 00744 </pre> 00745 * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex 00746 * \ingroup Semaphores 00747 */ 00748 #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) 00749 00750 /** 00751 * semphr. h 00752 * <pre>SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )</pre> 00753 * 00754 * <i>Macro</i> that creates a counting semaphore by using the existing 00755 * queue mechanism. 00756 * 00757 * Counting semaphores are typically used for two things: 00758 * 00759 * 1) Counting events. 00760 * 00761 * In this usage scenario an event handler will 'give' a semaphore each time 00762 * an event occurs (incrementing the semaphore count value), and a handler 00763 * task will 'take' a semaphore each time it processes an event 00764 * (decrementing the semaphore count value). The count value is therefore 00765 * the difference between the number of events that have occurred and the 00766 * number that have been processed. In this case it is desirable for the 00767 * initial count value to be zero. 00768 * 00769 * 2) Resource management. 00770 * 00771 * In this usage scenario the count value indicates the number of resources 00772 * available. To obtain control of a resource a task must first obtain a 00773 * semaphore - decrementing the semaphore count value. When the count value 00774 * reaches zero there are no free resources. When a task finishes with the 00775 * resource it 'gives' the semaphore back - incrementing the semaphore count 00776 * value. In this case it is desirable for the initial count value to be 00777 * equal to the maximum count value, indicating that all resources are free. 00778 * 00779 * @param uxMaxCount The maximum count value that can be reached. When the 00780 * semaphore reaches this value it can no longer be 'given'. 00781 * 00782 * @param uxInitialCount The count value assigned to the semaphore when it is 00783 * created. 00784 * 00785 * @return Handle to the created semaphore. Null if the semaphore could not be 00786 * created. 00787 * 00788 * Example usage: 00789 <pre> 00790 SemaphoreHandle_t xSemaphore; 00791 00792 void vATask( void * pvParameters ) 00793 { 00794 SemaphoreHandle_t xSemaphore = NULL; 00795 00796 // Semaphore cannot be used before a call to xSemaphoreCreateCounting(). 00797 // The max value to which the semaphore can count should be 10, and the 00798 // initial value assigned to the count should be 0. 00799 xSemaphore = xSemaphoreCreateCounting( 10, 0 ); 00800 00801 if( xSemaphore != NULL ) 00802 { 00803 // The semaphore was created successfully. 00804 // The semaphore can now be used. 00805 } 00806 } 00807 </pre> 00808 * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting 00809 * \ingroup Semaphores 00810 */ 00811 #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) 00812 00813 /** 00814 * semphr. h 00815 * <pre>void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );</pre> 00816 * 00817 * Delete a semaphore. This function must be used with care. For example, 00818 * do not delete a mutex type semaphore if the mutex is held by a task. 00819 * 00820 * @param xSemaphore A handle to the semaphore to be deleted. 00821 * 00822 * \defgroup vSemaphoreDelete vSemaphoreDelete 00823 * \ingroup Semaphores 00824 */ 00825 #define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) 00826 00827 /** 00828 * semphr.h 00829 * <pre>TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );</pre> 00830 * 00831 * If xMutex is indeed a mutex type semaphore, return the current mutex holder. 00832 * If xMutex is not a mutex type semaphore, or the mutex is available (not held 00833 * by a task), return NULL. 00834 * 00835 * Note: This is a good way of determining if the calling task is the mutex 00836 * holder, but not a good way of determining the identity of the mutex holder as 00837 * the holder may change between the function exiting and the returned value 00838 * being tested. 00839 */ 00840 #define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) 00841 00842 #endif /* SEMAPHORE_H */ 00843 00844 00845
Generated on Wed Jul 13 2022 15:58:46 by 1.7.2