]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/Full/integer.c
Update version number ready for version 9 release candidate 1.
[freertos] / FreeRTOS / Demo / Common / Full / integer.c
1 /*\r
2     FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \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
12 \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
19 \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
24 \r
25     ***************************************************************************\r
26      *                                                                       *\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
31      *                                                                       *\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
36      *                                                                       *\r
37     ***************************************************************************\r
38 \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
42 \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
46 \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
51 \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
55 \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
58 \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
62 \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
66 \r
67     1 tab == 4 spaces!\r
68 */\r
69 \r
70 /*\r
71 Changes from V1.2.3\r
72         \r
73         + The created tasks now include calls to tskYIELD(), allowing them to be used\r
74           with the cooperative scheduler.\r
75 */\r
76 \r
77 /**\r
78  * This does the same as flop. c, but uses variables of type long instead of \r
79  * type double.  \r
80  *\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
86  * more information.\r
87  *\r
88  * \page IntegerC integer.c\r
89  * \ingroup DemoFiles\r
90  * <HR>\r
91  */\r
92 \r
93 /*\r
94 Changes from V1.2.1\r
95 \r
96         + The constants used in the calculations are larger to ensure the\r
97           optimiser does not truncate them to 16 bits.\r
98 */\r
99 \r
100 #include <stdlib.h>\r
101 \r
102 /* Scheduler include files. */\r
103 #include "FreeRTOS.h"\r
104 #include "task.h"\r
105 #include "print.h"\r
106 \r
107 /* Demo program include files. */\r
108 #include "integer.h"\r
109 \r
110 #define intgSTACK_SIZE          ( ( unsigned short ) 256 )\r
111 #define intgNUMBER_OF_TASKS  ( 8 )\r
112 \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
119 \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
124 \r
125 void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority )\r
126 {\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
135 }\r
136 /*-----------------------------------------------------------*/\r
137 \r
138 static void vCompeteingIntMathTask1( void *pvParameters )\r
139 {\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
146 \r
147         /* Queue a message for printing to say the task has started. */\r
148         vPrintDisplayMessage( &pcTaskStartMsg );\r
149 \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
153 \r
154         /* Keep performing a calculation and checking the result against a constant. */\r
155         for(;;)\r
156         {\r
157                 l1 = ( long ) 74565L;\r
158                 l2 = ( long ) 1234567L;\r
159                 l3 = ( long ) -918L;\r
160 \r
161                 l4 = ( l1 + l2 ) * l3;\r
162 \r
163                 taskYIELD();\r
164 \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
168                 {\r
169                         vPrintDisplayMessage( &pcTaskFailMsg );\r
170                         sError = pdTRUE;\r
171                 }\r
172 \r
173                 if( sError == pdFALSE )\r
174                 {\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
178                 }\r
179         }\r
180 }\r
181 /*-----------------------------------------------------------*/\r
182 \r
183 static void vCompeteingIntMathTask2( void *pvParameters )\r
184 {\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
191 \r
192         /* Queue a message for printing to say the task has started. */\r
193         vPrintDisplayMessage( &pcTaskStartMsg );\r
194 \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
198 \r
199         /* Keep performing a calculation and checking the result against a constant. */\r
200         for( ;; )\r
201         {\r
202                 l1 = -389000L;\r
203                 l2 = 329999L;\r
204                 l3 = -89L;\r
205 \r
206                 l4 = ( l1 / l2 ) * l3;\r
207 \r
208                 taskYIELD();\r
209 \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
213                 {\r
214                         vPrintDisplayMessage( &pcTaskFailMsg );\r
215                         sError = pdTRUE;\r
216                 }\r
217 \r
218                 if( sError == pdFALSE )\r
219                 {\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
223                 }\r
224         }\r
225 }\r
226 /*-----------------------------------------------------------*/\r
227 \r
228 static void vCompeteingIntMathTask3( void *pvParameters )\r
229 {\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
237 \r
238         /* Queue a message for printing to say the task has started. */\r
239         vPrintDisplayMessage( &pcTaskStartMsg );\r
240 \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
244 \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
247 \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
251         for( ;; )\r
252         {\r
253                 lTotal1 = ( long ) 0;\r
254                 lTotal2 = ( long ) 0;\r
255 \r
256                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )\r
257                 {\r
258                         plArray[ usPosition ] = ( long ) usPosition + ( long ) 5;\r
259                         lTotal1 += ( long ) usPosition + ( long ) 5;\r
260                 }\r
261 \r
262                 taskYIELD();\r
263 \r
264                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )\r
265                 {\r
266                         lTotal2 += plArray[ usPosition ];\r
267                 }\r
268 \r
269                 if( lTotal1 != lTotal2 )\r
270                 {\r
271                         vPrintDisplayMessage( &pcTaskFailMsg );\r
272                         sError = pdTRUE;\r
273                 }\r
274 \r
275                 taskYIELD();\r
276 \r
277                 if( sError == pdFALSE )\r
278                 {\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
282                 }\r
283         }\r
284 }\r
285 /*-----------------------------------------------------------*/\r
286 \r
287 static void vCompeteingIntMathTask4( void *pvParameters )\r
288 {\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
296 \r
297         /* Queue a message for printing to say the task has started. */\r
298         vPrintDisplayMessage( &pcTaskStartMsg );\r
299 \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
303 \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
306 \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
310         for( ;; )\r
311         {\r
312                 lTotal1 = ( long ) 0;\r
313                 lTotal2 = ( long ) 0;\r
314 \r
315                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )\r
316                 {\r
317                         plArray[ usPosition ] = ( long ) usPosition * ( long ) 12;\r
318                         lTotal1 += ( long ) usPosition * ( long ) 12;   \r
319                 }\r
320 \r
321                 taskYIELD();\r
322         \r
323                 for( usPosition = 0; usPosition < usArraySize; usPosition++ )\r
324                 {\r
325                         lTotal2 += plArray[ usPosition ];\r
326                 }\r
327 \r
328 \r
329                 if( lTotal1 != lTotal2 )\r
330                 {\r
331                         vPrintDisplayMessage( &pcTaskFailMsg );\r
332                         sError = pdTRUE;\r
333                 }\r
334 \r
335                 taskYIELD();\r
336 \r
337                 if( sError == pdFALSE )\r
338                 {\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
342                 }\r
343         }\r
344 }\r
345 /*-----------------------------------------------------------*/\r
346 \r
347 /* This is called to check that all the created tasks are still running. */\r
348 portBASE_TYPE xAreIntegerMathsTaskStillRunning( void )\r
349 {\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
354 \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
358         {\r
359                 if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] )\r
360                 {\r
361                         /* The check has not incremented so an error exists. */\r
362                         xReturn = pdFALSE;\r
363                 }\r
364 \r
365                 usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ];\r
366         }\r
367 \r
368         return xReturn;\r
369 }\r