2 FreeRTOS V8.2.2 - Copyright (C) 2015 Real Time Engineers Ltd.
\r
5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 This file is part of the FreeRTOS distribution.
\r
9 FreeRTOS is free software; you can redistribute it and/or modify it under
\r
10 the terms of the GNU General Public License (version 2) as published by the
\r
11 Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
\r
13 ***************************************************************************
\r
14 >>! NOTE: The modification to the GPL is included to allow you to !<<
\r
15 >>! distribute a combined work that includes FreeRTOS without being !<<
\r
16 >>! obliged to provide the source code for proprietary components !<<
\r
17 >>! outside of the FreeRTOS kernel. !<<
\r
18 ***************************************************************************
\r
20 FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
\r
21 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
\r
22 FOR A PARTICULAR PURPOSE. Full license text is available on the following
\r
23 link: http://www.freertos.org/a00114.html
\r
25 ***************************************************************************
\r
27 * FreeRTOS provides completely free yet professionally developed, *
\r
28 * robust, strictly quality controlled, supported, and cross *
\r
29 * platform software that is more than just the market leader, it *
\r
30 * is the industry's de facto standard. *
\r
32 * Help yourself get started quickly while simultaneously helping *
\r
33 * to support the FreeRTOS project by purchasing a FreeRTOS *
\r
34 * tutorial book, reference manual, or both: *
\r
35 * http://www.FreeRTOS.org/Documentation *
\r
37 ***************************************************************************
\r
39 http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
\r
40 the FAQ page "My application does not run, what could be wrong?". Have you
\r
41 defined configASSERT()?
\r
43 http://www.FreeRTOS.org/support - In return for receiving this top quality
\r
44 embedded software for free we request you assist our global community by
\r
45 participating in the support forum.
\r
47 http://www.FreeRTOS.org/training - Investing in training allows your team to
\r
48 be as productive as possible as early as possible. Now you can receive
\r
49 FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
\r
50 Ltd, and the world's leading authority on the world's leading RTOS.
\r
52 http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
\r
53 including FreeRTOS+Trace - an indispensable productivity tool, a DOS
\r
54 compatible FAT file system, and our tiny thread aware UDP/IP stack.
\r
56 http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
\r
57 Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
\r
59 http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
\r
60 Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
\r
61 licenses offer ticketed support, indemnification and commercial middleware.
\r
63 http://www.SafeRTOS.com - High Integrity Systems also provide a safety
\r
64 engineered and independently SIL3 certified version for use in safety and
\r
65 mission critical applications that require provable dependability.
\r
73 + The created tasks now include calls to tskYIELD(), allowing them to be used
\r
74 with the cooperative scheduler.
\r
78 * This does the same as flop. c, but uses variables of type long instead of
\r
81 * As with flop. c, the tasks created in this file are a good test of the
\r
82 * scheduler context switch mechanism. The processor has to access 32bit
\r
83 * variables in two or four chunks (depending on the processor). The low
\r
84 * priority of these tasks means there is a high probability that a context
\r
85 * switch will occur mid calculation. See the flop. c documentation for
\r
88 * \page IntegerC integer.c
\r
89 * \ingroup DemoFiles
\r
96 + The constants used in the calculations are larger to ensure the
\r
97 optimiser does not truncate them to 16 bits.
\r
100 #include <stdlib.h>
\r
102 /* Scheduler include files. */
\r
103 #include "FreeRTOS.h"
\r
107 /* Demo program include files. */
\r
108 #include "integer.h"
\r
110 #define intgSTACK_SIZE ( ( unsigned short ) 256 )
\r
111 #define intgNUMBER_OF_TASKS ( 8 )
\r
113 /* Four tasks, each of which performs a different calculation on four byte
\r
114 variables. Each of the four is created twice. */
\r
115 static void vCompeteingIntMathTask1( void *pvParameters );
\r
116 static void vCompeteingIntMathTask2( void *pvParameters );
\r
117 static void vCompeteingIntMathTask3( void *pvParameters );
\r
118 static void vCompeteingIntMathTask4( void *pvParameters );
\r
120 /* These variables are used to check that all the tasks are still running. If a
\r
121 task gets a calculation wrong it will stop incrementing its check variable. */
\r
122 static volatile unsigned short usTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
\r
123 /*-----------------------------------------------------------*/
\r
125 void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority )
\r
127 xTaskCreate( vCompeteingIntMathTask1, "IntMath1", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL );
\r
128 xTaskCreate( vCompeteingIntMathTask2, "IntMath2", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL );
\r
129 xTaskCreate( vCompeteingIntMathTask3, "IntMath3", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL );
\r
130 xTaskCreate( vCompeteingIntMathTask4, "IntMath4", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL );
\r
131 xTaskCreate( vCompeteingIntMathTask1, "IntMath5", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL );
\r
132 xTaskCreate( vCompeteingIntMathTask2, "IntMath6", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL );
\r
133 xTaskCreate( vCompeteingIntMathTask3, "IntMath7", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL );
\r
134 xTaskCreate( vCompeteingIntMathTask4, "IntMath8", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL );
\r
136 /*-----------------------------------------------------------*/
\r
138 static void vCompeteingIntMathTask1( void *pvParameters )
\r
140 long l1, l2, l3, l4;
\r
141 short sError = pdFALSE;
\r
142 volatile unsigned short *pusTaskCheckVariable;
\r
143 const long lAnswer = ( ( long ) 74565L + ( long ) 1234567L ) * ( long ) -918L;
\r
144 const char * const pcTaskStartMsg = "Integer math task 1 started.\r\n";
\r
145 const char * const pcTaskFailMsg = "Integer math task 1 failed.\r\n";
\r
147 /* Queue a message for printing to say the task has started. */
\r
148 vPrintDisplayMessage( &pcTaskStartMsg );
\r
150 /* The variable this task increments to show it is still running is passed in
\r
151 as the parameter. */
\r
152 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
154 /* Keep performing a calculation and checking the result against a constant. */
\r
157 l1 = ( long ) 74565L;
\r
158 l2 = ( long ) 1234567L;
\r
159 l3 = ( long ) -918L;
\r
161 l4 = ( l1 + l2 ) * l3;
\r
165 /* If the calculation does not match the expected constant, stop the
\r
166 increment of the check variable. */
\r
167 if( l4 != lAnswer )
\r
169 vPrintDisplayMessage( &pcTaskFailMsg );
\r
173 if( sError == pdFALSE )
\r
175 /* If the calculation has always been correct, increment the check
\r
176 variable so we know this task is still running okay. */
\r
177 ( *pusTaskCheckVariable )++;
\r
181 /*-----------------------------------------------------------*/
\r
183 static void vCompeteingIntMathTask2( void *pvParameters )
\r
185 long l1, l2, l3, l4;
\r
186 short sError = pdFALSE;
\r
187 volatile unsigned short *pusTaskCheckVariable;
\r
188 const long lAnswer = ( ( long ) -389000L / ( long ) 329999L ) * ( long ) -89L;
\r
189 const char * const pcTaskStartMsg = "Integer math task 2 started.\r\n";
\r
190 const char * const pcTaskFailMsg = "Integer math task 2 failed.\r\n";
\r
192 /* Queue a message for printing to say the task has started. */
\r
193 vPrintDisplayMessage( &pcTaskStartMsg );
\r
195 /* The variable this task increments to show it is still running is passed in
\r
196 as the parameter. */
\r
197 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
199 /* Keep performing a calculation and checking the result against a constant. */
\r
206 l4 = ( l1 / l2 ) * l3;
\r
210 /* If the calculation does not match the expected constant, stop the
\r
211 increment of the check variable. */
\r
212 if( l4 != lAnswer )
\r
214 vPrintDisplayMessage( &pcTaskFailMsg );
\r
218 if( sError == pdFALSE )
\r
220 /* If the calculation has always been correct, increment the check
\r
221 variable so we know this task is still running okay. */
\r
222 ( *pusTaskCheckVariable )++;
\r
226 /*-----------------------------------------------------------*/
\r
228 static void vCompeteingIntMathTask3( void *pvParameters )
\r
230 long *plArray, lTotal1, lTotal2;
\r
231 short sError = pdFALSE;
\r
232 volatile unsigned short *pusTaskCheckVariable;
\r
233 const unsigned short usArraySize = ( unsigned short ) 250;
\r
234 unsigned short usPosition;
\r
235 const char * const pcTaskStartMsg = "Integer math task 3 started.\r\n";
\r
236 const char * const pcTaskFailMsg = "Integer math task 3 failed.\r\n";
\r
238 /* Queue a message for printing to say the task has started. */
\r
239 vPrintDisplayMessage( &pcTaskStartMsg );
\r
241 /* The variable this task increments to show it is still running is passed in
\r
242 as the parameter. */
\r
243 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
245 /* Create the array we are going to use for our check calculation. */
\r
246 plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) );
\r
248 /* Keep filling the array, keeping a running total of the values placed in the
\r
249 array. Then run through the array adding up all the values. If the two totals
\r
250 do not match, stop the check variable from incrementing. */
\r
253 lTotal1 = ( long ) 0;
\r
254 lTotal2 = ( long ) 0;
\r
256 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
\r
258 plArray[ usPosition ] = ( long ) usPosition + ( long ) 5;
\r
259 lTotal1 += ( long ) usPosition + ( long ) 5;
\r
264 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
\r
266 lTotal2 += plArray[ usPosition ];
\r
269 if( lTotal1 != lTotal2 )
\r
271 vPrintDisplayMessage( &pcTaskFailMsg );
\r
277 if( sError == pdFALSE )
\r
279 /* If the calculation has always been correct, increment the check
\r
280 variable so we know this task is still running okay. */
\r
281 ( *pusTaskCheckVariable )++;
\r
285 /*-----------------------------------------------------------*/
\r
287 static void vCompeteingIntMathTask4( void *pvParameters )
\r
289 long *plArray, lTotal1, lTotal2;
\r
290 short sError = pdFALSE;
\r
291 volatile unsigned short *pusTaskCheckVariable;
\r
292 const unsigned short usArraySize = 250;
\r
293 unsigned short usPosition;
\r
294 const char * const pcTaskStartMsg = "Integer math task 4 started.\r\n";
\r
295 const char * const pcTaskFailMsg = "Integer math task 4 failed.\r\n";
\r
297 /* Queue a message for printing to say the task has started. */
\r
298 vPrintDisplayMessage( &pcTaskStartMsg );
\r
300 /* The variable this task increments to show it is still running is passed in
\r
301 as the parameter. */
\r
302 pusTaskCheckVariable = ( unsigned short * ) pvParameters;
\r
304 /* Create the array we are going to use for our check calculation. */
\r
305 plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) );
\r
307 /* Keep filling the array, keeping a running total of the values placed in the
\r
308 array. Then run through the array adding up all the values. If the two totals
\r
309 do not match, stop the check variable from incrementing. */
\r
312 lTotal1 = ( long ) 0;
\r
313 lTotal2 = ( long ) 0;
\r
315 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
\r
317 plArray[ usPosition ] = ( long ) usPosition * ( long ) 12;
\r
318 lTotal1 += ( long ) usPosition * ( long ) 12;
\r
323 for( usPosition = 0; usPosition < usArraySize; usPosition++ )
\r
325 lTotal2 += plArray[ usPosition ];
\r
329 if( lTotal1 != lTotal2 )
\r
331 vPrintDisplayMessage( &pcTaskFailMsg );
\r
337 if( sError == pdFALSE )
\r
339 /* If the calculation has always been correct, increment the check
\r
340 variable so we know this task is still running okay. */
\r
341 ( *pusTaskCheckVariable )++;
\r
345 /*-----------------------------------------------------------*/
\r
347 /* This is called to check that all the created tasks are still running. */
\r
348 portBASE_TYPE xAreIntegerMathsTaskStillRunning( void )
\r
350 /* Keep a history of the check variables so we know if they have been incremented
\r
351 since the last call. */
\r
352 static unsigned short usLastTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 };
\r
353 portBASE_TYPE xReturn = pdTRUE, xTask;
\r
355 /* Check the maths tasks are still running by ensuring their check variables
\r
356 are still incrementing. */
\r
357 for( xTask = 0; xTask < intgNUMBER_OF_TASKS; xTask++ )
\r
359 if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )
\r
361 /* The check has not incremented so an error exists. */
\r
365 usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];
\r