2 * FreeRTOS Kernel V10.3.0
\r
3 * Copyright (C) 2020 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.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 * http://www.FreeRTOS.org
\r
23 * http://aws.amazon.com/freertos
\r
25 * 1 tab == 4 spaces!
\r
29 * Creates all the demo application tasks, then starts the scheduler.
\r
30 * In addition to the standard demo tasks, the following tasks and tests are
\r
31 * defined and/or created within this file:
\r
33 * "Check" task - This only executes every five seconds but has the highest
\r
34 * priority so is guaranteed to get processor time. Its main function is to
\r
35 * check that all the standard demo tasks are still operational. The check
\r
36 * task will write an error message to the console should an error be detected
\r
37 * within any of the demo tasks. The check task also toggles the LED defined
\r
38 * by mainCHECK_LED every 5 seconds while the system is error free, with the
\r
39 * toggle rate increasing to every 500ms should an error occur.
\r
41 * "Reg test" tasks - These fill the registers with known values, then check
\r
42 * that each register still contains its expected value. Each task uses
\r
43 * different values. The tasks run with very low priority so get preempted very
\r
44 * frequently. A register containing an unexpected value is indicative of an
\r
45 * error in the context switching mechanism.
\r
47 * See the online documentation for this demo for more information on interrupt
\r
51 /* Standard includes. */
\r
56 /* Scheduler includes. */
\r
57 #include "FreeRTOS.h"
\r
61 /* Demo application includes. */
\r
62 #include "partest.h"
\r
64 #include "blocktim.h"
\r
65 #include "semtest.h"
\r
67 #include "comtest.h"
\r
68 #include "GenQTest.h"
\r
70 #include "integer.h"
\r
73 #include "dynamic.h"
\r
74 #include "countsem.h"
\r
75 #include "recmutex.h"
\r
78 /*-----------------------------------------------------------*/
\r
80 #error The batch file Demo\NiosII_CycloneIII_DBC3C40_GCC\CreateProjectDirectoryStructure.bat must be executed before the project is imported into the workspace. Failure to do this will result in the include paths stored in the project being deleted. Remove this line after CreateProjectDirectoryStructure.bat has been executed.
\r
82 /*-----------------------------------------------------------*/
\r
84 /* The rate at which the LED controlled by the 'check' task will toggle when no
\r
85 errors have been detected. */
\r
86 #define mainNO_ERROR_PERIOD ( 5000 )
\r
88 /* The rate at which the LED controlled by the 'check' task will toggle when an
\r
89 error has been detected. */
\r
90 #define mainERROR_PERIOD ( 500 )
\r
92 /* The LED toggled by the Check task. */
\r
93 #define mainCHECK_LED ( 7 )
\r
95 /* The first LED used by the ComTest tasks. One LED toggles each time a
\r
96 character is transmitted, and one each time a character is received and
\r
97 verified as being the expected character. */
\r
98 #define mainCOMTEST_LED ( 4 )
\r
100 /* Priority definitions for the tasks in the demo application. */
\r
101 #define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
\r
102 #define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
\r
103 #define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
\r
104 #define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
105 #define mainQUEUE_BLOCK_PRIORITY ( tskIDLE_PRIORITY + 3 )
\r
106 #define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
\r
107 #define mainSEMAPHORE_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
\r
108 #define mainGENERIC_QUEUE_PRIORITY ( tskIDLE_PRIORITY )
\r
109 #define mainREG_TEST_PRIORITY ( tskIDLE_PRIORITY )
\r
112 #define mainDONT_WAIT ( 0 )
\r
114 /* The parameters passed to the reg test tasks. This is just done to check
\r
115 the parameter passing mechanism is working correctly. */
\r
116 #define mainREG_TEST_1_PARAMETER ( ( void * ) 0x12345678 )
\r
117 #define mainREG_TEST_2_PARAMETER ( ( void * ) 0x87654321 )
\r
119 /*-----------------------------------------------------------*/
\r
122 * Setup the processor ready for the demo.
\r
124 static void prvSetupHardware( void );
\r
127 * Execute all of the check functions to ensure the tests haven't failed.
\r
129 static void prvCheckTask( void *pvParameters );
\r
132 * The register test (or RegTest) tasks as described at the top of this file.
\r
134 static void prvFirstRegTestTask( void *pvParameters );
\r
135 static void prvSecondRegTestTask( void *pvParameters );
\r
137 /*-----------------------------------------------------------*/
\r
139 /* Counters that are incremented on each iteration of the RegTest tasks
\r
140 so long as no errors have been detected. */
\r
141 volatile unsigned long ulRegTest1Counter = 0UL, ulRegTest2Counter = 0UL;
\r
143 /*-----------------------------------------------------------*/
\r
146 * Create the demo tasks then start the scheduler.
\r
150 /* Configure any hardware required for this demo. */
\r
151 prvSetupHardware();
\r
153 /* Create all the other standard demo tasks. These serve no purpose other
\r
154 than to test the port and demonstrate the use of the FreeRTOS API. */
\r
155 vStartLEDFlashTasks( tskIDLE_PRIORITY );
\r
156 vStartIntegerMathTasks( mainGENERIC_QUEUE_PRIORITY );
\r
157 vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
\r
158 vStartBlockingQueueTasks( mainQUEUE_BLOCK_PRIORITY );
\r
159 vCreateBlockTimeTasks();
\r
160 vStartSemaphoreTasks( mainSEMAPHORE_TASK_PRIORITY );
\r
161 vStartDynamicPriorityTasks();
\r
162 vStartQueuePeekTasks();
\r
163 vStartGenericQueueTasks( mainGENERIC_QUEUE_PRIORITY );
\r
164 vStartCountingSemaphoreTasks();
\r
165 vStartRecursiveMutexTasks();
\r
166 vAltStartComTestTasks( mainCOM_TEST_PRIORITY, 0, mainCOMTEST_LED );
\r
168 /* prvCheckTask uses sprintf so requires more stack. */
\r
169 xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
\r
171 /* The RegTest tasks as described at the top of this file. */
\r
172 xTaskCreate( prvFirstRegTestTask, "Rreg1", configMINIMAL_STACK_SIZE, mainREG_TEST_1_PARAMETER, mainREG_TEST_PRIORITY, NULL );
\r
173 xTaskCreate( prvSecondRegTestTask, "Rreg2", configMINIMAL_STACK_SIZE, mainREG_TEST_2_PARAMETER, mainREG_TEST_PRIORITY, NULL );
\r
175 /* This task has to be created last as it keeps account of the number of tasks
\r
176 it expects to see running. */
\r
177 vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
\r
179 /* Finally start the scheduler. */
\r
180 vTaskStartScheduler();
\r
182 /* Will only reach here if there is insufficient heap available to start
\r
186 /*-----------------------------------------------------------*/
\r
188 static void prvSetupHardware( void )
\r
190 /* Setup the digital IO for the LED's. */
\r
191 vParTestInitialise();
\r
193 /*-----------------------------------------------------------*/
\r
195 void vApplicationStackOverflowHook( void )
\r
197 /* Look at pxCurrentTCB to see which task overflowed its stack. */
\r
203 /*-----------------------------------------------------------*/
\r
205 void _general_exception_handler( unsigned long ulCause, unsigned long ulStatus )
\r
207 /* This overrides the definition provided by the kernel. Other exceptions
\r
208 should be handled here. */
\r
214 /*-----------------------------------------------------------*/
\r
216 static void prvCheckTask( void *pvParameters )
\r
218 TickType_t xLastExecutionTime, ulTicksToWait = mainNO_ERROR_PERIOD;
\r
219 unsigned long ulLastRegTest1 = 0UL, ulLastRegTest2 = 0UL;
\r
220 const char * pcMessage;
\r
222 /* Initialise the variable used to control our iteration rate prior to
\r
224 xLastExecutionTime = xTaskGetTickCount();
\r
228 /* Wait until it is time to run the tests again. */
\r
229 vTaskDelayUntil( &xLastExecutionTime, ulTicksToWait );
\r
231 /* Have any of the standard demo tasks detected an error in their
\r
233 if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
\r
235 ulTicksToWait = mainERROR_PERIOD;
\r
236 pcMessage = "Error: Integer Maths.\n";
\r
238 else if( xAreGenericQueueTasksStillRunning() != pdTRUE )
\r
240 ulTicksToWait = mainERROR_PERIOD;
\r
241 pcMessage = "Error: GenQ.\n";
\r
243 else if( xAreBlockingQueuesStillRunning() != pdTRUE )
\r
245 ulTicksToWait = mainERROR_PERIOD;
\r
246 pcMessage = "Error: BlockQ.\n";
\r
248 else if( xArePollingQueuesStillRunning() != pdTRUE )
\r
250 ulTicksToWait = mainERROR_PERIOD;
\r
251 pcMessage = "Error: PollQ.\n";
\r
253 else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
\r
255 ulTicksToWait = mainERROR_PERIOD;
\r
256 pcMessage = "Error: PeekQ.\n";
\r
258 else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
\r
260 ulTicksToWait = mainERROR_PERIOD;
\r
261 pcMessage = "Error: Block Time.\n";
\r
263 else if( xAreSemaphoreTasksStillRunning() != pdTRUE )
\r
265 ulTicksToWait = mainERROR_PERIOD;
\r
266 pcMessage = "Error: Semaphore Test.\n";
\r
268 else if( xAreComTestTasksStillRunning() != pdTRUE )
\r
270 ulTicksToWait = mainERROR_PERIOD;
\r
271 pcMessage = "Error: Comm Test.\n";
\r
273 else if( xIsCreateTaskStillRunning() != pdTRUE )
\r
275 ulTicksToWait = mainERROR_PERIOD;
\r
276 pcMessage = "Error: Suicidal Tasks.\n";
\r
278 else if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
\r
280 ulTicksToWait = mainERROR_PERIOD;
\r
281 pcMessage = "Error: Dynamic Priority.\n";
\r
283 else if( xAreCountingSemaphoreTasksStillRunning() != pdTRUE )
\r
285 ulTicksToWait = mainERROR_PERIOD;
\r
286 pcMessage = "Error: Count Semaphore.\n";
\r
288 else if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
\r
290 ulTicksToWait = mainERROR_PERIOD;
\r
291 pcMessage = "Error: Recursive Mutex.\n";
\r
293 else if( ulLastRegTest1 == ulRegTest1Counter )
\r
295 /* ulRegTest1Counter is no longer being incremented, indicating
\r
296 that an error has been discovered in prvFirstRegTestTask(). */
\r
297 ulTicksToWait = mainERROR_PERIOD;
\r
298 pcMessage = "Error: Reg Test1.\n";
\r
300 else if( ulLastRegTest2 == ulRegTest2Counter )
\r
302 /* ulRegTest2Counter is no longer being incremented, indicating
\r
303 that an error has been discovered in prvSecondRegTestTask(). */
\r
304 ulTicksToWait = mainERROR_PERIOD;
\r
305 pcMessage = "Error: Reg Test2.\n";
\r
312 /* Remember the counter values this time around so a counter failing
\r
313 to be incremented correctly can be spotted. */
\r
314 ulLastRegTest1 = ulRegTest1Counter;
\r
315 ulLastRegTest2 = ulRegTest2Counter;
\r
317 /* Print out an error message if there is one. Mutual exclusion is
\r
318 not used as this is the only task accessing stdout. */
\r
319 if( pcMessage != NULL )
\r
321 printf( pcMessage );
\r
324 /* Provide visual feedback of the system status. If the LED is toggled
\r
325 every 5 seconds then no errors have been found. If the LED is toggled
\r
326 every 500ms then at least one error has been found. */
\r
327 vParTestToggleLED( mainCHECK_LED );
\r
330 /*-----------------------------------------------------------*/
\r
332 static void prvFirstRegTestTask( void *pvParameters )
\r
334 /* Check the parameters are passed in as expected. */
\r
335 if( pvParameters != mainREG_TEST_1_PARAMETER )
\r
337 /* Don't execute any further so an error is recognised by the check
\r
339 vTaskDelete( NULL );
\r
342 /* Fill registers with known values, then check that each register still
\r
343 contains its expected value. An incorrect value is indicative of an error
\r
344 in the context switching process.
\r
346 If no errors are found ulRegTest1Counter is incremented. The check task
\r
347 will recognise an error if ulRegTest1Counter stops being incremented.
\r
348 This task also performs a manual yield in the middle of its execution, just
\r
349 to increase the test coverage. */
\r
351 " .extern ulRegTest1Counter \n" \
\r
353 " addi r3, r0, 3 \n" \
\r
354 " addi r4, r0, 4 \n" \
\r
355 " addi r5, r0, 5 \n" \
\r
356 " addi r6, r0, 6 \n" \
\r
357 " addi r7, r0, 7 \n" \
\r
358 " addi r8, r0, 8 \n" \
\r
359 " addi r9, r0, 9 \n" \
\r
360 " addi r10, r0, 10 \n" \
\r
361 " addi r11, r0, 11 \n" \
\r
362 " addi r12, r0, 12 \n" \
\r
363 " addi r13, r0, 13 \n" \
\r
364 " addi r14, r0, 14 \n" \
\r
365 " addi r15, r0, 15 \n" \
\r
366 " addi r16, r0, 16 \n" \
\r
367 " addi r17, r0, 17 \n" \
\r
368 " addi r18, r0, 18 \n" \
\r
369 " addi r19, r0, 19 \n" \
\r
370 " addi r20, r0, 20 \n" \
\r
371 " addi r21, r0, 21 \n" \
\r
372 " addi r22, r0, 22 \n" \
\r
373 " addi r23, r0, 23 \n" \
\r
374 " addi r28, r0, 28 \n" \
\r
375 " addi r31, r0, 31 \n" \
\r
377 " addi r2, r0, 0 \n" \
\r
379 " bne r2, r0, RegTest1Error \n" \
\r
380 " addi r2, r0, 3 \n" \
\r
381 " bne r2, r3, RegTest1Error \n" \
\r
382 " addi r2, r0, 4 \n" \
\r
383 " bne r2, r4, RegTest1Error \n" \
\r
384 " addi r2, r0, 5 \n" \
\r
385 " bne r2, r5, RegTest1Error \n" \
\r
386 " addi r2, r0, 6 \n" \
\r
387 " bne r2, r6, RegTest1Error \n" \
\r
388 " addi r2, r0, 7 \n" \
\r
389 " bne r2, r7, RegTest1Error \n" \
\r
390 " addi r2, r0, 8 \n" \
\r
391 " bne r2, r8, RegTest1Error \n" \
\r
392 " addi r2, r0, 9 \n" \
\r
393 " bne r2, r9, RegTest1Error \n" \
\r
394 " addi r2, r0, 10 \n" \
\r
395 " bne r2, r10, RegTest1Error \n" \
\r
396 " addi r2, r0, 11 \n" \
\r
397 " bne r2, r11, RegTest1Error \n" \
\r
398 " addi r2, r0, 12 \n" \
\r
399 " bne r2, r12, RegTest1Error \n" \
\r
400 " addi r2, r0, 13 \n" \
\r
401 " bne r2, r13, RegTest1Error \n" \
\r
402 " addi r2, r0, 14 \n" \
\r
403 " bne r2, r14, RegTest1Error \n" \
\r
404 " addi r2, r0, 15 \n" \
\r
405 " bne r2, r15, RegTest1Error \n" \
\r
406 " addi r2, r0, 16 \n" \
\r
407 " bne r2, r16, RegTest1Error \n" \
\r
408 " addi r2, r0, 17 \n" \
\r
409 " bne r2, r17, RegTest1Error \n" \
\r
410 " addi r2, r0, 18 \n" \
\r
411 " bne r2, r18, RegTest1Error \n" \
\r
412 " addi r2, r0, 19 \n" \
\r
413 " bne r2, r19, RegTest1Error \n" \
\r
414 " addi r2, r0, 20 \n" \
\r
415 " bne r2, r20, RegTest1Error \n" \
\r
416 " addi r2, r0, 21 \n" \
\r
417 " bne r2, r21, RegTest1Error \n" \
\r
418 " addi r2, r0, 22 \n" \
\r
419 " bne r2, r22, RegTest1Error \n" \
\r
420 " addi r2, r0, 23 \n" \
\r
421 " bne r2, r23, RegTest1Error \n" \
\r
422 " addi r2, r0, 28 \n" \
\r
423 " bne r2, r28, RegTest1Error \n" \
\r
424 " addi r2, r0, 31 \n" \
\r
425 " bne r2, r31, RegTest1Error \n" \
\r
426 " ldw r2, %gprel(ulRegTest1Counter)(gp) \n" \
\r
427 " addi r2, r2, 1 \n" \
\r
428 " stw r2, %gprel(ulRegTest1Counter)(gp) \n" \
\r
429 " br RegTest1 \n" \
\r
430 "RegTest1Error: \n" \
\r
431 " br RegTest1Error \n"
\r
434 /*-----------------------------------------------------------*/
\r
436 static void prvSecondRegTestTask( void *pvParameters )
\r
438 /* Check the parameters are passed in as expected. */
\r
439 if( pvParameters != mainREG_TEST_2_PARAMETER )
\r
441 /* Don't execute any further so an error is recognised by the check
\r
443 vTaskDelete( NULL );
\r
446 /* Fill registers with known values, then check that each register still
\r
447 contains its expected value. An incorrect value is indicative of an error
\r
448 in the context switching process.
\r
450 If no errors are found ulRegTest2Counter is incremented. The check task
\r
451 will recognise an error if ulRegTest2Counter stops being incremented. */
\r
453 " .extern ulRegTest2Counter \n" \
\r
455 " addi r3, r0, 3 \n" \
\r
456 " addi r4, r0, 4 \n" \
\r
457 " addi r5, r0, 5 \n" \
\r
458 " addi r6, r0, 6 \n" \
\r
459 " addi r7, r0, 7 \n" \
\r
460 " addi r8, r0, 8 \n" \
\r
461 " addi r9, r0, 9 \n" \
\r
462 " addi r10, r0, 10 \n" \
\r
463 " addi r11, r0, 11 \n" \
\r
464 " addi r12, r0, 12 \n" \
\r
465 " addi r13, r0, 13 \n" \
\r
466 " addi r14, r0, 14 \n" \
\r
467 " addi r15, r0, 15 \n" \
\r
468 " addi r16, r0, 16 \n" \
\r
469 " addi r17, r0, 17 \n" \
\r
470 " addi r18, r0, 18 \n" \
\r
471 " addi r19, r0, 19 \n" \
\r
472 " addi r20, r0, 20 \n" \
\r
473 " addi r21, r0, 21 \n" \
\r
474 " addi r22, r0, 22 \n" \
\r
475 " addi r23, r0, 23 \n" \
\r
476 " addi r28, r0, 28 \n" \
\r
477 " addi r31, r0, 31 \n" \
\r
479 " addi r2, r0, 0 \n" \
\r
480 " bne r2, r0, RegTest2Error \n" \
\r
481 " addi r2, r0, 3 \n" \
\r
482 " bne r2, r3, RegTest2Error \n" \
\r
483 " addi r2, r0, 4 \n" \
\r
484 " bne r2, r4, RegTest2Error \n" \
\r
485 " addi r2, r0, 5 \n" \
\r
486 " bne r2, r5, RegTest2Error \n" \
\r
487 " addi r2, r0, 6 \n" \
\r
488 " bne r2, r6, RegTest2Error \n" \
\r
489 " addi r2, r0, 7 \n" \
\r
490 " bne r2, r7, RegTest2Error \n" \
\r
491 " addi r2, r0, 8 \n" \
\r
492 " bne r2, r8, RegTest2Error \n" \
\r
493 " addi r2, r0, 9 \n" \
\r
494 " bne r2, r9, RegTest2Error \n" \
\r
495 " addi r2, r0, 10 \n" \
\r
496 " bne r2, r10, RegTest2Error \n" \
\r
497 " addi r2, r0, 11 \n" \
\r
498 " bne r2, r11, RegTest2Error \n" \
\r
499 " addi r2, r0, 12 \n" \
\r
500 " bne r2, r12, RegTest2Error \n" \
\r
501 " addi r2, r0, 13 \n" \
\r
502 " bne r2, r13, RegTest2Error \n" \
\r
503 " addi r2, r0, 14 \n" \
\r
504 " bne r2, r14, RegTest2Error \n" \
\r
505 " addi r2, r0, 15 \n" \
\r
506 " bne r2, r15, RegTest2Error \n" \
\r
507 " addi r2, r0, 16 \n" \
\r
508 " bne r2, r16, RegTest2Error \n" \
\r
509 " addi r2, r0, 17 \n" \
\r
510 " bne r2, r17, RegTest2Error \n" \
\r
511 " addi r2, r0, 18 \n" \
\r
512 " bne r2, r18, RegTest2Error \n" \
\r
513 " addi r2, r0, 19 \n" \
\r
514 " bne r2, r19, RegTest2Error \n" \
\r
515 " addi r2, r0, 20 \n" \
\r
516 " bne r2, r20, RegTest2Error \n" \
\r
517 " addi r2, r0, 21 \n" \
\r
518 " bne r2, r21, RegTest2Error \n" \
\r
519 " addi r2, r0, 22 \n" \
\r
520 " bne r2, r22, RegTest2Error \n" \
\r
521 " addi r2, r0, 23 \n" \
\r
522 " bne r2, r23, RegTest2Error \n" \
\r
523 " addi r2, r0, 28 \n" \
\r
524 " bne r2, r28, RegTest2Error \n" \
\r
525 " addi r2, r0, 31 \n" \
\r
526 " bne r2, r31, RegTest2Error \n" \
\r
527 " ldw r2, %gprel(ulRegTest2Counter)(gp) \n" \
\r
528 " addi r2, r2, 1 \n" \
\r
529 " stw r2, %gprel(ulRegTest2Counter)(gp) \n" \
\r
530 " br RegTest2 \n" \
\r
531 "RegTest2Error: \n" \
\r
532 " br RegTest2Error \n"
\r
535 /*-----------------------------------------------------------*/
\r