3 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
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:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
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.
22 * https://www.FreeRTOS.org
23 * https://github.com/FreeRTOS
27 /******************************************************************************
28 * This project provides two demo applications. A simple blinky style project,
29 * a more comprehensive test and demo application.
30 * The mainSELECTED_APPLICATION setting is used to select between
33 * If mainSELECTED_APPLICATION = BLINKY_DEMO the simple blinky demo will be built.
34 * The simply blinky demo is implemented and described in main_blinky.c.
36 * If mainSELECTED_APPLICATION = FULL_DEMO the more comprehensive test and demo
37 * application built. This is implemented and described in main_full.c.
39 * This file implements the code that is not demo specific, including the
40 * hardware setup and FreeRTOS hook functions.
42 *******************************************************************************
43 * NOTE: Linux will not be running the FreeRTOS demo threads continuously, so
44 * do not expect to get real time behaviour from the FreeRTOS Linux port, or
45 * this demo application. Also, the timing information in the FreeRTOS+Trace
46 * logs have no meaningful units. See the documentation page for the Linux
47 * port for further information:
48 * https://freertos.org/FreeRTOS-simulator-for-Linux.html
50 *******************************************************************************
53 /* Standard includes. */
60 #include <sys/select.h>
62 /* FreeRTOS kernel includes. */
73 #define BUILD BUILD_DIR
78 /* Demo type is passed as an argument */
80 #define mainSELECTED_APPLICATION USER_DEMO
81 #else /* Default Setting */
82 #define mainSELECTED_APPLICATION BLINKY_DEMO
85 /* This demo uses heap_3.c (the libc provided malloc() and free()). */
87 /*-----------------------------------------------------------*/
88 extern void main_blinky( void );
89 extern void main_full( void );
90 static void traceOnEnter( void );
93 * Only the comprehensive demo uses application hook (callback) functions. See
94 * http://www.freertos.org/a00016.html for more information.
96 void vFullDemoTickHookFunction( void );
97 void vFullDemoIdleFunction( void );
100 * Prototypes for the standard FreeRTOS application hook (callback) functions
101 * implemented within this file. See http://www.freertos.org/a00016.html .
103 void vApplicationMallocFailedHook( void );
104 void vApplicationIdleHook( void );
105 void vApplicationStackOverflowHook( TaskHandle_t pxTask,
107 void vApplicationTickHook( void );
108 void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
109 StackType_t ** ppxIdleTaskStackBuffer,
110 uint32_t * pulIdleTaskStackSize );
111 void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
112 StackType_t ** ppxTimerTaskStackBuffer,
113 uint32_t * pulTimerTaskStackSize );
116 * Writes trace data to a disk file when the trace recording is stopped.
117 * This function will simply overwrite any trace files that already exist.
119 static void prvSaveTraceFile( void );
122 * Signal handler for Ctrl_C to cause the program to exit, and generate the
125 static void handle_sigint( int signal );
127 /*-----------------------------------------------------------*/
129 /* When configSUPPORT_STATIC_ALLOCATION is set to 1 the application writer can
130 * use a callback function to optionally provide the memory required by the idle
131 * and timer tasks. This is the stack that will be used by the timer task. It is
132 * declared here, as a global, so it can be checked by a test that is implemented
133 * in a different file. */
134 StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
136 /* Notes if the trace is running or not. */
137 #if ( projCOVERAGE_TEST == 1 )
138 static BaseType_t xTraceRunning = pdFALSE;
140 static BaseType_t xTraceRunning = pdTRUE;
143 /*-----------------------------------------------------------*/
147 /* SIGINT is not blocked by the posix port */
148 signal( SIGINT, handle_sigint );
150 /* Do not include trace code when performing a code coverage analysis. */
151 #if ( projCOVERAGE_TEST != 1 )
153 /* Initialise the trace recorder. Use of the trace recorder is optional.
154 * See http://www.FreeRTOS.org/trace for more information. */
155 vTraceEnable( TRC_START );
157 /* Start the trace recording - the recording is written to a file if
158 * configASSERT() is called. */
159 printf( "\r\nTrace started.\r\nThe trace will be dumped to disk if a call to configASSERT() fails.\r\n" );
161 #if ( TRACE_ON_ENTER == 1 )
162 printf( "\r\nThe trace will be dumped to disk if Enter is hit.\r\n" );
166 #endif /* if ( projCOVERAGE_TEST != 1 ) */
169 #if ( mainSELECTED_APPLICATION == BLINKY_DEMO )
171 console_print( "Starting echo blinky demo\n" );
174 #elif ( mainSELECTED_APPLICATION == FULL_DEMO )
176 console_print( "Starting full demo\n" );
181 #error "The selected demo is not valid"
183 #endif /* if ( mainSELECTED_APPLICATION ) */
187 /*-----------------------------------------------------------*/
189 void vApplicationMallocFailedHook( void )
191 /* vApplicationMallocFailedHook() will only be called if
192 * configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
193 * function that will get called if a call to pvPortMalloc() fails.
194 * pvPortMalloc() is called internally by the kernel whenever a task, queue,
195 * timer or semaphore is created. It is also called by various parts of the
196 * demo application. If heap_1.c, heap_2.c or heap_4.c is being used, then the
197 * size of the heap available to pvPortMalloc() is defined by
198 * configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()
199 * API function can be used to query the size of free heap space that remains
200 * (although it does not provide information on how the remaining heap might be
201 * fragmented). See http://www.freertos.org/a00111.html for more
203 vAssertCalled( __FILE__, __LINE__ );
205 /*-----------------------------------------------------------*/
207 void vApplicationIdleHook( void )
209 /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
210 * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
211 * task. It is essential that code added to this hook function never attempts
212 * to block in any way (for example, call xQueueReceive() with a block time
213 * specified, or call vTaskDelay()). If application tasks make use of the
214 * vTaskDelete() API function to delete themselves then it is also important
215 * that vApplicationIdleHook() is permitted to return to its calling function,
216 * because it is the responsibility of the idle task to clean up memory
217 * allocated by the kernel to any task that has since deleted itself. */
223 #if ( mainSELECTED_APPLICATION == FULL_DEMO )
225 /* Call the idle task processing used by the full demo. The simple
226 * blinky demo does not use the idle task hook. */
227 vFullDemoIdleFunction();
231 /*-----------------------------------------------------------*/
233 void vApplicationStackOverflowHook( TaskHandle_t pxTask,
239 /* Run time stack overflow checking is performed if
240 * configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
241 * function is called if a stack overflow is detected. This function is
242 * provided as an example only as stack overflow checking does not function
243 * when running the FreeRTOS POSIX port. */
244 vAssertCalled( __FILE__, __LINE__ );
246 /*-----------------------------------------------------------*/
248 void vApplicationTickHook( void )
250 /* This function will be called by each tick interrupt if
251 * configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
252 * added here, but the tick hook is called from an interrupt context, so
253 * code must not attempt to block, and only the interrupt safe FreeRTOS API
254 * functions can be used (those that end in FromISR()). */
256 #if ( mainSELECTED_APPLICATION == FULL_DEMO )
258 vFullDemoTickHookFunction();
260 #endif /* mainSELECTED_APPLICATION */
265 #if ( TRACE_ON_ENTER == 1 )
267 struct timeval tv = { 0L, 0L };
271 FD_SET( STDIN_FILENO, &fds );
273 xReturn = select( STDIN_FILENO + 1, &fds, NULL, NULL, &tv );
277 if( xTraceRunning == pdTRUE )
282 /* clear the buffer */
284 read( STDIN_FILENO, &buffer, 1 );
286 #endif /* if ( TRACE_ON_ENTER == 1 ) */
289 void vLoggingPrintf( const char * pcFormat,
294 va_start( arg, pcFormat );
295 vprintf( pcFormat, arg );
298 /*-----------------------------------------------------------*/
300 void vApplicationDaemonTaskStartupHook( void )
302 /* This function will be called once only, when the daemon task starts to
303 * execute (sometimes called the timer task). This is useful if the
304 * application includes initialisation code that would benefit from executing
305 * after the scheduler has been started. */
307 /*-----------------------------------------------------------*/
309 void vAssertCalled( const char * const pcFileName,
310 unsigned long ulLine )
312 static BaseType_t xPrinted = pdFALSE;
313 volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
315 /* Called if an assertion passed to configASSERT() fails. See
316 * http://www.freertos.org/a00110.html#configASSERT for more information. */
318 /* Parameters are not used. */
323 taskENTER_CRITICAL();
325 /* Stop the trace recording. */
326 if( xPrinted == pdFALSE )
330 if( xTraceRunning == pdTRUE )
336 /* You can step out of this function to debug the assertion by using
337 * the debugger to set ulSetToNonZeroInDebuggerToContinue to a non-zero
339 while( ulSetToNonZeroInDebuggerToContinue == 0 )
341 __asm volatile ( "NOP" );
342 __asm volatile ( "NOP" );
347 /*-----------------------------------------------------------*/
349 static void prvSaveTraceFile( void )
351 /* Tracing is not used when code coverage analysis is being performed. */
352 #if ( projCOVERAGE_TEST != 1 )
358 pxOutputFile = fopen( "Trace.dump", "wb" );
360 if( pxOutputFile != NULL )
362 fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile );
363 fclose( pxOutputFile );
364 printf( "\r\nTrace output saved to Trace.dump\r\n" );
368 printf( "\r\nFailed to create trace dump file\r\n" );
371 #endif /* if ( projCOVERAGE_TEST != 1 ) */
373 /*-----------------------------------------------------------*/
375 /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
376 * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
377 * used by the Idle task. */
378 void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
379 StackType_t ** ppxIdleTaskStackBuffer,
380 uint32_t * pulIdleTaskStackSize )
382 /* If the buffers to be provided to the Idle task are declared inside this
383 * function then they must be declared static - otherwise they will be allocated on
384 * the stack and so not exists after this function exits. */
385 static StaticTask_t xIdleTaskTCB;
386 static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
388 /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
389 * state will be stored. */
390 *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
392 /* Pass out the array that will be used as the Idle task's stack. */
393 *ppxIdleTaskStackBuffer = uxIdleTaskStack;
395 /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
396 * Note that, as the array is necessarily of type StackType_t,
397 * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
398 *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
400 /*-----------------------------------------------------------*/
402 /* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
403 * application must provide an implementation of vApplicationGetTimerTaskMemory()
404 * to provide the memory that is used by the Timer service task. */
405 void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
406 StackType_t ** ppxTimerTaskStackBuffer,
407 uint32_t * pulTimerTaskStackSize )
409 /* If the buffers to be provided to the Timer task are declared inside this
410 * function then they must be declared static - otherwise they will be allocated on
411 * the stack and so not exists after this function exits. */
412 static StaticTask_t xTimerTaskTCB;
414 /* Pass out a pointer to the StaticTask_t structure in which the Timer
415 * task's state will be stored. */
416 *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
418 /* Pass out the array that will be used as the Timer task's stack. */
419 *ppxTimerTaskStackBuffer = uxTimerTaskStack;
421 /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
422 * Note that, as the array is necessarily of type StackType_t,
423 * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
424 *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
427 void handle_sigint( int signal )
431 xReturn = chdir( BUILD ); /* changing dir to place gmon.out inside build */
435 printf( "chdir into %s error is %d\n", BUILD, errno );