]> begriffs open source - cmsis-freertos/blob - Demo/WIN32-MSVC-Static-Allocation-Only/main.c
Updated pack to FreeRTOS 10.3.1
[cmsis-freertos] / Demo / WIN32-MSVC-Static-Allocation-Only / main.c
1 /*
2  * FreeRTOS Kernel V10.3.1
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * http://www.FreeRTOS.org
23  * http://aws.amazon.com/freertos
24  *
25  * 1 tab == 4 spaces!
26  */
27
28 /******************************************************************************
29  *
30  * This project is provided as an example of how to create a FreeRTOS project
31  * that does not need a heap.  configSUPPORT_STATIC_ALLOCATION is set to 1 to
32  * allow RTOS objects to be created using statically allocated RAM, and
33  * configSUPPORT_DYNAMIC_ALLOCATION is set to 0 to remove any build dependency
34  * on the FreeRTOS heap.  When configSUPPORT_DYNAMIC_ALLOCATION is set to 0
35  * pvPortMalloc() just equates to NULL, and calls to vPortFree() have no
36  * effect.  See:
37  *
38  * http://www.freertos.org/a00111.html and
39  * http://www.freertos.org/Static_Vs_Dynamic_Memory_Allocation.html
40  *
41  *******************************************************************************
42  */
43
44 /* Standard includes. */
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <conio.h>
48
49 /* FreeRTOS kernel includes. */
50 #include "FreeRTOS.h"
51 #include "task.h"
52
53 /* Standard demo includes. */
54 #include "StaticAllocation.h"
55
56
57 /*-----------------------------------------------------------*/
58
59 /*
60  * Prototypes for the standard FreeRTOS stack overflow hook (callback)
61  * function.  http://www.freertos.org/Stacks-and-stack-overflow-checking.html
62  */
63 void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
64
65 /*
66  * This demo has configSUPPORT_STATIC_ALLOCATION set to 1 so the following
67  * application callback function must be provided to supply the RAM that will
68  * get used for the Idle task data structures and stack.
69  */
70 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
71
72 /*
73 * This demo has configSUPPORT_STATIC_ALLOCATION set to 1 and configUSE_TIMERS
74 * set to 1 so the following application callback function must be provided to
75 * supply the RAM that will get used for the Timer task data structures and
76 * stack.
77 */
78 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );
79
80 /* This demo only uses the standard demo tasks that use statically allocated
81 RAM.  A 'check' task is also created to periodically inspect the demo tasks to
82 ensure they are still running, and that no errors have been detected. */
83 static void prvStartCheckTask( void );
84 static void prvCheckTask( void *pvParameters );
85
86 /*-----------------------------------------------------------*/
87
88 int main( void )
89 {
90         /* This demo has configSUPPORT_STATIC_ALLOCATION set to 1 and
91         configSUPPORT_DYNAMIC_ALLOCATION set to 0, so the only standard temo tasks
92         created are the ones that only use static allocation.  This allow the
93         application to be built without including a FreeRTOS heap file (without one
94         of the heap files described on http://www.freertos.org/a00111.html */
95         vStartStaticallyAllocatedTasks();
96
97         /* Start a task that periodically inspects the tasks created by
98         vStartStaticallyAllocatedTasks() to ensure they are still running, and not
99         reporting any errors. */
100         prvStartCheckTask();
101
102         /* Start the scheduler so the demo tasks start to execute. */
103         vTaskStartScheduler();
104
105         /* vTaskStartScheduler() would only return if RAM required by the Idle and
106         Timer tasks could not be allocated.  As this demo uses statically allocated
107         RAM only, there are no allocations that could fail, and
108         vTaskStartScheduler() cannot return - so there is no need to put the normal
109         infinite loop after the call to vTaskStartScheduler(). */
110
111         return 0;
112 }
113 /*-----------------------------------------------------------*/
114
115 static void prvStartCheckTask( void )
116 {
117 /* Allocate the data structure that will hold the task's TCB.  NOTE:  This is
118 declared static so it still exists after this function has returned. */
119 static StaticTask_t xCheckTask;
120
121 /* Allocate the stack that will be used by the task.  NOTE:  This is declared
122 static so it still exists after this function has returned. */
123 static StackType_t ucTaskStack[ configMINIMAL_STACK_SIZE * sizeof( StackType_t ) ];
124
125         /* Create the task, which will use the RAM allocated by the linker to the
126         variables declared in this function. */
127         xTaskCreateStatic( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, ucTaskStack, &xCheckTask );
128 }
129 /*-----------------------------------------------------------*/
130
131 static void prvCheckTask( void *pvParameters )
132 {
133 const TickType_t xCycleFrequency = pdMS_TO_TICKS( 2500UL );
134 static char *pcStatusMessage = "No errors";
135
136         /* Just to remove compiler warning. */
137         ( void ) pvParameters;
138
139         for( ;; )
140         {
141                 /* Place this task in the blocked state until it is time to run again. */
142                 vTaskDelay( xCycleFrequency );
143
144                 /* Check the tasks that use static allocation are still executing. */
145                 if( xAreStaticAllocationTasksStillRunning() != pdPASS )
146                 {
147                         pcStatusMessage = "Error: Static allocation";
148                 }
149
150                 /* This is the only task that uses stdout so its ok to call printf()
151                 directly. */
152                 printf( "%s - tick count %d - number of tasks executing %d\r\n",
153                                                                                                         pcStatusMessage,
154                                                                                                         xTaskGetTickCount(),
155                                                                                                         uxTaskGetNumberOfTasks() );
156         }
157 }
158
159 /*-----------------------------------------------------------*/
160 void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
161 {
162         ( void ) pcTaskName;
163         ( void ) pxTask;
164
165         /* Run time stack overflow checking is performed if
166         configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
167         function is called if a stack overflow is detected.  This function is
168         provided as an example only as stack overflow checking does not function
169         when running the FreeRTOS Windows port. */
170         vAssertCalled( __LINE__, __FILE__ );
171 }
172 /*-----------------------------------------------------------*/
173
174 void vAssertCalled( unsigned long ulLine, const char * const pcFileName )
175 {
176 volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
177
178         /* Called if an assertion passed to configASSERT() fails.  See
179         http://www.freertos.org/a00110.html#configASSERT for more information. */
180
181         /* Parameters are not used. */
182         ( void ) ulLine;
183         ( void ) pcFileName;
184
185         printf( "ASSERT! Line %d, file %s\r\n", ulLine, pcFileName );
186
187         taskENTER_CRITICAL();
188         {
189                 /* You can step out of this function to debug the assertion by using
190                 the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero
191                 value. */
192                 while( ulSetToNonZeroInDebuggerToContinue == 0 )
193                 {
194                         __asm{ NOP };
195                         __asm{ NOP };
196                 }
197         }
198         taskEXIT_CRITICAL();
199 }
200 /*-----------------------------------------------------------*/
201
202 /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
203 implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
204 used by the Idle task. */
205 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
206 {
207 /* If the buffers to be provided to the Idle task are declared inside this
208 function then they must be declared static - otherwise they will be allocated on
209 the stack and so not exists after this function exits. */
210 static StaticTask_t xIdleTaskTCB;
211 static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
212
213         /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
214         state will be stored. */
215         *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
216
217         /* Pass out the array that will be used as the Idle task's stack. */
218         *ppxIdleTaskStackBuffer = uxIdleTaskStack;
219
220         /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
221         Note that, as the array is necessarily of type StackType_t,
222         configMINIMAL_STACK_SIZE is specified in words, not bytes. */
223         *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
224 }
225 /*-----------------------------------------------------------*/
226
227 /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
228 application must provide an implementation of vApplicationGetTimerTaskMemory()
229 to provide the memory that is used by the Timer service task. */
230 void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
231 {
232 /* If the buffers to be provided to the Timer task are declared inside this
233 function then they must be declared static - otherwise they will be allocated on
234 the stack and so not exists after this function exits. */
235 static StaticTask_t xTimerTaskTCB;
236 static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
237
238         /* Pass out a pointer to the StaticTask_t structure in which the Timer
239         task's state will be stored. */
240         *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
241
242         /* Pass out the array that will be used as the Timer task's stack. */
243         *ppxTimerTaskStackBuffer = uxTimerTaskStack;
244
245         /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
246         Note that, as the array is necessarily of type StackType_t,
247         configMINIMAL_STACK_SIZE is specified in words, not bytes. */
248         *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
249 }
250