2 * FreeRTOS Kernel V10.0.0
\r
3 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\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
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
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
23 * http://www.FreeRTOS.org
\r
24 * http://aws.amazon.com/freertos
\r
26 * 1 tab == 4 spaces!
\r
31 * Creates all the demo application tasks, then starts the scheduler. The WEB
\r
32 * documentation provides more details of the standard demo application tasks
\r
33 * (which just exist to test the kernel port and provide an example of how to use
\r
34 * each FreeRTOS API function).
\r
36 * In addition to the standard demo tasks, the following tasks and tests are
\r
37 * defined and/or created within this file:
\r
39 * "Check" task - This only executes every five seconds but has the highest
\r
40 * priority so is guaranteed to get processor time. Its main function is to
\r
41 * check that all the standard demo tasks are still operational. The check task
\r
42 * will toggle LED 3 (PB11) every five seconds so long as no errors have been
\r
43 * detected. The toggle rate will increase to half a second if an error has
\r
44 * been found in any task.
\r
46 * "Echo" task - This is a very basic task that simply echoes any characters
\r
47 * received on COM0 (USART1). This can be tested by transmitting a text file
\r
48 * from a dumb terminal to the STM32 USART then observing or capturing the text
\r
49 * that is echoed back. Missing characters will be all the more obvious if the
\r
50 * file contains a simple repeating string of fixed width.
\r
52 * Currently this demo does not include interrupt nesting examples. High
\r
53 * frequency timer and simpler nesting examples can be found in most Cortex-M3
\r
54 * demo applications.
\r
56 * The functions used to initialise, set and clear LED outputs are normally
\r
57 * defined in partest.c. This demo includes two partest files, one that is
\r
58 * configured for use with the Keil MCBSTM32 evaluation board (called
\r
59 * ParTest_MCBSTM32.c) and one that is configured for use with the official
\r
60 * ST Eval board (called ParTest_ST_Eval.c). One one of these files should be
\r
61 * included in the build at any one time, as appropriate for the hardware
\r
62 * actually being used.
\r
65 /* Standard includes. */
\r
68 /* Scheduler includes. */
\r
69 #include "FreeRTOS.h"
\r
73 /* Library includes. */
\r
74 #include "stm32f10x_it.h"
\r
76 /* Demo app includes. */
\r
78 #include "integer.h"
\r
80 #include "partest.h"
\r
81 #include "semtest.h"
\r
82 #include "GenQTest.h"
\r
84 #include "recmutex.h"
\r
86 /* Driver includes. */
\r
87 #include "STM32_USART.h"
\r
90 /* The time between cycles of the 'check' task - which depends on whether the
\r
91 check task has detected an error or not. */
\r
92 #define mainCHECK_DELAY_NO_ERROR ( ( TickType_t ) 5000 / portTICK_PERIOD_MS )
\r
93 #define mainCHECK_DELAY_ERROR ( ( TickType_t ) 500 / portTICK_PERIOD_MS )
\r
95 /* The LED controlled by the 'check' task. */
\r
96 #define mainCHECK_LED ( 3 )
\r
98 /* Task priorities. */
\r
99 #define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )
\r
100 #define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
101 #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
\r
102 #define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
103 #define mainECHO_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
\r
104 #define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
\r
105 #define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
\r
107 /* COM port and baud rate used by the echo task. */
\r
108 #define mainCOM0 ( 0 )
\r
109 #define mainBAUD_RATE ( 115200 )
\r
111 /*-----------------------------------------------------------*/
\r
114 * Configure the hardware for the demo.
\r
116 static void prvSetupHardware( void );
\r
118 /* The 'check' task as described at the top of this file. */
\r
119 static void prvCheckTask( void *pvParameters );
\r
121 /* A simple task that echoes all the characters that are received on COM0
\r
123 static void prvUSARTEchoTask( void *pvParameters );
\r
125 /*-----------------------------------------------------------*/
\r
133 /* Set up the clocks and memory interface. */
\r
134 prvSetupHardware();
\r
136 /* Start the standard demo tasks. These are just here to exercise the
\r
137 kernel port and provide examples of how the FreeRTOS API can be used. */
\r
138 vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
\r
139 vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
\r
140 vStartIntegerMathTasks( mainINTEGER_TASK_PRIORITY );
\r
141 vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );
\r
142 vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );
\r
143 vStartQueuePeekTasks();
\r
144 vStartRecursiveMutexTasks();
\r
146 /* Create the 'echo' task, which is also defined within this file. */
\r
147 xTaskCreate( prvUSARTEchoTask, "Echo", configMINIMAL_STACK_SIZE, NULL, mainECHO_TASK_PRIORITY, NULL );
\r
149 /* Create the 'check' task, which is also defined within this file. */
\r
150 xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
\r
152 /* Start the scheduler. */
\r
153 vTaskStartScheduler();
\r
155 /* Will only get here if there was insufficient memory to create the idle
\r
156 task. The idle task is created within vTaskStartScheduler(). */
\r
159 /*-----------------------------------------------------------*/
\r
161 /* Described at the top of this file. */
\r
162 static void prvCheckTask( void *pvParameters )
\r
164 TickType_t xLastExecutionTime;
\r
165 unsigned long ulTicksToWait = mainCHECK_DELAY_NO_ERROR;
\r
167 /* Just to remove the compiler warning about the unused parameter. */
\r
168 ( void ) pvParameters;
\r
170 /* Initialise the variable used to control our iteration rate prior to
\r
172 xLastExecutionTime = xTaskGetTickCount();
\r
176 /* Wait until it is time to run the tests again. */
\r
177 vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait );
\r
179 /* Has an error been found in any task? */
\r
180 if( xAreGenericQueueTasksStillRunning() != pdTRUE )
\r
182 /* Reduce the time between cycles of this task - which has the
\r
183 effect of increasing the rate at which the 'check' LED toggles to
\r
184 indicate the existence of an error to an observer. */
\r
185 ulTicksToWait = mainCHECK_DELAY_ERROR;
\r
187 else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
\r
189 ulTicksToWait = mainCHECK_DELAY_ERROR;
\r
191 else if( xAreBlockingQueuesStillRunning() != pdTRUE )
\r
193 ulTicksToWait = mainCHECK_DELAY_ERROR;
\r
195 else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
\r
197 ulTicksToWait = mainCHECK_DELAY_ERROR;
\r
199 else if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
\r
201 ulTicksToWait = mainCHECK_DELAY_ERROR;
\r
203 else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
\r
205 ulTicksToWait = mainCHECK_DELAY_ERROR;
\r
208 vParTestToggleLED( mainCHECK_LED );
\r
211 /*-----------------------------------------------------------*/
\r
213 /* Described at the top of this file. */
\r
214 static void prvUSARTEchoTask( void *pvParameters )
\r
218 /* String declared static to ensure it does not end up on the stack, no matter
\r
219 what the optimisation level. */
\r
220 static const char *pcLongishString =
\r
221 "ABBA was a Swedish pop music group formed in Stockholm in 1972, consisting of Anni-Frid Frida Lyngstad, "
\r
222 "Björn Ulvaeus, Benny Andersson and Agnetha Fältskog. Throughout the band's existence, Fältskog and Ulvaeus "
\r
223 "were a married couple, as were Lyngstad and Andersson - although both couples later divorced. They became one "
\r
224 "of the most commercially successful acts in the history of popular music, and they topped the charts worldwide "
\r
225 "from 1972 to 1983. ABBA gained international popularity employing catchy song hooks, simple lyrics, sound "
\r
226 "effects (reverb, phasing) and a Wall of Sound achieved by overdubbing the female singers' voices in multiple "
\r
227 "harmonies. As their popularity grew, they were sought after to tour Europe, Australia, and North America, drawing "
\r
228 "crowds of ardent fans, notably in Australia. Touring became a contentious issue, being particularly cumbersome for "
\r
229 "Fältskog, but they continued to release studio albums to widespread commercial success. At the height of their "
\r
230 "popularity, however, both relationships began suffering strain that led ultimately to the collapse of first the "
\r
231 "Ulvaeus-Fältskog marriage (in 1979) and then of the Andersson-Lyngstad marriage in 1981. In the late 1970s and early "
\r
232 "1980s these relationship changes began manifesting in the group's music, as they produced more thoughtful, "
\r
233 "introspective lyrics with different compositions.";
\r
235 /* Just to avoid compiler warnings. */
\r
236 ( void ) pvParameters;
\r
238 /* Initialise COM0, which is USART1 according to the STM32 libraries. */
\r
239 lCOMPortInit( mainCOM0, mainBAUD_RATE );
\r
241 /* Try sending out a string all in one go, as a very basic test of the
\r
242 lSerialPutString() function. */
\r
243 lSerialPutString( mainCOM0, pcLongishString, strlen( pcLongishString ) );
\r
247 /* Block to wait for a character to be received on COM0. */
\r
248 xSerialGetChar( mainCOM0, &cChar, portMAX_DELAY );
\r
250 /* Write the received character back to COM0. */
\r
251 xSerialPutChar( mainCOM0, cChar, 0 );
\r
254 /*-----------------------------------------------------------*/
\r
256 static void prvSetupHardware( void )
\r
258 /* RCC system reset(for debug purpose). */
\r
262 RCC_HSEConfig( RCC_HSE_ON );
\r
264 /* Wait till HSE is ready. */
\r
265 while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
\r
267 /* HCLK = SYSCLK. */
\r
268 RCC_HCLKConfig( RCC_SYSCLK_Div1 );
\r
270 /* PCLK2 = HCLK. */
\r
271 RCC_PCLK2Config( RCC_HCLK_Div1 );
\r
273 /* PCLK1 = HCLK/2. */
\r
274 RCC_PCLK1Config( RCC_HCLK_Div2 );
\r
276 /* ADCCLK = PCLK2/4. */
\r
277 RCC_ADCCLKConfig( RCC_PCLK2_Div4 );
\r
279 /* Flash 2 wait state. */
\r
280 *( volatile unsigned long * )0x40022000 = 0x01;
\r
282 /* PLLCLK = 8MHz * 9 = 72 MHz */
\r
283 RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_9 );
\r
286 RCC_PLLCmd( ENABLE );
\r
288 /* Wait till PLL is ready. */
\r
289 while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
\r
291 /* Select PLL as system clock source. */
\r
292 RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);
\r
294 /* Wait till PLL is used as system clock source. */
\r
295 while (RCC_GetSYSCLKSource() != 0x08);
\r
297 /* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
\r
298 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC
\r
299 | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE );
\r
301 /* Set the Vector Table base address at 0x08000000. */
\r
302 NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 );
\r
304 NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
\r
306 /* Configure HCLK clock as SysTick clock source. */
\r
307 SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );
\r
309 /* Initialise the IO used for the LED outputs. */
\r
310 vParTestInitialise();
\r
312 /* SPI2 Periph clock enable */
\r
313 RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );
\r
315 /*-----------------------------------------------------------*/
\r
317 void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
\r
319 /* This function will get called if a task overflows its stack. If the
\r
320 parameters are corrupt then inspect pxCurrentTCB to find which was the
\r
324 ( void ) pcTaskName;
\r
328 /*-----------------------------------------------------------*/
\r
330 void assert_failed( unsigned char *pucFile, unsigned long ulLine )
\r