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, and tests objects being
\r
74 * created and deleted with both statically allocated memory and dynamically
\r
78 /* Scheduler include files. */
\r
79 #include "FreeRTOS.h"
\r
83 #include "event_groups.h"
\r
86 /* Demo program include files. */
\r
87 #include "StaticAllocation.h"
\r
89 /* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */
\r
90 #if( configSUPPORT_STATIC_ALLOCATION == 1 )
\r
92 /* The priority at which the task that performs the tests is created. */
\r
93 #define staticTASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
95 /* The length of the queue, in items, not bytes, used in the queue static
\r
96 allocation tests. */
\r
97 #define staticQUEUE_LENGTH_IN_ITEMS ( 5 )
\r
99 /* A block time of 0 simply means "don't block". */
\r
100 #define staticDONT_BLOCK ( ( TickType_t ) 0 )
\r
102 /* Binary semaphores have a maximum count of 1. */
\r
103 #define staticBINARY_SEMAPHORE_MAX_COUNT ( 1 )
\r
105 /* The size of the stack used by the task that runs the tests. */
\r
106 #define staticCREATOR_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 )
\r
108 /* The number of times the software timer will execute before stopping itself. */
\r
109 #define staticMAX_TIMER_CALLBACK_EXECUTIONS ( 5 )
\r
112 /*-----------------------------------------------------------*/
\r
115 * The task that repeatedly creates and deletes statically allocated tasks, and
\r
116 * other RTOS objects.
\r
118 static void prvStaticallyAllocatedCreator( void *pvParameters );
\r
121 * The callback function used by the software timer that is repeatedly created
\r
122 * and deleted using both static and dynamically allocated memory.
\r
124 static void prvTimerCallback( TimerHandle_t xExpiredTimer );
\r
127 * A task that is created and deleted multiple times, using both statically and
\r
128 * dynamically allocated stack and TCB.
\r
130 static void prvStaticallyAllocatedTask( void *pvParameters );
\r
133 * A function that demonstrates and tests the xTaskCreateStatic() API function
\r
134 * by creating and then deleting tasks with both dynamically and statically
\r
135 * allocated TCBs and stacks.
\r
137 static void prvCreateAndDeleteStaticallyAllocatedTasks( void );
\r
140 * A function that demonstrates and tests the xEventGroupCreateStatic() API
\r
141 * function by creating and then deleting event groups using both dynamically
\r
142 * and statically allocated event group structures.
\r
144 static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void );
\r
147 * A function that demonstrates and tests the xQueueCreateStatic() API function
\r
148 * by creating and then deleting queues with both dynamically and statically
\r
149 * allocated queue structures and queue storage areas.
\r
151 static void prvCreateAndDeleteStaticallyAllocatedQueues( void );
\r
154 * A function that demonstrates and tests the xSemaphoreCreateBinaryStatic() API
\r
155 * macro by creating and then deleting binary semaphores with both dynamically
\r
156 * and statically allocated semaphore structures.
\r
158 static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void );
\r
161 * A function that demonstrates and tests the xTimerCreateStatic() API macro by
\r
162 * creating and then deleting software timers with both dynamically and
\r
163 * statically allocated timer structures.
\r
165 static void prvCreateAndDeleteStaticallyAllocatedTimers( void );
\r
168 * A function that demonstrates and tests the xSemaphoreCreateMutexStatic() API
\r
169 * macro by creating and then deleting mutexes with both dynamically and
\r
170 * statically allocated semaphore structures.
\r
172 static void prvCreateAndDeleteStaticallyAllocatedMutexes( void );
\r
175 * A function that demonstrates and tests the xSemaphoreCreateCountingStatic()
\r
176 * API macro by creating and then deleting counting semaphores with both
\r
177 * dynamically and statically allocated semaphore structures.
\r
179 static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void );
\r
182 * A function that demonstrates and tests the
\r
183 * xSemaphoreCreateRecursiveMutexStatic() API macro by creating and then
\r
184 * deleting recursive mutexes with both dynamically and statically allocated
\r
185 * semaphore structures.
\r
187 static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void );
\r
190 * Utility function to create pseudo random numbers.
\r
192 static UBaseType_t prvRand( void );
\r
195 * The task that creates and deletes other tasks has to delay occasionally to
\r
196 * ensure lower priority tasks are not starved of processing time. A pseudo
\r
197 * random delay time is used just to add a little bit of randomisation into the
\r
198 * execution pattern. prvGetNextDelayTime() generates the pseudo random delay.
\r
200 static TickType_t prvGetNextDelayTime( void );
\r
203 * Checks the basic operation of a queue after it has been created.
\r
205 static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue );
\r
208 * Checks the basic operation of a recursive mutex after it has been created.
\r
210 static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore );
\r
213 * Checks the basic operation of a binary semaphore after it has been created.
\r
215 static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount );
\r
218 * Checks the basic operation of an event group after it has been created.
\r
220 static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup );
\r
222 /*-----------------------------------------------------------*/
\r
224 /* StaticTask_t is a publicly accessible structure that has the same size and
\r
225 alignment requirements as the real TCB structure. It is provided as a mechanism
\r
226 for applications to know the size of the TCB (which is dependent on the
\r
227 architecture and configuration file settings) without breaking the strict data
\r
228 hiding policy by exposing the real TCB. This StaticTask_t variable is passed
\r
229 into the xTaskCreateStatic() function that creates the
\r
230 prvStaticallyAllocatedCreator() task, and will hold the TCB of the created
\r
232 static StaticTask_t xCreatorTaskTCBBuffer;
\r
234 /* This is the stack that will be used by the prvStaticallyAllocatedCreator()
\r
235 task, which is itself created using statically allocated buffers (so without any
\r
236 dynamic memory allocation). */
\r
237 static StackType_t uxCreatorTaskStackBuffer[ staticCREATOR_TASK_STACK_SIZE ];
\r
239 /* Used by the pseudo random number generating function. */
\r
240 static uint32_t ulNextRand = 0;
\r
242 /* Used so a check task can ensure this test is still executing, and not
\r
244 static volatile UBaseType_t uxCycleCounter = 0;
\r
246 /* A variable that gets set to pdTRUE if an error is detected. */
\r
247 static BaseType_t xErrorOccurred = pdFALSE;
\r
249 /*-----------------------------------------------------------*/
\r
251 void vStartStaticallyAllocatedTasks( void )
\r
253 /* Create a single task, which then repeatedly creates and deletes the
\r
254 task implemented by prvStaticallyAllocatedTask() at various different
\r
255 priorities, and both with and without statically allocated TCB and stack. */
\r
256 xTaskCreateStatic( prvStaticallyAllocatedCreator, /* The function that implements the task being created. */
\r
257 "StatCreate", /* Text name for the task - not used by the RTOS, its just to assist debugging. */
\r
258 staticCREATOR_TASK_STACK_SIZE, /* Size of the buffer passed in as the stack - in words, not bytes! */
\r
259 NULL, /* Parameter passed into the task - not used in this case. */
\r
260 staticTASK_PRIORITY, /* Priority of the task. */
\r
261 NULL, /* Handle of the task being created, not used in this case. */
\r
262 &( uxCreatorTaskStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
\r
263 &xCreatorTaskTCBBuffer ); /* The variable that will hold the task's TCB. */
\r
265 /* Pseudo seed the random number generator. */
\r
266 ulNextRand = ( uint32_t ) prvRand;
\r
268 /*-----------------------------------------------------------*/
\r
270 static void prvStaticallyAllocatedCreator( void *pvParameters )
\r
272 /* Avoid compiler warnings. */
\r
273 ( void ) pvParameters;
\r
277 /* Loop, running functions that create and delete the various objects
\r
278 that can be optionally created using either static or dynamic memory
\r
280 prvCreateAndDeleteStaticallyAllocatedTasks();
\r
281 prvCreateAndDeleteStaticallyAllocatedQueues();
\r
282 prvCreateAndDeleteStaticallyAllocatedBinarySemaphores();
\r
283 prvCreateAndDeleteStaticallyAllocatedCountingSemaphores();
\r
284 prvCreateAndDeleteStaticallyAllocatedMutexes();
\r
285 prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes();
\r
286 prvCreateAndDeleteStaticallyAllocatedEventGroups();
\r
287 prvCreateAndDeleteStaticallyAllocatedTimers();
\r
290 /*-----------------------------------------------------------*/
\r
292 static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup )
\r
294 EventBits_t xEventBits;
\r
295 const EventBits_t xFirstTestBits = ( EventBits_t ) 0xaa, xSecondTestBits = ( EventBits_t ) 0x55;
\r
297 /* The event group should not have any bits set yet. */
\r
298 xEventBits = xEventGroupGetBits( xEventGroup );
\r
300 if( xEventBits != ( EventBits_t ) 0 )
\r
302 xErrorOccurred = pdTRUE;
\r
305 /* Some some bits, then read them back to check they are as expected. */
\r
306 xEventGroupSetBits( xEventGroup, xFirstTestBits );
\r
308 xEventBits = xEventGroupGetBits( xEventGroup );
\r
310 if( xEventBits != xFirstTestBits )
\r
312 xErrorOccurred = pdTRUE;
\r
315 xEventGroupSetBits( xEventGroup, xSecondTestBits );
\r
317 xEventBits = xEventGroupGetBits( xEventGroup );
\r
319 if( xEventBits != ( xFirstTestBits | xSecondTestBits ) )
\r
321 xErrorOccurred = pdTRUE;
\r
324 /* Finally try clearing some bits too and check that operation proceeds as
\r
326 xEventGroupClearBits( xEventGroup, xFirstTestBits );
\r
328 xEventBits = xEventGroupGetBits( xEventGroup );
\r
330 if( xEventBits != xSecondTestBits )
\r
332 xErrorOccurred = pdTRUE;
\r
335 /*-----------------------------------------------------------*/
\r
337 static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount )
\r
339 BaseType_t xReturned;
\r
341 const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 );
\r
342 TickType_t xTickCount;
\r
344 /* The binary semaphore should start 'empty', so a call to xSemaphoreTake()
\r
346 xTickCount = xTaskGetTickCount();
\r
347 xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );
\r
349 if( ( xTaskGetTickCount() - xTickCount) < xShortBlockTime )
\r
351 /* Did not block on the semaphore as long as expected. */
\r
352 xErrorOccurred = pdTRUE;
\r
355 if( xReturned != pdFAIL )
\r
357 xErrorOccurred = pdTRUE;
\r
360 /* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount
\r
362 for( x = 0; x < uxMaxCount; x++ )
\r
364 xReturned = xSemaphoreGive( xSemaphore );
\r
366 if( xReturned == pdFAIL )
\r
368 xErrorOccurred = pdTRUE;
\r
372 /* Giving the semaphore again should fail, as it is 'full'. */
\r
373 xReturned = xSemaphoreGive( xSemaphore );
\r
375 if( xReturned != pdFAIL )
\r
377 xErrorOccurred = pdTRUE;
\r
380 configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount );
\r
382 /* Should now be possible to 'take' the semaphore up to a maximum of
\r
383 uxMaxCount times without blocking. */
\r
384 for( x = 0; x < uxMaxCount; x++ )
\r
386 xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );
\r
388 if( xReturned == pdFAIL )
\r
390 xErrorOccurred = pdTRUE;
\r
394 /* Back to the starting condition, where the semaphore should not be
\r
396 xTickCount = xTaskGetTickCount();
\r
397 xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime );
\r
399 if( ( xTaskGetTickCount() - xTickCount) < xShortBlockTime )
\r
401 /* Did not block on the semaphore as long as expected. */
\r
402 xErrorOccurred = pdTRUE;
\r
405 if( xReturned != pdFAIL )
\r
407 xErrorOccurred = pdTRUE;
\r
410 configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 );
\r
412 /*-----------------------------------------------------------*/
\r
414 static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue )
\r
416 uint64_t ull, ullRead;
\r
417 BaseType_t xReturned, xLoop;
\r
419 /* This test is done twice to ensure the queue storage area wraps. */
\r
420 for( xLoop = 0; xLoop < 2; xLoop++ )
\r
422 /* A very basic test that the queue can be written to and read from as
\r
423 expected. First the queue should be empty. */
\r
424 xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );
\r
425 if( xReturned != errQUEUE_EMPTY )
\r
427 xErrorOccurred = pdTRUE;
\r
430 /* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS
\r
432 for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )
\r
434 xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );
\r
435 if( xReturned != pdPASS )
\r
437 xErrorOccurred = pdTRUE;
\r
441 /* Should not now be possible to write to the queue again. */
\r
442 xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK );
\r
443 if( xReturned != errQUEUE_FULL )
\r
445 xErrorOccurred = pdTRUE;
\r
448 /* Now read back from the queue to ensure the data read back matches that
\r
450 for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ )
\r
452 xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK );
\r
454 if( xReturned != pdPASS )
\r
456 xErrorOccurred = pdTRUE;
\r
459 if( ullRead != ull )
\r
461 xErrorOccurred = pdTRUE;
\r
465 /* The queue should be empty again. */
\r
466 xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK );
\r
467 if( xReturned != errQUEUE_EMPTY )
\r
469 xErrorOccurred = pdTRUE;
\r
473 /*-----------------------------------------------------------*/
\r
475 static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore )
\r
477 const BaseType_t xLoops = 5;
\r
478 BaseType_t x, xReturned;
\r
480 /* A very basic test that the recursive semaphore behaved like a recursive
\r
481 semaphore. First the semaphore should not be able to be given, as it has not
\r
483 xReturned = xSemaphoreGiveRecursive( xSemaphore );
\r
485 if( xReturned != pdFAIL )
\r
487 xErrorOccurred = pdTRUE;
\r
490 /* Now it should be possible to take the mutex a number of times. */
\r
491 for( x = 0; x < xLoops; x++ )
\r
493 xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK );
\r
495 if( xReturned != pdPASS )
\r
497 xErrorOccurred = pdTRUE;
\r
501 /* Should be possible to give the semaphore the same number of times as it
\r
502 was given in the loop above. */
\r
503 for( x = 0; x < xLoops; x++ )
\r
505 xReturned = xSemaphoreGiveRecursive( xSemaphore );
\r
507 if( xReturned != pdPASS )
\r
509 xErrorOccurred = pdTRUE;
\r
513 /* No more gives should be possible though. */
\r
514 xReturned = xSemaphoreGiveRecursive( xSemaphore );
\r
516 if( xReturned != pdFAIL )
\r
518 xErrorOccurred = pdTRUE;
\r
521 /*-----------------------------------------------------------*/
\r
523 static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void )
\r
525 SemaphoreHandle_t xSemaphore;
\r
526 const UBaseType_t uxMaxCount = ( UBaseType_t ) 10;
\r
528 /* StaticSemaphore_t is a publicly accessible structure that has the same size
\r
529 and alignment requirements as the real semaphore structure. It is provided as a
\r
530 mechanism for applications to know the size of the semaphore (which is dependent
\r
531 on the architecture and configuration file settings) without breaking the strict
\r
532 data hiding policy by exposing the real semaphore internals. This
\r
533 StaticSemaphore_t variable is passed into the xSemaphoreCreateCountingStatic()
\r
534 function calls within this function. NOTE: In most usage scenarios now it is
\r
535 faster and more memory efficient to use a direct to task notification instead of
\r
536 a counting semaphore. http://www.freertos.org/RTOS-task-notifications.html */
\r
537 StaticSemaphore_t xSemaphoreBuffer;
\r
539 /* Create the semaphore. xSemaphoreCreateCountingStatic() has one more
\r
540 parameter than the usual xSemaphoreCreateCounting() function. The paraemter
\r
541 is a pointer to the pre-allocated StaticSemaphore_t structure, which will
\r
542 hold information on the semaphore in an anonymous way. If the pointer is
\r
543 passed as NULL then the structure will be allocated dynamically, just as
\r
544 when xSemaphoreCreateCounting() is called. */
\r
545 xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, 0, &xSemaphoreBuffer );
\r
547 /* The semaphore handle should equal the static semaphore structure passed
\r
548 into the xSemaphoreCreateBinaryStatic() function. */
\r
549 configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
\r
551 /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
\r
552 prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount );
\r
554 /* Delete the semaphore again so the buffers can be reused. */
\r
555 vSemaphoreDelete( xSemaphore );
\r
558 /* The semaphore created above had a statically allocated semaphore
\r
559 structure. Repeat the above using NULL as the third
\r
560 xSemaphoreCreateCountingStatic() parameter so the semaphore structure is
\r
561 instead allocated dynamically. */
\r
562 xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, 0, NULL );
\r
564 /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
\r
565 prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount );
\r
567 /* Delete the semaphore again so the buffers can be reused. */
\r
568 vSemaphoreDelete( xSemaphore );
\r
570 /* Ensure lower priority tasks get CPU time. */
\r
571 vTaskDelay( prvGetNextDelayTime() );
\r
573 /* Just to show the check task that this task is still executing. */
\r
576 /*-----------------------------------------------------------*/
\r
578 static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void )
\r
580 SemaphoreHandle_t xSemaphore;
\r
582 /* StaticSemaphore_t is a publicly accessible structure that has the same size
\r
583 and alignment requirements as the real semaphore structure. It is provided as a
\r
584 mechanism for applications to know the size of the semaphore (which is dependent
\r
585 on the architecture and configuration file settings) without breaking the strict
\r
586 data hiding policy by exposing the real semaphore internals. This
\r
587 StaticSemaphore_t variable is passed into the
\r
588 xSemaphoreCreateRecursiveMutexStatic() function calls within this function. */
\r
589 StaticSemaphore_t xSemaphoreBuffer;
\r
591 /* Create the semaphore. xSemaphoreCreateRecursiveMutexStatic() has one
\r
592 more parameter than the usual xSemaphoreCreateRecursiveMutex() function.
\r
593 The parameter is a pointer to the pre-allocated StaticSemaphore_t structure,
\r
594 which will hold information on the semaphore in an anonymous way. If the
\r
595 pointer is passed as NULL then the structure will be allocated dynamically,
\r
596 just as when xSemaphoreCreateRecursiveMutex() is called. */
\r
597 xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xSemaphoreBuffer );
\r
599 /* The semaphore handle should equal the static semaphore structure passed
\r
600 into the xSemaphoreCreateBinaryStatic() function. */
\r
601 configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
\r
603 /* Ensure the semaphore passes a few sanity checks as a valid
\r
604 recursive semaphore. */
\r
605 prvSanityCheckCreatedRecursiveMutex( xSemaphore );
\r
607 /* Delete the semaphore again so the buffers can be reused. */
\r
608 vSemaphoreDelete( xSemaphore );
\r
611 /* The semaphore created above had a statically allocated semaphore
\r
612 structure. Repeat the above using NULL as the
\r
613 xSemaphoreCreateRecursiveMutexStatic() parameter so the semaphore structure
\r
614 is instead allocated dynamically. */
\r
615 xSemaphore = xSemaphoreCreateRecursiveMutexStatic( NULL );
\r
617 /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
\r
618 prvSanityCheckCreatedRecursiveMutex( xSemaphore );
\r
620 /* Delete the semaphore again so the buffers can be reused. */
\r
621 vSemaphoreDelete( xSemaphore );
\r
623 /* Ensure lower priority tasks get CPU time. */
\r
624 vTaskDelay( prvGetNextDelayTime() );
\r
626 /* Just to show the check task that this task is still executing. */
\r
629 /*-----------------------------------------------------------*/
\r
631 static void prvCreateAndDeleteStaticallyAllocatedQueues( void )
\r
633 QueueHandle_t xQueue;
\r
635 /* StaticQueue_t is a publicly accessible structure that has the same size and
\r
636 alignment requirements as the real queue structure. It is provided as a
\r
637 mechanism for applications to know the size of the queue (which is dependent on
\r
638 the architecture and configuration file settings) without breaking the strict
\r
639 data hiding policy by exposing the real queue internals. This StaticQueue_t
\r
640 variable is passed into the xQueueCreateStatic() function calls within this
\r
642 static StaticQueue_t xStaticQueue;
\r
644 /* The queue storage area must be large enough to hold the maximum number of
\r
645 items it is possible for the queue to hold at any one time, which equals the
\r
646 queue length (in items, not bytes) multiplied by the size of each item. In this
\r
647 case the queue will hold staticQUEUE_LENGTH_IN_ITEMS 64-bit items. See
\r
648 http://www.freertos.org/Embedded-RTOS-Queues.html */
\r
649 static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ];
\r
651 /* Create the queue. xQueueCreateStatic() has two more parameters than the
\r
652 usual xQueueCreate() function. The first new paraemter is a pointer to the
\r
653 pre-allocated queue storage area. The second new parameter is a pointer to
\r
654 the StaticQueue_t structure that will hold the queue state information in
\r
655 an anonymous way. If either pointer is passed as NULL then the respective
\r
656 data will be allocated dynamically as if xQueueCreate() had been called. */
\r
657 xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
\r
658 sizeof( uint64_t ), /* The size of each item. */
\r
659 ucQueueStorageArea, /* The buffer used to hold items within the queue. */
\r
660 &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */
\r
662 /* The queue handle should equal the static queue structure passed into the
\r
663 xQueueCreateStatic() function. */
\r
664 configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );
\r
666 /* Ensure the queue passes a few sanity checks as a valid queue. */
\r
667 prvSanityCheckCreatedQueue( xQueue );
\r
669 /* Delete the queue again so the buffers can be reused. */
\r
670 vQueueDelete( xQueue );
\r
673 /* The queue created above had a statically allocated queue storage area and
\r
674 queue structure. Repeat the above with three more times - with different
\r
675 combinations of static and dynamic allocation. */
\r
677 xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
\r
678 sizeof( uint64_t ), /* The size of each item. */
\r
679 NULL, /* Allocate the buffer used to hold items within the queue dynamically. */
\r
680 &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */
\r
682 configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue );
\r
683 prvSanityCheckCreatedQueue( xQueue );
\r
684 vQueueDelete( xQueue );
\r
686 /* Ensure lower priority tasks get CPU time. */
\r
687 vTaskDelay( prvGetNextDelayTime() );
\r
689 /* Just to show the check task that this task is still executing. */
\r
692 xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
\r
693 sizeof( uint64_t ), /* The size of each item. */
\r
694 ucQueueStorageArea, /* The buffer used to hold items within the queue. */
\r
695 NULL ); /* The queue structure is allocated dynamically. */
\r
697 prvSanityCheckCreatedQueue( xQueue );
\r
698 vQueueDelete( xQueue );
\r
700 xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */
\r
701 sizeof( uint64_t ), /* The size of each item. */
\r
702 NULL, /* Allocate the buffer used to hold items within the queue dynamically. */
\r
703 NULL ); /* The queue structure is allocated dynamically. */
\r
705 prvSanityCheckCreatedQueue( xQueue );
\r
706 vQueueDelete( xQueue );
\r
708 /* Ensure lower priority tasks get CPU time. */
\r
709 vTaskDelay( prvGetNextDelayTime() );
\r
711 /* Just to show the check task that this task is still executing. */
\r
714 /*-----------------------------------------------------------*/
\r
716 static void prvCreateAndDeleteStaticallyAllocatedMutexes( void )
\r
718 SemaphoreHandle_t xSemaphore;
\r
719 BaseType_t xReturned;
\r
721 /* StaticSemaphore_t is a publicly accessible structure that has the same size
\r
722 and alignment requirements as the real semaphore structure. It is provided as a
\r
723 mechanism for applications to know the size of the semaphore (which is dependent
\r
724 on the architecture and configuration file settings) without breaking the strict
\r
725 data hiding policy by exposing the real semaphore internals. This
\r
726 StaticSemaphore_t variable is passed into the xSemaphoreCreateMutexStatic()
\r
727 function calls within this function. */
\r
728 StaticSemaphore_t xSemaphoreBuffer;
\r
730 /* Create the semaphore. xSemaphoreCreateMutexStatic() has one more
\r
731 parameter than the usual xSemaphoreCreateMutex() function. The paraemter
\r
732 is a pointer to the pre-allocated StaticSemaphore_t structure, which will
\r
733 hold information on the semaphore in an anonymous way. If the pointer is
\r
734 passed as NULL then the structure will be allocated dynamically, just as
\r
735 when xSemaphoreCreateMutex() is called. */
\r
736 xSemaphore = xSemaphoreCreateMutexStatic( &xSemaphoreBuffer );
\r
738 /* The semaphore handle should equal the static semaphore structure passed
\r
739 into the xSemaphoreCreateMutexStatic() function. */
\r
740 configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
\r
742 /* Take the mutex so the mutex is in the state expected by the
\r
743 prvSanityCheckCreatedSemaphore() function. */
\r
744 xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );
\r
746 if( xReturned != pdPASS )
\r
748 xErrorOccurred = pdTRUE;
\r
751 /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
\r
752 prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
\r
754 /* Delete the semaphore again so the buffers can be reused. */
\r
755 vSemaphoreDelete( xSemaphore );
\r
758 /* The semaphore created above had a statically allocated semaphore
\r
759 structure. Repeat the above using NULL as the xSemaphoreCreateMutexStatic()
\r
760 parameter so the semaphore structure is instead allocated dynamically. */
\r
761 xSemaphore = xSemaphoreCreateMutexStatic( NULL );
\r
763 /* Take the mutex so the mutex is in the state expected by the
\r
764 prvSanityCheckCreatedSemaphore() function. */
\r
765 xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK );
\r
767 if( xReturned != pdPASS )
\r
769 xErrorOccurred = pdTRUE;
\r
772 /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
\r
773 prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
\r
775 /* Delete the semaphore again so the buffers can be reused. */
\r
776 vSemaphoreDelete( xSemaphore );
\r
778 /* Ensure lower priority tasks get CPU time. */
\r
779 vTaskDelay( prvGetNextDelayTime() );
\r
781 /* Just to show the check task that this task is still executing. */
\r
784 /*-----------------------------------------------------------*/
\r
786 static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void )
\r
788 SemaphoreHandle_t xSemaphore;
\r
790 /* StaticSemaphore_t is a publicly accessible structure that has the same size
\r
791 and alignment requirements as the real semaphore structure. It is provided as a
\r
792 mechanism for applications to know the size of the semaphore (which is dependent
\r
793 on the architecture and configuration file settings) without breaking the strict
\r
794 data hiding policy by exposing the real semaphore internals. This
\r
795 StaticSemaphore_t variable is passed into the xSemaphoreCreateBinaryStatic()
\r
796 function calls within this function. NOTE: In most usage scenarios now it is
\r
797 faster and more memory efficient to use a direct to task notification instead of
\r
798 a binary semaphore. http://www.freertos.org/RTOS-task-notifications.html */
\r
799 StaticSemaphore_t xSemaphoreBuffer;
\r
801 /* Create the semaphore. xSemaphoreCreateBinaryStatic() has one more
\r
802 parameter than the usual xSemaphoreCreateBinary() function. The paraemter
\r
803 is a pointer to the pre-allocated StaticSemaphore_t structure, which will
\r
804 hold information on the semaphore in an anonymous way. If the pointer is
\r
805 passed as NULL then the structure will be allocated dynamically, just as
\r
806 when xSemaphoreCreateBinary() is called. */
\r
807 xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer );
\r
809 /* The semaphore handle should equal the static semaphore structure passed
\r
810 into the xSemaphoreCreateBinaryStatic() function. */
\r
811 configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer );
\r
813 /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
\r
814 prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
\r
816 /* Delete the semaphore again so the buffers can be reused. */
\r
817 vSemaphoreDelete( xSemaphore );
\r
820 /* The semaphore created above had a statically allocated semaphore
\r
821 structure. Repeat the above using NULL as the xSemaphoreCreateBinaryStatic()
\r
822 parameter so the semaphore structure is instead allocated dynamically. */
\r
823 xSemaphore = xSemaphoreCreateBinaryStatic( NULL );
\r
825 /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */
\r
826 prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
\r
828 /* Delete the semaphore again so the buffers can be reused. */
\r
829 vSemaphoreDelete( xSemaphore );
\r
833 /* There isn't a static version of the old and deprecated
\r
834 vSemaphoreCreateBinary() macro (because its deprecated!), but check it is
\r
835 still functioning correctly when configSUPPORT_STATIC_ALLOCATION is set to
\r
837 vSemaphoreCreateBinary( xSemaphore );
\r
839 /* The macro starts with the binary semaphore available, but the test
\r
840 function expects it to be unavailable. */
\r
841 if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL )
\r
843 xErrorOccurred = pdTRUE;
\r
846 prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT );
\r
847 vSemaphoreDelete( xSemaphore );
\r
849 /* Ensure lower priority tasks get CPU time. */
\r
850 vTaskDelay( prvGetNextDelayTime() );
\r
852 /* Just to show the check task that this task is still executing. */
\r
855 /*-----------------------------------------------------------*/
\r
857 static void prvTimerCallback( TimerHandle_t xExpiredTimer )
\r
859 UBaseType_t *puxVariableToIncrement;
\r
860 BaseType_t xReturned;
\r
862 /* Obtain the address of the variable to increment from the timer ID. */
\r
863 puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer );
\r
865 /* Increment the variable to show the timer callback has executed. */
\r
866 ( *puxVariableToIncrement )++;
\r
868 /* If this callback has executed the required number of times, stop the
\r
870 if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS )
\r
872 /* This is called from a timer callback so must not block. */
\r
873 xReturned = xTimerStop( xExpiredTimer, staticDONT_BLOCK );
\r
875 if( xReturned != pdPASS )
\r
877 xErrorOccurred = pdTRUE;
\r
881 /*-----------------------------------------------------------*/
\r
883 static void prvCreateAndDeleteStaticallyAllocatedTimers( void )
\r
885 TimerHandle_t xTimer;
\r
886 UBaseType_t uxVariableToIncrement;
\r
887 const TickType_t xTimerPeriod = pdMS_TO_TICKS( 20 );
\r
888 BaseType_t xReturned;
\r
890 /* StaticTimer_t is a publicly accessible structure that has the same size
\r
891 and alignment requirements as the real timer structure. It is provided as a
\r
892 mechanism for applications to know the size of the timer structure (which is
\r
893 dependent on the architecture and configuration file settings) without breaking
\r
894 the strict data hiding policy by exposing the real timer internals. This
\r
895 StaticTimer_t variable is passed into the xTimerCreateStatic() function calls
\r
896 within this function. */
\r
897 StaticTimer_t xTimerBuffer;
\r
899 /* Create the software time. xTimerCreateStatic() has an extra parameter
\r
900 than the normal xTimerCreate() API function. The parameter is a pointer to
\r
901 the StaticTimer_t structure that will hold the software timer structure. If
\r
902 the parameter is passed as NULL then the structure will be allocated
\r
903 dynamically, just as if xTimerCreate() had been called. */
\r
904 xTimer = xTimerCreateStatic( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */
\r
905 xTimerPeriod, /* The period of the timer in ticks. */
\r
906 pdTRUE, /* This is an auto-reload timer. */
\r
907 ( void * ) &uxVariableToIncrement, /* The variable incremented by the test is passed into the timer callback using the timer ID. */
\r
908 prvTimerCallback, /* The function to execute when the timer expires. */
\r
909 &xTimerBuffer ); /* The buffer that will hold the software timer structure. */
\r
911 /* The timer handle should equal the static timer structure passed into the
\r
912 xTimerCreateStatic() function. */
\r
913 configASSERT( xTimer == ( TimerHandle_t ) &xTimerBuffer );
\r
915 /* Set the variable to 0, wait for a few timer periods to expire, then check
\r
916 the timer callback has incremented the variable to the expected value. */
\r
917 uxVariableToIncrement = 0;
\r
919 /* This is a low priority so a block time should not be needed. */
\r
920 xReturned = xTimerStart( xTimer, staticDONT_BLOCK );
\r
922 if( xReturned != pdPASS )
\r
924 xErrorOccurred = pdTRUE;
\r
927 vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );
\r
929 /* By now the timer should have expired staticMAX_TIMER_CALLBACK_EXECUTIONS
\r
930 times, and then stopped itself. */
\r
931 if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )
\r
933 xErrorOccurred = pdTRUE;
\r
936 /* Finished with the timer, delete it. */
\r
937 xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );
\r
939 /* Again, as this is a low priority task it is expected that the timer
\r
940 command will have been sent even without a block time being used. */
\r
941 if( xReturned != pdPASS )
\r
943 xErrorOccurred = pdTRUE;
\r
946 /* Just to show the check task that this task is still executing. */
\r
949 /* The software timer created above had a statically allocated timer
\r
950 structure. Repeat the above using NULL as the xTimerCreateStatic()
\r
951 parameter so the timer structure is instead allocated dynamically. */
\r
952 xTimer = xTimerCreateStatic( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */
\r
953 xTimerPeriod, /* The period of the timer in ticks. */
\r
954 pdTRUE, /* This is an auto-reload timer. */
\r
955 ( void * ) &uxVariableToIncrement, /* The variable incremented by the test is passed into the timer callback using the timer ID. */
\r
956 prvTimerCallback, /* The function to execute when the timer expires. */
\r
957 NULL ); /* A buffer is not passed this time, so the timer should be allocated dynamically. */
\r
958 uxVariableToIncrement = 0;
\r
959 xReturned = xTimerStart( xTimer, staticDONT_BLOCK );
\r
961 if( xReturned != pdPASS )
\r
963 xErrorOccurred = pdTRUE;
\r
966 vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS );
\r
968 /* Just to show the check task that this task is still executing. */
\r
971 if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS )
\r
973 xErrorOccurred = pdTRUE;
\r
976 xReturned = xTimerDelete( xTimer, staticDONT_BLOCK );
\r
978 if( xReturned != pdPASS )
\r
980 xErrorOccurred = pdTRUE;
\r
983 /* Just to show the check task that this task is still executing. */
\r
986 /*-----------------------------------------------------------*/
\r
988 static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void )
\r
990 EventGroupHandle_t xEventGroup;
\r
992 /* StaticEventGroup_t is a publicly accessible structure that has the same size
\r
993 and alignment requirements as the real event group structure. It is provided as
\r
994 a mechanism for applications to know the size of the event group (which is
\r
995 dependent on the architecture and configuration file settings) without breaking
\r
996 the strict data hiding policy by exposing the real event group internals. This
\r
997 StaticEventGroup_t variable is passed into the xSemaphoreCreateEventGroupStatic()
\r
998 function calls within this function. */
\r
999 StaticEventGroup_t xEventGroupBuffer;
\r
1001 /* Create the event group. xEventGroupCreateStatic() has an extra parameter
\r
1002 than the normal xEventGroupCreate() API function. The parameter is a
\r
1003 pointer to the StaticEventGroup_t structure that will hold the event group
\r
1004 structure. If the parameter is passed as NULL then the structure will be
\r
1005 allocated dynamically, just as if xEventGroupCreate() had been called. */
\r
1006 xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
\r
1008 /* The event group handle should equal the static event group structure
\r
1009 passed into the xEventGroupCreateStatic() function. */
\r
1010 configASSERT( xEventGroup == ( EventGroupHandle_t ) &xEventGroupBuffer );
\r
1012 /* Ensure the event group passes a few sanity checks as a valid event
\r
1014 prvSanityCheckCreatedEventGroup( xEventGroup );
\r
1016 /* Delete the event group again so the buffers can be reused. */
\r
1017 vEventGroupDelete( xEventGroup );
\r
1020 /* The event group created above had a statically allocated event group
\r
1021 structure. Repeat the above using NULL as the xEventGroupCreateStatic()
\r
1022 parameter so the event group structure is instead allocated dynamically. */
\r
1023 xEventGroup = xEventGroupCreateStatic( NULL );
\r
1025 /* Ensure the event group passes a few sanity checks as a valid event
\r
1027 prvSanityCheckCreatedEventGroup( xEventGroup );
\r
1029 /* Delete the event group again so the buffers can be reused. */
\r
1030 vEventGroupDelete( xEventGroup );
\r
1032 /* Ensure lower priority tasks get CPU time. */
\r
1033 vTaskDelay( prvGetNextDelayTime() );
\r
1035 /* Just to show the check task that this task is still executing. */
\r
1038 /*-----------------------------------------------------------*/
\r
1040 static void prvCreateAndDeleteStaticallyAllocatedTasks( void )
\r
1042 TaskHandle_t xCreatedTask;
\r
1043 BaseType_t xReturned;
\r
1045 /* The variable that will hold the TCB of tasks created by this function. See
\r
1046 the comments above the declaration of the xCreatorTaskTCBBuffer variable for
\r
1047 more information. */
\r
1048 StaticTask_t xTCBBuffer;
\r
1050 /* This buffer that will be used as the stack of tasks created by this function.
\r
1051 See the comments above the declaration of the uxCreatorTaskStackBuffer[] array
\r
1052 above for more information. */
\r
1053 static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ];
\r
1055 /* Create the task. xTaskCreateStatic() has two more parameters than
\r
1056 the usual xTaskCreate() function. The first new parameter is a pointer to
\r
1057 the pre-allocated stack. The second new parameter is a pointer to the
\r
1058 StaticTask_t structure that will hold the task's TCB. If either pointer is
\r
1059 passed as NULL then the respective object will be allocated dynamically as
\r
1060 if xTaskCreate() had been called. */
\r
1061 xReturned = xTaskCreateStatic(
\r
1062 prvStaticallyAllocatedTask, /* Function that implements the task. */
\r
1063 "Static", /* Human readable name for the task. */
\r
1064 configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
\r
1065 NULL, /* Parameter to pass into the task. */
\r
1066 tskIDLE_PRIORITY, /* The priority of the task. */
\r
1067 &xCreatedTask, /* Handle of the task being created. */
\r
1068 &( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
\r
1069 &xTCBBuffer ); /* The variable that will hold that task's TCB. */
\r
1071 /* Check the task was created correctly, then delete the task. */
\r
1072 configASSERT( xReturned == pdPASS );
\r
1073 if( xReturned != pdPASS )
\r
1075 xErrorOccurred = pdTRUE;
\r
1077 vTaskDelete( xCreatedTask );
\r
1079 /* Ensure lower priority tasks get CPU time. */
\r
1080 vTaskDelay( prvGetNextDelayTime() );
\r
1082 /* Create and delete the task a few times again - testing both static and
\r
1083 dynamic allocation for the stack and TCB. */
\r
1084 xReturned = xTaskCreateStatic(
\r
1085 prvStaticallyAllocatedTask, /* Function that implements the task. */
\r
1086 "Static", /* Human readable name for the task. */
\r
1087 configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
\r
1088 NULL, /* Parameter to pass into the task. */
\r
1089 staticTASK_PRIORITY + 1, /* The priority of the task. */
\r
1090 &xCreatedTask, /* Handle of the task being created. */
\r
1091 NULL, /* This time, dynamically allocate the stack. */
\r
1092 &xTCBBuffer ); /* The variable that will hold that task's TCB. */
\r
1094 configASSERT( xReturned == pdPASS );
\r
1095 if( xReturned != pdPASS )
\r
1097 xErrorOccurred = pdTRUE;
\r
1099 vTaskDelete( xCreatedTask );
\r
1101 /* Just to show the check task that this task is still executing. */
\r
1104 /* Ensure lower priority tasks get CPU time. */
\r
1105 vTaskDelay( prvGetNextDelayTime() );
\r
1107 xReturned = xTaskCreateStatic(
\r
1108 prvStaticallyAllocatedTask, /* Function that implements the task. */
\r
1109 "Static", /* Human readable name for the task. */
\r
1110 configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
\r
1111 NULL, /* Parameter to pass into the task. */
\r
1112 staticTASK_PRIORITY - 1, /* The priority of the task. */
\r
1113 &xCreatedTask, /* Handle of the task being created. */
\r
1114 &( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */
\r
1115 NULL ); /* This time dynamically allocate the TCB. */
\r
1117 configASSERT( xReturned == pdPASS );
\r
1118 if( xReturned != pdPASS )
\r
1120 xErrorOccurred = pdTRUE;
\r
1122 vTaskDelete( xCreatedTask );
\r
1124 /* Ensure lower priority tasks get CPU time. */
\r
1125 vTaskDelay( prvGetNextDelayTime() );
\r
1127 xReturned = xTaskCreateStatic(
\r
1128 prvStaticallyAllocatedTask, /* Function that implements the task. */
\r
1129 "Static", /* Human readable name for the task. */
\r
1130 configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */
\r
1131 NULL, /* Parameter to pass into the task. */
\r
1132 staticTASK_PRIORITY, /* The priority of the task. */
\r
1133 &xCreatedTask, /* Handle of the task being created. */
\r
1134 NULL, /* This time dynamically allocate the stack and TCB. */
\r
1135 NULL ); /* This time dynamically allocate the stack and TCB. */
\r
1137 configASSERT( xReturned == pdPASS );
\r
1138 if( xReturned != pdPASS )
\r
1140 xErrorOccurred = pdTRUE;
\r
1142 vTaskDelete( xCreatedTask );
\r
1144 /* Ensure lower priority tasks get CPU time. */
\r
1145 vTaskDelay( prvGetNextDelayTime() );
\r
1147 /* Just to show the check task that this task is still executing. */
\r
1150 /*-----------------------------------------------------------*/
\r
1152 static void prvStaticallyAllocatedTask( void *pvParameters )
\r
1154 ( void ) pvParameters;
\r
1156 /* The created task doesn't do anything - just waits to get deleted. */
\r
1157 vTaskSuspend( NULL );
\r
1159 /*-----------------------------------------------------------*/
\r
1161 static UBaseType_t prvRand( void )
\r
1163 const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
\r
1165 /* Utility function to generate a pseudo random number. */
\r
1166 ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
\r
1167 return( ( ulNextRand >> 16UL ) & 0x7fffUL );
\r
1169 /*-----------------------------------------------------------*/
\r
1171 static TickType_t prvGetNextDelayTime( void )
\r
1173 TickType_t xNextDelay;
\r
1174 const TickType_t xMaxDelay = pdMS_TO_TICKS( ( TickType_t ) 150 );
\r
1175 const TickType_t xMinDelay = pdMS_TO_TICKS( ( TickType_t ) 75 );
\r
1176 const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 );
\r
1178 /* Generate the next delay time. This is kept within a narrow band so as
\r
1179 not to disturb the timing of other tests - but does add in some pseudo
\r
1180 randomisation into the tests. */
\r
1183 xNextDelay = prvRand() % xMaxDelay;
\r
1185 /* Just in case this loop is executed lots of times. */
\r
1186 vTaskDelay( xTinyDelay );
\r
1188 } while ( xNextDelay < xMinDelay );
\r
1190 return xNextDelay;
\r
1192 /*-----------------------------------------------------------*/
\r
1194 BaseType_t xAreStaticAllocationTasksStillRunning( void )
\r
1196 static UBaseType_t uxLastCycleCounter = 0;
\r
1197 BaseType_t xReturn;
\r
1199 if( uxCycleCounter == uxLastCycleCounter )
\r
1201 xErrorOccurred = pdTRUE;
\r
1205 uxLastCycleCounter = uxCycleCounter;
\r
1208 if( xErrorOccurred != pdFALSE )
\r
1219 /*-----------------------------------------------------------*/
\r
1221 /* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */
\r
1222 #endif /* configSUPPORT_STATIC_ALLOCATION == 1 */
\r