2 * FreeRTOS Kernel V10.0.1
3 * Copyright (C) 2017 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 * http://www.FreeRTOS.org
23 * http://aws.amazon.com/freertos
30 * Creates all the demo application tasks, then starts the scheduler. The WEB
31 * documentation provides more details of the standard demo application tasks
32 * (which just exist to test the kernel port and provide an example of how to use
33 * each FreeRTOS API function).
35 * In addition to the standard demo tasks, the following tasks and tests are
36 * defined and/or created within this file:
38 * "Check" hook - This only executes fully every five seconds from the tick
39 * hook. Its main function is to check that all the standard demo tasks are
40 * still operational. The status can be viewed using on the Task Stats page
41 * served by the WEB server.
43 * "uIP" task - This is the task that handles the uIP stack. All TCP/IP
44 * processing is performed in this task.
46 * "USB" task - Enumerates the USB device as a CDC class, then echoes back all
47 * received characters with a configurable offset (for example, if the offset
48 * is 1 and 'A' is received then 'B' will be sent back). A dumb terminal such
49 * as Hyperterminal can be used to talk to the USB task.
52 /* Scheduler includes. */
56 /* Demo app includes. */
68 /*-----------------------------------------------------------*/
70 /* The time between cycles of the 'check' functionality (defined within the
72 #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
74 /* Task priorities. */
75 #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
76 #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
77 #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
78 #define mainUIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
79 #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
80 #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
81 #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
83 /* The WEB server has a larger stack as it utilises stack hungry string
84 handling library calls. */
85 #define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 )
87 /* The message displayed by the WEB server when all tasks are executing
88 without an error being reported. */
89 #define mainPASS_STATUS_MESSAGE "All tasks are executing without error."
91 /*-----------------------------------------------------------*/
94 * Configure the hardware for the demo.
96 static void prvSetupHardware( void );
99 * The task that handles the uIP stack. All TCP/IP processing is performed in
102 extern void vuIP_Task( void *pvParameters );
105 * The task that handles the USB stack.
107 extern void vUSBTask( void *pvParameters );
110 * Simply returns the current status message for display on served WEB pages.
112 char *pcGetTaskStatusMessage( void );
114 /*-----------------------------------------------------------*/
116 /* Holds the status message displayed by the WEB server. */
117 static char *pcStatusMessage = mainPASS_STATUS_MESSAGE;
119 /*-----------------------------------------------------------*/
123 /* Configure the hardware for use by this demo. */
126 /* Start the standard demo tasks. These are just here to exercise the
127 kernel port and provide examples of how the FreeRTOS API can be used. */
128 vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
129 vCreateBlockTimeTasks();
130 vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
131 vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
132 vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
133 vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
134 vStartQueuePeekTasks();
135 vStartRecursiveMutexTasks();
136 vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
138 /* Create the USB task. */
139 xTaskCreate( vUSBTask, "USB", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
141 /* Create the uIP task. The WEB server runs in this task. */
142 xTaskCreate( vuIP_Task, "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );
144 /* Start the scheduler. */
145 vTaskStartScheduler();
147 /* Will only get here if there was insufficient memory to create the idle
148 task. The idle task is created within vTaskStartScheduler(). */
151 /*-----------------------------------------------------------*/
153 void vApplicationTickHook( void )
155 static unsigned long ulTicksSinceLastDisplay = 0;
157 /* Called from every tick interrupt as described in the comments at the top
160 Have enough ticks passed to make it time to perform our health status
162 ulTicksSinceLastDisplay++;
163 if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
165 /* Reset the counter so these checks run again in mainCHECK_DELAY
167 ulTicksSinceLastDisplay = 0;
169 /* Has an error been found in any task? */
170 if( xAreGenericQueueTasksStillRunning() != pdTRUE )
172 pcStatusMessage = "An error has been detected in the Generic Queue test/demo.";
174 else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
176 pcStatusMessage = "An error has been detected in the Peek Queue test/demo.";
178 else if( xAreBlockingQueuesStillRunning() != pdTRUE )
180 pcStatusMessage = "An error has been detected in the Block Queue test/demo.";
182 else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
184 pcStatusMessage = "An error has been detected in the Block Time test/demo.";
186 else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
188 pcStatusMessage = "An error has been detected in the Semaphore test/demo.";
190 else if( xArePollingQueuesStillRunning() != pdTRUE )
192 pcStatusMessage = "An error has been detected in the Poll Queue test/demo.";
194 else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
196 pcStatusMessage = "An error has been detected in the Int Math test/demo.";
198 else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
200 pcStatusMessage = "An error has been detected in the Mutex test/demo.";
204 /*-----------------------------------------------------------*/
206 char *pcGetTaskStatusMessage( void )
208 /* Not bothered about a critical section here. */
209 return pcStatusMessage;
211 /*-----------------------------------------------------------*/
213 void prvSetupHardware( void )
215 /* Disable peripherals power. */
218 /* Enable GPIO power. */
219 SC->PCONP = PCONP_PCGPIO;
222 PINCON->PINSEL10 = 0;
224 /* Setup the peripheral bus to be the same as the CPU output (100 MHz). */
225 SC->PCLKSEL0 = 0x05555555;
227 /* Configure the LEDs. */
228 vParTestInitialise();
230 /*-----------------------------------------------------------*/
232 void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
234 /* This function will get called if a task overflows its stack. */
241 /*-----------------------------------------------------------*/
243 void vConfigureTimerForRunTimeStats( void )
245 const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
247 /* This function configures a timer that is used as the time base when
248 collecting run time statistical information - basically the percentage
249 of CPU time that each task is utilising. It is called automatically when
250 the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set
253 /* Power up and feed the timer. */
255 SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
258 TIM0->TCR = TCR_COUNT_RESET;
261 TIM0->CTCR = CTCR_CTM_TIMER;
263 /* Prescale to a frequency that is good enough to get a decent resolution,
264 but not too fast so as to overflow all the time. */
265 TIM0->PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;
267 /* Start the counter. */
268 TIM0->TCR = TCR_COUNT_ENABLE;
270 /*-----------------------------------------------------------*/