1 /*
2  * FreeRTOS V202212.00
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  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  */
26 
27 /* Standard includes. */
28 #include <stdio.h>
29 #include <time.h>
30 
31 /* Visual studio intrinsics used so the __debugbreak() function is available
32  * should an assert get hit. */
33 #include <intrin.h>
34 
35 
36 #ifdef WIN32_LEAN_AND_MEAN
37     #include <winsock2.h>
38 #else
39     #include <winsock.h>
40 #endif /* WIN32_LEAN_AND_MEAN */
41 
42 #include <windows.h>
43 
44 /* Windows Crypt api for uxRand() */
45 #include <wincrypt.h>
46 
47 /* FreeRTOS includes. */
48 #include "FreeRTOS.h"
49 #include "task.h"
50 
51 /*-----------------------------------------------------------*/
52 
53 extern void vPlatformStopLoggingThreadAndFlush( void );
54 
55 /*-----------------------------------------------------------*/
56 
vAssertCalled(const char * pcFile,uint32_t ulLine)57 void vAssertCalled( const char * pcFile,
58                     uint32_t ulLine )
59 {
60     volatile uint32_t ulBlockVariable = 0UL;
61     volatile char * pcFileName = ( volatile char * ) pcFile;
62     volatile uint32_t ulLineNumber = ulLine;
63 
64     ( void ) pcFileName;
65     ( void ) ulLineNumber;
66 
67     /* Stop the windows logging thread and flush the log buffer. This function does
68      * nothing if the logging is not initialized before. */
69     vPlatformStopLoggingThreadAndFlush();
70 
71     printf( "vAssertCalled( %s, %u )\n", pcFile, ulLine );
72 
73     /* Setting ulBlockVariable to a non-zero value in the debugger will allow
74      * this function to be exited. */
75     taskENTER_CRITICAL();
76     {
77         while( ulBlockVariable == 0UL )
78         {
79             __debugbreak();
80         }
81     }
82     taskEXIT_CRITICAL();
83 }
84 /*-----------------------------------------------------------*/
85 
uxRand(void)86 UBaseType_t uxRand( void )
87 {
88     HCRYPTPROV hProv = 0;
89     BOOL xResult = 0;
90     UBaseType_t uxRandNum = 0U;
91 
92     xResult = CryptAcquireContextA( &hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT );
93 
94     configASSERT( xResult );
95 
96     xResult = CryptGenRandom( hProv, sizeof( UBaseType_t ), ( uint8_t * ) ( &uxRandNum ) );
97 
98     configASSERT( xResult );
99 
100     CryptReleaseContext( hProv, 0 );
101 
102     return uxRandNum;
103 }
104 
105 /*-----------------------------------------------------------*/
106 
107 #if defined( configUSE_STATIC_ALLOCATION ) && ( configUSE_STATIC_ALLOCATION == 1U )
108 
109 /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
110  * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
111  * used by the Idle task. */
vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize)112     void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
113                                         StackType_t ** ppxIdleTaskStackBuffer,
114                                         uint32_t * pulIdleTaskStackSize )
115     {
116         /* If the buffers to be provided to the Idle task are declared inside this
117          * function then they must be declared static - otherwise they will be allocated on
118          * the stack and so not exists after this function exits. */
119         static StaticTask_t xIdleTaskTCB;
120         static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
121 
122         /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
123          * state will be stored. */
124         *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
125 
126         /* Pass out the array that will be used as the Idle task's stack. */
127         *ppxIdleTaskStackBuffer = uxIdleTaskStack;
128 
129         /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
130          * Note that, as the array is necessarily of type StackType_t,
131          * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
132         *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
133     }
134 
135 /*-----------------------------------------------------------*/
136 
137     #if defined( configUSE_TIMERS ) && ( configUSE_TIMERS == 1U )
138 
139 /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
140  * application must provide an implementation of vApplicationGetTimerTaskMemory()
141  * to provide the memory that is used by the Timer service task. */
vApplicationGetTimerTaskMemory(StaticTask_t ** ppxTimerTaskTCBBuffer,StackType_t ** ppxTimerTaskStackBuffer,uint32_t * pulTimerTaskStackSize)142         void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
143                                              StackType_t ** ppxTimerTaskStackBuffer,
144                                              uint32_t * pulTimerTaskStackSize )
145         {
146             /* If the buffers to be provided to the Timer task are declared inside this
147              * function then they must be declared static - otherwise they will be allocated on
148              * the stack and so not exists after this function exits. */
149             static StaticTask_t xTimerTaskTCB;
150             static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
151 
152             /* Pass out a pointer to the StaticTask_t structure in which the Timer
153              * task's state will be stored. */
154             *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
155 
156             /* Pass out the array that will be used as the Timer task's stack. */
157             *ppxTimerTaskStackBuffer = uxTimerTaskStack;
158 
159             /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
160              * Note that, as the array is necessarily of type StackType_t,
161              * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
162             *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
163         }
164     #endif /*  defined( configUSE_TIMERS ) && ( configUSE_TIMERS == 1U ) */
165 
166 #endif /* defined( configUSE_STATIC_ALLOCATION ) && ( configUSE_STATIC_ALLOCATION == 1U ) */
167 
168 /*-----------------------------------------------------------*/
169 
170 #if ( configUSE_MALLOC_FAILED_HOOK == 1U )
vApplicationMallocFailedHook(void)171     void vApplicationMallocFailedHook( void )
172     {
173         /*
174          * vApplicationMallocFailedHook() will only be called if
175          * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook
176          * function that will get called if a call to pvPortMalloc() fails.
177          * pvPortMalloc() is called internally by the kernel whenever a task, queue,
178          * timer or semaphore is created.  It is also called by various parts of the
179          * demo application.  If heap_1.c, heap_2.c or heap_4.c is being used, then the
180          * size of the    heap available to pvPortMalloc() is defined by
181          * configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()
182          * API function can be used to query the size of free heap space that remains
183          * (although it does not provide information on how the remaining heap might be
184          * fragmented).  See http://www.freertos.org/a00111.html for more
185          * information.
186          */
187         vAssertCalled( __FILE__, __LINE__ );
188     }
189 #endif /* configUSE_MALLOC_FAILED_HOOK == 1U */
190 
191 /*-----------------------------------------------------------*/
192 
193 #if ( configUSE_IDLE_HOOK == 1U )
vApplicationIdleHook(void)194     void vApplicationIdleHook( void )
195     {
196         /*
197          * vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
198          * to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle
199          * task.  It is essential that code added to this hook function never attempts
200          * to block in any way (for example, call xQueueReceive() with a block time
201          * specified, or call vTaskDelay()).  If application tasks make use of the
202          * vTaskDelete() API function to delete themselves then it is also important
203          * that vApplicationIdleHook() is permitted to return to its calling function,
204          * because it is the responsibility of the idle task to clean up memory
205          * allocated by the kernel to any task that has since deleted itself.
206          */
207     }
208 #endif /* configUSE_IDLE_HOOK */
209 
210 /*-----------------------------------------------------------*/
211 
212 #if ( configUSE_TICK_HOOK == 1U )
vApplicationTickHook(void)213     void vApplicationTickHook( void )
214     {
215         /*
216          * This function will be called by each tick interrupt if
217          * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h.  User code can be
218          * added here, but the tick hook is called from an interrupt context, so
219          * code must not attempt to block, and only the interrupt safe FreeRTOS API
220          * functions can be used (those that end in FromISR()).
221          */
222     }
223 #endif /* configUSE_TICK_HOOK == 1U */
224 
225 /*-----------------------------------------------------------*/
226 
227 #if ( configSUPPORT_STATIC_ALLOCATION == 1U )
228 
229 /*
230  * configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
231  * application must provide an implementation of vApplicationGetTimerTaskMemory()
232  * to provide the memory that is used by the Timer service task.
233  */
vApplicationGetTimerTaskMemory(StaticTask_t ** ppxTimerTaskTCBBuffer,StackType_t ** ppxTimerTaskStackBuffer,uint32_t * pulTimerTaskStackSize)234     void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
235                                          StackType_t ** ppxTimerTaskStackBuffer,
236                                          uint32_t * pulTimerTaskStackSize )
237     {
238         /*
239          * If the buffers to be provided to the Timer task are declared inside this
240          * function then they must be declared static - otherwise they will be allocated on
241          * the stack and so not exists after this function exits.
242          */
243         static StaticTask_t xTimerTaskTCB;
244         static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
245 
246         /*
247          * Pass out a pointer to the StaticTask_t structure in which the Timer
248          * task's state will be stored.
249          */
250         *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
251 
252         /* Pass out the array that will be used as the Timer task's stack. */
253         *ppxTimerTaskStackBuffer = uxTimerTaskStack;
254 
255         /*
256          * Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
257          * Note that, as the array is necessarily of type StackType_t,
258          * configMINIMAL_STACK_SIZE is specified in words, not bytes.
259          */
260         *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
261     }
262 #endif /* configSUPPORT_STATIC_ALLOCATION == 1U */
263 
264 /*-----------------------------------------------------------*/
265 
266 #if ( configSUPPORT_STATIC_ALLOCATION == 1U )
267 
268 /*
269  * configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
270  * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
271  * used by the Idle task.
272  */
vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize)273     void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
274                                         StackType_t ** ppxIdleTaskStackBuffer,
275                                         uint32_t * pulIdleTaskStackSize )
276     {
277         /*
278          * If the buffers to be provided to the Idle task are declared inside this
279          * function then they must be declared static - otherwise they will be allocated on
280          * the stack and so not exists after this function exits.
281          */
282         static StaticTask_t xIdleTaskTCB;
283         static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
284 
285         /*
286          * Pass out a pointer to the StaticTask_t structure in which the Idle task's
287          * state will be stored.
288          */
289         *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
290 
291         /* Pass out the array that will be used as the Idle task's stack. */
292         *ppxIdleTaskStackBuffer = uxIdleTaskStack;
293 
294         /*
295          * Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
296          * Note that, as the array is necessarily of type StackType_t,
297          * configMINIMAL_STACK_SIZE is specified in words, not bytes.
298          */
299         *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
300     }
301 #endif /* configSUPPORT_STATIC_ALLOCATION == 1U  */
302 
303 /*-----------------------------------------------------------*/
304