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