2 * FreeRTOS Kernel V10.2.1
3 * Copyright (C) 2019 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 /* The toggle rate for the LED. */
75 #define mainLED_TOGGLE_RATE ( ( TickType_t ) 1000 / portTICK_PERIOD_MS )
77 /* Task priorities. */
78 #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
79 #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
80 #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
81 #define mainUIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
82 #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
83 #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
84 #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
86 /* The WEB server has a larger stack as it utilises stack hungry string
87 handling library calls. */
88 #define mainBASIC_WEB_STACK_SIZE ( configMINIMAL_STACK_SIZE * 4 )
90 /* The message displayed by the WEB server when all tasks are executing
91 without an error being reported. */
92 #define mainPASS_STATUS_MESSAGE "All tasks are executing without error."
94 /*-----------------------------------------------------------*/
97 * Configure the hardware for the demo.
99 static void prvSetupHardware( void );
102 * The task that handles the uIP stack. All TCP/IP processing is performed in
105 extern void vuIP_Task( void *pvParameters );
108 * The task that handles the USB stack.
110 extern void vUSBTask( void *pvParameters );
113 * Very basic task that does nothing but use delays to flash an LED.
115 static void prvFlashTask( void *pvParameters );
118 * Simply returns the current status message for display on served WEB pages.
120 char *pcGetTaskStatusMessage( void );
122 /*-----------------------------------------------------------*/
124 /* Holds the status message displayed by the WEB server. */
125 static char *pcStatusMessage = mainPASS_STATUS_MESSAGE;
127 /*-----------------------------------------------------------*/
131 /* Configure the hardware for use by this demo. */
134 /* Start the standard demo tasks. These are just here to exercise the
135 kernel port and provide examples of how the FreeRTOS API can be used. */
136 vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
137 vCreateBlockTimeTasks();
138 vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
139 vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
140 vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
141 vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
142 vStartQueuePeekTasks();
143 vStartRecursiveMutexTasks();
145 /* Create the simple LED flash task. */
146 xTaskCreate( prvFlashTask, "Flash", configMINIMAL_STACK_SIZE, ( void * ) NULL, mainFLASH_TASK_PRIORITY, NULL );
148 /* Create the USB task. */
149 xTaskCreate( vUSBTask, "USB", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL );
151 /* Create the uIP task. The WEB server runs in this task. */
152 xTaskCreate( vuIP_Task, "uIP", mainBASIC_WEB_STACK_SIZE, ( void * ) NULL, mainUIP_TASK_PRIORITY, NULL );
154 /* Start the scheduler. */
155 vTaskStartScheduler();
157 /* Will only get here if there was insufficient memory to create the idle
158 task. The idle task is created within vTaskStartScheduler(). */
161 /*-----------------------------------------------------------*/
163 void vApplicationTickHook( void )
165 static unsigned long ulTicksSinceLastDisplay = 0;
167 /* Called from every tick interrupt as described in the comments at the top
170 Have enough ticks passed to make it time to perform our health status
172 ulTicksSinceLastDisplay++;
173 if( ulTicksSinceLastDisplay >= mainCHECK_DELAY )
175 /* Reset the counter so these checks run again in mainCHECK_DELAY
177 ulTicksSinceLastDisplay = 0;
179 /* Has an error been found in any task? */
180 if( xAreGenericQueueTasksStillRunning() != pdTRUE )
182 pcStatusMessage = "An error has been detected in the Generic Queue test/demo.";
184 else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
186 pcStatusMessage = "An error has been detected in the Peek Queue test/demo.";
188 else if( xAreBlockingQueuesStillRunning() != pdTRUE )
190 pcStatusMessage = "An error has been detected in the Block Queue test/demo.";
192 else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
194 pcStatusMessage = "An error has been detected in the Block Time test/demo.";
196 else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
198 pcStatusMessage = "An error has been detected in the Semaphore test/demo.";
200 else if( xArePollingQueuesStillRunning() != pdTRUE )
202 pcStatusMessage = "An error has been detected in the Poll Queue test/demo.";
204 else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
206 pcStatusMessage = "An error has been detected in the Int Math test/demo.";
208 else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
210 pcStatusMessage = "An error has been detected in the Mutex test/demo.";
214 /*-----------------------------------------------------------*/
216 static void prvFlashTask( void *pvParameters )
218 TickType_t xLastFlashTime;
220 /* We need to initialise xLastFlashTime prior to the first call to
221 vTaskDelayUntil(). */
222 xLastFlashTime = xTaskGetTickCount();
226 /* Simply toggle the LED between delays. */
227 vTaskDelayUntil( &xLastFlashTime, mainLED_TOGGLE_RATE );
228 vParTestToggleLED( 0 );
231 /*-----------------------------------------------------------*/
233 char *pcGetTaskStatusMessage( void )
235 /* Not bothered about a critical section here. */
236 return pcStatusMessage;
238 /*-----------------------------------------------------------*/
240 void prvSetupHardware( void )
242 /* Disable peripherals power. */
245 /* Enable GPIO power. */
246 SC->PCONP = PCONP_PCGPIO;
249 PINCON->PINSEL10 = 0;
251 if ( SC->PLL0STAT & ( 1 << 25 ) )
253 /* Enable PLL, disconnected. */
255 SC->PLL0FEED = PLLFEED_FEED1;
256 SC->PLL0FEED = PLLFEED_FEED2;
259 /* Disable PLL, disconnected. */
261 SC->PLL0FEED = PLLFEED_FEED1;
262 SC->PLL0FEED = PLLFEED_FEED2;
264 /* Enable main OSC. */
266 while( !( SC->SCS & 0x40 ) );
268 /* select main OSC, 12MHz, as the PLL clock source. */
271 SC->PLL0CFG = 0x20031;
272 SC->PLL0FEED = PLLFEED_FEED1;
273 SC->PLL0FEED = PLLFEED_FEED2;
275 /* Enable PLL, disconnected. */
277 SC->PLL0FEED = PLLFEED_FEED1;
278 SC->PLL0FEED = PLLFEED_FEED2;
280 /* Set clock divider. */
283 /* Configure flash accelerator. */
284 SC->FLASHCFG = 0x403a;
286 /* Check lock bit status. */
287 while( ( ( SC->PLL0STAT & ( 1 << 26 ) ) == 0 ) );
289 /* Enable and connect. */
291 SC->PLL0FEED = PLLFEED_FEED1;
292 SC->PLL0FEED = PLLFEED_FEED2;
293 while( ( ( SC->PLL0STAT & ( 1 << 25 ) ) == 0 ) );
298 /* Configure the clock for the USB. */
300 if( SC->PLL1STAT & ( 1 << 9 ) )
302 /* Enable PLL, disconnected. */
304 SC->PLL1FEED = PLLFEED_FEED1;
305 SC->PLL1FEED = PLLFEED_FEED2;
308 /* Disable PLL, disconnected. */
310 SC->PLL1FEED = PLLFEED_FEED1;
311 SC->PLL1FEED = PLLFEED_FEED2;
314 SC->PLL1FEED = PLLFEED_FEED1;
315 SC->PLL1FEED = PLLFEED_FEED2;
317 /* Enable PLL, disconnected. */
319 SC->PLL1FEED = PLLFEED_FEED1;
320 SC->PLL1FEED = PLLFEED_FEED2;
321 while( ( ( SC->PLL1STAT & ( 1 << 10 ) ) == 0 ) );
323 /* Enable and connect. */
325 SC->PLL1FEED = PLLFEED_FEED1;
326 SC->PLL1FEED = PLLFEED_FEED2;
327 while( ( ( SC->PLL1STAT & ( 1 << 9 ) ) == 0 ) );
329 /* Setup the peripheral bus to be the same as the CPU output (100 MHz). */
330 SC->PCLKSEL0 = 0x05555555;
332 /* Configure the LEDs. */
333 vParTestInitialise();
335 /*-----------------------------------------------------------*/
337 void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
339 /* This function will get called if a task overflows its stack. */
346 /*-----------------------------------------------------------*/
348 void vConfigureTimerForRunTimeStats( void )
350 const unsigned long TCR_COUNT_RESET = 2, CTCR_CTM_TIMER = 0x00, TCR_COUNT_ENABLE = 0x01;
352 /* This function configures a timer that is used as the time base when
353 collecting run time statistical information - basically the percentage
354 of CPU time that each task is utilising. It is called automatically when
355 the scheduler is started (assuming configGENERATE_RUN_TIME_STATS is set
358 /* Power up and feed the timer. */
360 SC->PCLKSEL0 = (SC->PCLKSEL0 & (~(0x3<<2))) | (0x01 << 2);
363 TIM0->TCR = TCR_COUNT_RESET;
366 TIM0->CTCR = CTCR_CTM_TIMER;
368 /* Prescale to a frequency that is good enough to get a decent resolution,
369 but not too fast so as to overflow all the time. */
370 TIM0->PR = ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;
372 /* Start the counter. */
373 TIM0->TCR = TCR_COUNT_ENABLE;
375 /*-----------------------------------------------------------*/