2 FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
\r
5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 This file is part of the FreeRTOS distribution.
\r
9 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
10 the terms of the GNU General Public License (version 2) as published by the
\r
11 Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
\r
13 ***************************************************************************
\r
14 >>! NOTE: The modification to the GPL is included to allow you to !<<
\r
15 >>! distribute a combined work that includes FreeRTOS without being !<<
\r
16 >>! obliged to provide the source code for proprietary components !<<
\r
17 >>! outside of the FreeRTOS kernel. !<<
\r
18 ***************************************************************************
\r
20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
\r
21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
\r
22 FOR A PARTICULAR PURPOSE. Full license text is available on the following
\r
23 link: http://www.freertos.org/a00114.html
\r
25 ***************************************************************************
\r
27 * FreeRTOS provides completely free yet professionally developed, *
\r
28 * robust, strictly quality controlled, supported, and cross *
\r
29 * platform software that is more than just the market leader, it *
\r
30 * is the industry's de facto standard. *
\r
32 * Help yourself get started quickly while simultaneously helping *
\r
33 * to support the FreeRTOS project by purchasing a FreeRTOS *
\r
34 * tutorial book, reference manual, or both: *
\r
35 * http://www.FreeRTOS.org/Documentation *
\r
37 ***************************************************************************
\r
39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
\r
40 the FAQ page "My application does not run, what could be wrong?". Have you
\r
41 defined configASSERT()?
\r
43 http://www.FreeRTOS.org/support - In return for receiving this top quality
\r
44 embedded software for free we request you assist our global community by
\r
45 participating in the support forum.
\r
47 http://www.FreeRTOS.org/training - Investing in training allows your team to
\r
48 be as productive as possible as early as possible. Now you can receive
\r
49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
\r
50 Ltd, and the world's leading authority on the world's leading RTOS.
\r
52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
\r
54 compatible FAT file system, and our tiny thread aware UDP/IP stack.
\r
56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
\r
57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
\r
59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
\r
60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
\r
61 licenses offer ticketed support, indemnification and commercial middleware.
\r
63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
\r
64 engineered and independently SIL3 certified version for use in safety and
\r
65 mission critical applications that require provable dependability.
\r
72 * Demonstrates how to create FreeRTOS objects using pre-allocated memory,
\r
73 * rather than the normal dynamically allocated memory.
\r
75 * Two buffers are required by a task - one that is used by the task as its
\r
76 * stack, and one that holds the task's control block (TCB).
\r
77 * prvStaticallyAllocatedCreator() creates and deletes tasks with all
\r
78 * possible combinations of statically allocated and dynamically allocated
\r
82 /* Scheduler include files. */
\r
83 #include "FreeRTOS.h"
\r
88 /* Demo program include files. */
\r
89 #include "StaticAllocation.h"
\r
91 /* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */
\r
92 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
94 /* The priority at which the task that performs the tests is created. */
\r
95 #define staticTASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
97 /* The length of the queue, in items, not bytes, used in the queue static
\r
98 allocation tests. */
\r
99 #define staticQUEUE_LENGTH_IN_ITEMS ( 5 )
\r
101 /* A block time of 0 simply means "don't block". */
\r
102 #define staticDONT_BLOCK ( ( TickType_t ) 0 )
\r
104 /* Binary semaphores have a maximum count of 1. */
\r
105 #define staticBINARY_SEMAPHORE_MAX_COUNT ( 1 )
\r
108 /*-----------------------------------------------------------*/
\r
111 * A task that is created and deleted multiple times, using both statically and
\r
112 * dynamically allocated stack and TCB.
\r
114 static void prvStaticallyAllocatedTask( void *pvParameters );
\r
117 * The task that repeatedly creates and deletes statically allocated tasks, and
\r
118 * other RTOS objects.
\r
120 static void prvStaticallyAllocatedCreator( void *pvParameters );
\r
123 * Utility function to create pseudo random numbers.
\r
125 static UBaseType_t prvRand( void );
\r
128 * A function that demonstrates and tests the xTaskCreateStatic() API function
\r
129 * by creating and then deleting tasks with both dynamically and statically
\r
130 * allocated TCBs and stacks.
\r
132 static void prvCreateAndDeleteStaticallyAllocatedTasks( void );
\r
135 * A function that demonstrates and tests the xQueueCreateStatic() API function
\r
136 * by creating and then deleting queues with both dynamically and statically
\r
137 * allocated queue structures and queue storage areas.
\r
139 static void prvCreateAndDeleteStaticallyAllocatedQueues( void );
\r
142 * A function that demonstrates and tests the xSemaphoreCreateBinaryStatic() API
\r
143 * macro by creating and then deleting binary semaphores with both dynamically
\r
144 * and statically allocated semaphore structures.
\r
146 static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void );
\r
149 * The task that creates and deletes other tasks has to delay occasionally to
\r
150 * ensure lower priority tasks are not starved of processing time. A pseudo
\r
151 * random delay time is used just to add a little bit of randomisation into the
\r
152 * execution pattern. prvGetNextDelayTime() generates the pseudo random delay.
\r
154 static TickType_t prvGetNextDelayTime( void );
\r
157 * Checks the basic operation of a queue after it has been created.
\r
159 static void prvCheckQueueFunction( QueueHandle_t xQueue );
\r
162 * Checks the basic operation of a binary semaphore after it has been created.
\r
164 static void prvCheckSemaphoreFunction( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount );
\r
166 /*-----------------------------------------------------------*/
\r
168 /* StaticTCB_t is a publicly accessible structure that has the same size and
\r
169 alignment requirements as the real TCB structure. It is provided as a mechanism
\r
170 for applications to know the size of the TCB (which is dependent on the
\r
171 architecture and configuration file settings) without breaking the strict data
\r
172 hiding policy by exposing the real TCB. This StaticTCB_t variable is passed
\r
173 into the xTaskCreateStatic() function that creates the
\r
174 prvStaticallyAllocatedCreator() task, and will hold the TCB of the created
\r
176 static StaticTCB_t xCreatorTaskTCBBuffer;
\r
178 /* This is the stack that will be used by the prvStaticallyAllocatedCreator()
\r
179 task, which is itself created using statically allocated buffers (so without any
\r
180 dynamic memory allocation). */
\r
181 static StackType_t uxCreatorTaskStackBuffer[ configMINIMAL_STACK_SIZE ];
\r
183 /* Used by the pseudo random number generating function. */
\r
184 static uint32_t ulNextRand = 0;
\r
186 /* Used so a check task can ensure this test is still executing, and not
\r
188 static volatile UBaseType_t uxCycleCounter = 0;
\r
190 /* A variable that gets set to pdTRUE if an error is detected. */
\r
191 static BaseType_t xErrorOccurred = pdFALSE;
\r
193 /*-----------------------------------------------------------*/
\r
195 void vStartStaticallyAllocatedTasks( void )
\r
197 /* Create a single task, which then repeatedly creates and deletes the
\r
198 task implemented by prvStaticallyAllocatedTask() at various different
\r
199 priorities, and both with and without statically allocated TCB and stack. */
\r
200 xTaskCreateStatic( prvStaticallyAllocatedCreator, /* The function that implements the task being created. */
\r
201 "StatCreate", /* Text name for the task - not used by the RTOS, its just to assist debugging. */
\r
202 configMINIMAL_STACK_SIZE, /* Size of the buffer passed in as the stack - in words, not bytes! */
\r
203 NULL, /* Parameter passed into the task - not used in this case. */
\r
204 staticTASK_PRIORITY, /* Priority of the task. */
\r
205 NULL, /* Handle of the task being created, not used in this case. */
\r
206 &( uxCreatorTaskStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
\r
207 &xCreatorTaskTCBBuffer ); /* The variable that will hold the task's TCB. */
\r
209 /* Pseudo seed the random number generator. */
\r
210 ulNextRand = ( uint32_t ) prvRand;
\r
212 /*-----------------------------------------------------------*/
\r
214 static void prvStaticallyAllocatedCreator( void *pvParameters )
\r
216 /* Avoid compiler warnings. */
\r
217 ( void ) pvParameters;
\r
221 prvCreateAndDeleteStaticallyAllocatedTasks();
\r
222 prvCreateAndDeleteStaticallyAllocatedQueues();
\r
223 prvCreateAndDeleteStaticallyAllocatedBinarySemaphores();
\r
226 /*-----------------------------------------------------------*/
\r
228 static void prvCheckSemaphoreFunction( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount )
\r
230 BaseType_t xReturned;
\r
232 const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 );
\r
233 TickType_t xTickCount;
\r
235 /* The binary semaphore should start 'empty', so a call to xSemaphoreTake()
\r
237 xTickCount = xTaskGetTickCount();
\r
238 xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );
\r
240 if( ( xTaskGetTickCount() - xTickCount) < xShortBlockTime )
\r
242 /* Did not block on the semaphore as long as expected. */
\r
243 xErrorOccurred = pdTRUE;
\r
246 if( xReturned != pdFAIL )
\r
248 xErrorOccurred = pdTRUE;
\r
251 /* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount
\r
253 for( x = 0; x < uxMaxCount; x++ )
\r
255 xReturned = xSemaphoreGive( xSemaphore );
\r
257 if( xReturned == pdFAIL )
\r
259 xErrorOccurred = pdTRUE;
\r
263 /* Giving the semaphore again should fail, as it is 'full'. */
\r
264 xReturned = xSemaphoreGive( xSemaphore );
\r
266 if( xReturned != pdFAIL )
\r
268 xErrorOccurred = pdTRUE;
\r
271 configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount );
\r
273 /* Should now be possible to 'take' the semaphore up to a maximum of
\r
274 uxMaxCount times without blocking. */
\r
275 for( x = 0; x < uxMaxCount; x++ )
\r
277 xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );
\r
279 if( xReturned == pdFAIL )
\r
281 xErrorOccurred = pdTRUE;
\r
285 /* Back to the starting condition, where the semaphore should not be
\r
287 xTickCount = xTaskGetTickCount();
\r
288 xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );
\r
290 if( ( xTaskGetTickCount() - xTickCount) < xShortBlockTime )
\r
292 /* Did not block on the semaphore as long as expected. */
\r
293 xErrorOccurred = pdTRUE;
\r
296 if( xReturned != pdFAIL )
\r
298 xErrorOccurred = pdTRUE;
\r
301 configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );
\r
303 /*-----------------------------------------------------------*/
\r
305 static void prvCheckQueueFunction( QueueHandle_t xQueue )
\r
307 uint64_t ull, ullRead;
\r
308 BaseType_t xReturned, xLoop;
\r
310 /* This test is done twice to ensure the queue storage area wraps. */
\r
311 for( xLoop = 0; xLoop < 2; xLoop++ )
\r
313 /* A very basic test that the queue can be written to and read from as
\r
314 expected. First the queue should be empty. */
\r
315 xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );
\r
316 if( xReturned != errQUEUE_EMPTY )
\r
318 xErrorOccurred = pdTRUE;
\r
321 /* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS
\r
323 for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )
\r
325 xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );
\r
326 if( xReturned != pdPASS )
\r
328 xErrorOccurred = pdTRUE;
\r
332 /* Should not now be possible to write to the queue again. */
\r
333 xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );
\r
334 if( xReturned != errQUEUE_FULL )
\r
336 xErrorOccurred = pdTRUE;
\r
339 /* Now read back from the queue to ensure the data read back matches that
\r
341 for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )
\r
343 xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK );
\r
345 if( xReturned != pdPASS )
\r
347 xErrorOccurred = pdTRUE;
\r
350 if( ullRead != ull )
\r
352 xErrorOccurred = pdTRUE;
\r
356 /* The queue should be empty again. */
\r
357 xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );
\r
358 if( xReturned != errQUEUE_EMPTY )
\r
360 xErrorOccurred = pdTRUE;
\r
364 /*-----------------------------------------------------------*/
\r
366 static void prvCreateAndDeleteStaticallyAllocatedQueues( void )
\r
368 QueueHandle_t xQueue;
\r
370 /* StaticQueue_t is a publicly accessible structure that has the same size and
\r
371 alignment requirements as the real queue structure. It is provided as a
\r
372 mechanism for applications to know the size of the queue (which is dependent on
\r
373 the architecture and configuration file settings) without breaking the strict
\r
374 data hiding policy by exposing the real queue internals. This StaticQueue_t
\r
375 variable is passed into the xQueueCreateStatic() function calls within this
\r
377 static StaticQueue_t xStaticQueue;
\r
379 /* The queue storage area must be large enough to hold the maximum number of
\r
380 items it is possible for the queue to hold at any one time, which equals the
\r
381 queue length (in items, not bytes) multiplied by the size of each item. In this
\r
382 case the queue will hold staticQUEUE_LENGTH_IN_ITEMS 64-bit items. See
\r
383 http://www.freertos.org/Embedded-RTOS-Queues.html */
\r
384 static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ];
\r
386 /* Create the queue. xQueueCreateStatic() has two more parameters than the
\r
387 usual xQueueCreate() function. The first new paraemter is a pointer to the
\r
388 pre-allocated queue storage area. The second new parameter is a pointer to
\r
389 the StaticQueue_t structure that will hold the queue state information in
\r
390 an anonymous way. If either pointer is passed as NULL then the respective
\r
391 data will be allocated dynamically as if xQueueCreate() had been called. */
\r
392 xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
\r
393 sizeof( uint64_t ), /* The size of each item. */
\r
394 ucQueueStorageArea, /* The buffer used to hold items within the queue. */
\r
395 &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */
\r
397 /* The queue handle should equal the static queue structure passed into the
\r
398 xQueueCreateStatic() function. */
\r
399 configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );
\r
401 /* Ensure the queue passes a few sanity checks as a valid queue. */
\r
402 prvCheckQueueFunction( xQueue );
\r
404 /* Delete the queue again so the buffers can be reused. */
\r
405 vQueueDelete( xQueue );
\r
408 /* The queue created above had a statically allocated queue storage area and
\r
409 queue structure. Repeat the above with three more times - with different
\r
410 combinations of static and dynamic allocation. */
\r
412 xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
\r
413 sizeof( uint64_t ), /* The size of each item. */
\r
414 NULL, /* Allocate the buffer used to hold items within the queue dynamically. */
\r
415 &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */
\r
417 configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );
\r
418 prvCheckQueueFunction( xQueue );
\r
419 vQueueDelete( xQueue );
\r
421 /* Ensure lower priority tasks get CPU time. */
\r
422 vTaskDelay( prvGetNextDelayTime() );
\r
424 /* Just to show the check task that this task is still executing. */
\r
427 xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
\r
428 sizeof( uint64_t ), /* The size of each item. */
\r
429 ucQueueStorageArea, /* The buffer used to hold items within the queue. */
\r
430 NULL ); /* The queue structure is allocated dynamically. */
\r
432 prvCheckQueueFunction( xQueue );
\r
433 vQueueDelete( xQueue );
\r
435 xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
\r
436 sizeof( uint64_t ), /* The size of each item. */
\r
437 NULL, /* Allocate the buffer used to hold items within the queue dynamically. */
\r
438 NULL ); /* The queue structure is allocated dynamically. */
\r
440 prvCheckQueueFunction( xQueue );
\r
441 vQueueDelete( xQueue );
\r
443 /* Ensure lower priority tasks get CPU time. */
\r
444 vTaskDelay( prvGetNextDelayTime() );
\r
446 /* Just to show the check task that this task is still executing. */
\r
449 /*-----------------------------------------------------------*/
\r
451 static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void )
\r
453 SemaphoreHandle_t xSemaphore;
\r
455 /* StaticSemaphore_t is a publicly accessible structure that has the same size
\r
456 and alignment requirements as the real semaphore structure. It is provided as a
\r
457 mechanism for applications to know the size of the semaphore (which is dependent
\r
458 on the architecture and configuration file settings) without breaking the strict
\r
459 data hiding policy by exposing the real semaphore internals. This
\r
460 StaticSemaphore_t variable is passed into the xSemaphoreCreateBinary() function
\r
461 calls within this function. NOTE: In most usage scenarios now it is faster and
\r
462 more memory efficient to use a direct to task notification instead of a binary
\r
463 semaphore. http://www.freertos.org/RTOS-task-notifications.html */
\r
464 static StaticSemaphore_t xSemaphoreBuffer; /* Static so it doesn't use too much stack space. */
\r
466 /* Create the semaphore. xSemaphoreCreateBinaryStatic() has one more
\r
467 parameter than the usual xSemaphoreCreateBinary() function. The paraemter
\r
468 is a pointer to the pre-allocated StaticSemaphore_t structure, which will
\r
469 hold information on the semaphore in an anonymous way. If the pointer is
\r
470 passed as NULL then the structure will be allocated dynamically, just as
\r
471 when xSemaphoreCreateBinary() is called. */
\r
472 xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
\r
474 /* The semaphore handle should equal the static semaphore structure passed
\r
475 into the xSemaphoreCreateBinaryStatic() function. */
\r
476 configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
\r
478 /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
\r
479 prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
\r
481 /* Delete the semaphore again so the buffers can be reused. */
\r
482 vSemaphoreDelete( xSemaphore );
\r
485 /* The semaphore created above had a statically allocated semaphore
\r
486 structure. Repeat the above using NULL as the xSemaphoreCreateBinaryStatic()
\r
487 parameter so the queue structure is instead allocated dynamically. */
\r
488 xSemaphore = xSemaphoreCreateBinaryStatic( NULL );
\r
490 /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
\r
491 prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
\r
493 /* Delete the semaphore again so the buffers can be reused. */
\r
494 vSemaphoreDelete( xSemaphore );
\r
498 /* There isn't a static version of the old and deprecated
\r
499 vSemaphoreCreateBinary() macro (because its deprecated!), but check it is
\r
500 still functioning correctly when configSUPPORT_STATIC_ALLOCATION is set to
\r
502 vSemaphoreCreateBinary( xSemaphore );
\r
504 /* The macro starts with the binary semaphore available, but the test
\r
505 function expects it to be unavailable. */
\r
506 if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL )
\r
508 xErrorOccurred = pdTRUE;
\r
511 prvCheckSemaphoreFunction( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
\r
512 vSemaphoreDelete( xSemaphore );
\r
514 /* Ensure lower priority tasks get CPU time. */
\r
515 vTaskDelay( prvGetNextDelayTime() );
\r
517 /* Just to show the check task that this task is still executing. */
\r
520 /*-----------------------------------------------------------*/
\r
522 static void prvCreateAndDeleteStaticallyAllocatedTasks( void )
\r
524 TaskHandle_t xCreatedTask;
\r
525 BaseType_t xReturned;
\r
527 /* The variable that will hold the TCB of tasks created by this function. See
\r
528 the comments above the declaration of the xCreatorTaskTCBBuffer variable for
\r
529 more information. */
\r
530 static StaticTCB_t xTCBBuffer; /* Static so it does not use too much stack space. */
\r
532 /* This buffer that will be used as the stack of tasks created by this function.
\r
533 See the comments above the declaration of the uxCreatorTaskStackBuffer[] array
\r
534 above for more information. */
\r
535 static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
\r
537 /* Create the task. xTaskCreateStatic() has two more parameters than
\r
538 the usual xTaskCreate() function. The first new parameter is a pointer to
\r
539 the pre-allocated stack. The second new parameter is a pointer to the
\r
540 StaticTCB_t structure that will hold the task's TCB. If either pointer is
\r
541 passed as NULL then the respective object will be allocated dynamically as
\r
542 if xTaskCreate() had been called. */
\r
543 xReturned = xTaskCreateStatic(
\r
544 prvStaticallyAllocatedTask, /* Function that implements the task. */
\r
545 "Static", /* Human readable name for the task. */
\r
546 configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
\r
547 NULL, /* Parameter to pass into the task. */
\r
548 tskIDLE_PRIORITY, /* The priority of the task. */
\r
549 &xCreatedTask, /* Handle of the task being created. */
\r
550 &( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
\r
551 &xTCBBuffer ); /* The variable that will hold that task's TCB. */
\r
553 /* Check the task was created correctly, then delete the task. */
\r
554 configASSERT( xReturned == pdPASS );
\r
555 if( xReturned != pdPASS )
\r
557 xErrorOccurred = pdTRUE;
\r
559 vTaskDelete( xCreatedTask );
\r
561 /* Ensure lower priority tasks get CPU time. */
\r
562 vTaskDelay( prvGetNextDelayTime() );
\r
564 /* Create and delete the task a few times again - testing both static and
\r
565 dynamic allocation for the stack and TCB. */
\r
566 xReturned = xTaskCreateStatic(
\r
567 prvStaticallyAllocatedTask, /* Function that implements the task. */
\r
568 "Static", /* Human readable name for the task. */
\r
569 configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
\r
570 NULL, /* Parameter to pass into the task. */
\r
571 staticTASK_PRIORITY + 1, /* The priority of the task. */
\r
572 &xCreatedTask, /* Handle of the task being created. */
\r
573 NULL, /* This time, dynamically allocate the stack. */
\r
574 &xTCBBuffer ); /* The variable that will hold that task's TCB. */
\r
576 configASSERT( xReturned == pdPASS );
\r
577 if( xReturned != pdPASS )
\r
579 xErrorOccurred = pdTRUE;
\r
581 vTaskDelete( xCreatedTask );
\r
583 /* Just to show the check task that this task is still executing. */
\r
586 /* Ensure lower priority tasks get CPU time. */
\r
587 vTaskDelay( prvGetNextDelayTime() );
\r
589 xReturned = xTaskCreateStatic(
\r
590 prvStaticallyAllocatedTask, /* Function that implements the task. */
\r
591 "Static", /* Human readable name for the task. */
\r
592 configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
\r
593 NULL, /* Parameter to pass into the task. */
\r
594 staticTASK_PRIORITY - 1, /* The priority of the task. */
\r
595 &xCreatedTask, /* Handle of the task being created. */
\r
596 &( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
\r
597 NULL ); /* This time dynamically allocate the TCB. */
\r
599 configASSERT( xReturned == pdPASS );
\r
600 if( xReturned != pdPASS )
\r
602 xErrorOccurred = pdTRUE;
\r
604 vTaskDelete( xCreatedTask );
\r
606 /* Ensure lower priority tasks get CPU time. */
\r
607 vTaskDelay( prvGetNextDelayTime() );
\r
609 xReturned = xTaskCreateStatic(
\r
610 prvStaticallyAllocatedTask, /* Function that implements the task. */
\r
611 "Static", /* Human readable name for the task. */
\r
612 configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
\r
613 NULL, /* Parameter to pass into the task. */
\r
614 staticTASK_PRIORITY, /* The priority of the task. */
\r
615 &xCreatedTask, /* Handle of the task being created. */
\r
616 NULL, /* This time dynamically allocate the stack and TCB. */
\r
617 NULL ); /* This time dynamically allocate the stack and TCB. */
\r
619 configASSERT( xReturned == pdPASS );
\r
620 if( xReturned != pdPASS )
\r
622 xErrorOccurred = pdTRUE;
\r
624 vTaskDelete( xCreatedTask );
\r
626 /* Ensure lower priority tasks get CPU time. */
\r
627 vTaskDelay( prvGetNextDelayTime() );
\r
629 /* Just to show the check task that this task is still executing. */
\r
632 /*-----------------------------------------------------------*/
\r
634 static void prvStaticallyAllocatedTask( void *pvParameters )
\r
636 ( void ) pvParameters;
\r
638 /* The created task doesn't do anything - just waits to get deleted. */
\r
639 vTaskSuspend( NULL );
\r
641 /*-----------------------------------------------------------*/
\r
643 static UBaseType_t prvRand( void )
\r
645 const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
\r
647 /* Utility function to generate a pseudo random number. */
\r
648 ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
\r
649 return( ( ulNextRand >> 16UL ) & 0x7fffUL );
\r
651 /*-----------------------------------------------------------*/
\r
653 static TickType_t prvGetNextDelayTime( void )
\r
655 TickType_t xNextDelay;
\r
656 const TickType_t xMaxDelay = pdMS_TO_TICKS( ( TickType_t ) 150 );
\r
657 const TickType_t xMinDelay = pdMS_TO_TICKS( ( TickType_t ) 75 );
\r
658 const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 );
\r
660 /* Generate the next delay time. This is kept within a narrow band so as
\r
661 not to disturb the timing of other tests - but does add in some pseudo
\r
662 randomisation into the tests. */
\r
665 xNextDelay = prvRand() % xMaxDelay;
\r
667 /* Just in case this loop is executed lots of times. */
\r
668 vTaskDelay( xTinyDelay );
\r
670 } while ( xNextDelay < xMinDelay );
\r
674 /*-----------------------------------------------------------*/
\r
676 BaseType_t xAreStaticAllocationTasksStillRunning( void )
\r
678 static UBaseType_t uxLastCycleCounter = 0;
\r
679 BaseType_t xReturn;
\r
681 if( uxCycleCounter == uxLastCycleCounter )
\r
683 xErrorOccurred = pdTRUE;
\r
687 uxLastCycleCounter = uxCycleCounter;
\r
690 if( xErrorOccurred != pdFALSE )
\r
701 /*-----------------------------------------------------------*/
\r
703 /* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */
\r
704 #endif /* configSUPPORT_STATIC_ALLOCATION == 1 */
\r