]> git.sur5r.net Git - freertos/blob - Demo/Common/Full/death.c
Ready for V5.1.1 release.
[freertos] / Demo / Common / Full / death.c
1 /*\r
2         FreeRTOS.org V5.1.1 - Copyright (C) 2003-2008 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS.org is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS.org; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS.org, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section \r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26     ***************************************************************************\r
27     ***************************************************************************\r
28     *                                                                         *\r
29     * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *\r
30     * and even write all or part of your application on your behalf.          *\r
31     * See http://www.OpenRTOS.com for details of the services we provide to   *\r
32     * expedite your project.                                                  *\r
33     *                                                                         *\r
34     ***************************************************************************\r
35     ***************************************************************************\r
36 \r
37         Please ensure to read the configuration and relevant port sections of the\r
38         online documentation.\r
39 \r
40         http://www.FreeRTOS.org - Documentation, latest information, license and \r
41         contact details.\r
42 \r
43         http://www.SafeRTOS.com - A version that is certified for use in safety \r
44         critical systems.\r
45 \r
46         http://www.OpenRTOS.com - Commercial support, development, porting, \r
47         licensing and training services.\r
48 */\r
49 \r
50 /**\r
51  * Create a single persistent task which periodically dynamically creates another \r
52  * four tasks.  The original task is called the creator task, the four tasks it \r
53  * creates are called suicidal tasks.\r
54  *\r
55  * Two of the created suicidal tasks kill one other suicidal task before killing \r
56  * themselves - leaving just the original task remaining.  \r
57  *\r
58  * The creator task must be spawned after all of the other demo application tasks \r
59  * as it keeps a check on the number of tasks under the scheduler control.  The \r
60  * number of tasks it expects to see running should never be greater than the \r
61  * number of tasks that were in existence when the creator task was spawned, plus \r
62  * one set of four suicidal tasks.  If this number is exceeded an error is flagged.\r
63  *\r
64  * \page DeathC death.c\r
65  * \ingroup DemoFiles\r
66  * <HR>\r
67  */\r
68 \r
69 /*\r
70 Changes from V2.0.0\r
71 \r
72         + Delay periods are now specified using variables and constants of\r
73           portTickType rather than unsigned portLONG.\r
74 */\r
75 \r
76 #include <stdlib.h>\r
77 \r
78 /* Scheduler include files. */\r
79 #include "FreeRTOS.h"\r
80 #include "task.h"\r
81 \r
82 /* Demo program include files. */\r
83 #include "death.h"\r
84 #include "print.h"\r
85 \r
86 #define deathSTACK_SIZE         ( ( unsigned portSHORT ) 512 )\r
87 \r
88 /* The task originally created which is responsible for periodically dynamically \r
89 creating another four tasks. */\r
90 static void vCreateTasks( void *pvParameters );\r
91 \r
92 /* The task function of the dynamically created tasks. */\r
93 static void vSuicidalTask( void *pvParameters );\r
94 \r
95 /* A variable which is incremented every time the dynamic tasks are created.  This \r
96 is used to check that the task is still running. */\r
97 static volatile portSHORT sCreationCount = 0;\r
98 \r
99 /* Used to store the number of tasks that were originally running so the creator \r
100 task can tell if any of the suicidal tasks have failed to die. */\r
101 static volatile unsigned portBASE_TYPE uxTasksRunningAtStart = 0;\r
102 static const unsigned portBASE_TYPE uxMaxNumberOfExtraTasksRunning = 5;\r
103 \r
104 /* Used to store a handle to the tasks that should be killed by a suicidal task, \r
105 before it kills itself. */\r
106 xTaskHandle xCreatedTask1, xCreatedTask2;\r
107 \r
108 /*-----------------------------------------------------------*/\r
109 \r
110 void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority )\r
111 {\r
112 unsigned portBASE_TYPE *puxPriority;\r
113 \r
114         /* Create the Creator tasks - passing in as a parameter the priority at which \r
115         the suicidal tasks should be created. */\r
116         puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) );\r
117         *puxPriority = uxPriority;\r
118 \r
119         xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL );\r
120 \r
121         /* Record the number of tasks that are running now so we know if any of the \r
122         suicidal tasks have failed to be killed. */\r
123         uxTasksRunningAtStart = uxTaskGetNumberOfTasks();\r
124 }\r
125 /*-----------------------------------------------------------*/\r
126 \r
127 static void vSuicidalTask( void *pvParameters )\r
128 {\r
129 portDOUBLE d1, d2;\r
130 xTaskHandle xTaskToKill;\r
131 const portTickType xDelay = ( portTickType ) 500 / portTICK_RATE_MS;\r
132 \r
133         if( pvParameters != NULL )\r
134         {\r
135                 /* This task is periodically created four times.  Tow created tasks are \r
136                 passed a handle to the other task so it can kill it before killing itself.  \r
137                 The other task is passed in null. */\r
138                 xTaskToKill = *( xTaskHandle* )pvParameters;\r
139         }\r
140         else\r
141         {\r
142                 xTaskToKill = NULL;\r
143         }\r
144 \r
145         for( ;; )\r
146         {\r
147                 /* Do something random just to use some stack and registers. */\r
148                 d1 = 2.4;\r
149                 d2 = 89.2;\r
150                 d2 *= d1;\r
151                 vTaskDelay( xDelay );\r
152 \r
153                 if( xTaskToKill != NULL )\r
154                 {\r
155                         /* Make sure the other task has a go before we delete it. */\r
156                         vTaskDelay( ( portTickType ) 0 );\r
157                         /* Kill the other task that was created by vCreateTasks(). */\r
158                         vTaskDelete( xTaskToKill );\r
159                         /* Kill ourselves. */\r
160                         vTaskDelete( NULL );\r
161                 }\r
162         }\r
163 }/*lint !e818 !e550 Function prototype must be as per standard for task functions. */\r
164 /*-----------------------------------------------------------*/\r
165 \r
166 static void vCreateTasks( void *pvParameters )\r
167 {\r
168 const portTickType xDelay = ( portTickType ) 1000 / portTICK_RATE_MS;\r
169 unsigned portBASE_TYPE uxPriority;\r
170 const portCHAR * const pcTaskStartMsg = "Create task started.\r\n";\r
171 \r
172         /* Queue a message for printing to say the task has started. */\r
173         vPrintDisplayMessage( &pcTaskStartMsg );\r
174 \r
175         uxPriority = *( unsigned portBASE_TYPE * ) pvParameters;\r
176         vPortFree( pvParameters );\r
177 \r
178         for( ;; )\r
179         {\r
180                 /* Just loop round, delaying then creating the four suicidal tasks. */\r
181                 vTaskDelay( xDelay );\r
182 \r
183                 xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask1 );\r
184                 xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask1, uxPriority, NULL );\r
185 \r
186                 xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask2 );\r
187                 xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask2, uxPriority, NULL );\r
188 \r
189                 ++sCreationCount;\r
190         }\r
191 }\r
192 /*-----------------------------------------------------------*/\r
193 \r
194 /* This is called to check that the creator task is still running and that there \r
195 are not any more than four extra tasks. */\r
196 portBASE_TYPE xIsCreateTaskStillRunning( void )\r
197 {\r
198 static portSHORT sLastCreationCount = 0;\r
199 portSHORT sReturn = pdTRUE;\r
200 unsigned portBASE_TYPE uxTasksRunningNow;\r
201 \r
202         if( sLastCreationCount == sCreationCount )\r
203         {\r
204                 sReturn = pdFALSE;\r
205         }\r
206         \r
207         uxTasksRunningNow = uxTaskGetNumberOfTasks();\r
208 \r
209         if( uxTasksRunningNow < uxTasksRunningAtStart )\r
210         {\r
211                 sReturn = pdFALSE;\r
212         }\r
213         else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning )\r
214         {\r
215                 sReturn = pdFALSE;\r
216         }\r
217         else\r
218         {\r
219                 /* Everything is okay. */\r
220         }\r
221 \r
222         return sReturn;\r
223 }\r
224 \r
225 \r