]> begriffs open source - freertos/blob - Demo/Common/Full/death.c
Update to V5.1.2.
[freertos] / Demo / Common / Full / death.c
1 /*\r
2         FreeRTOS.org V5.1.2 - Copyright (C) 2003-2009 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     * Get the FreeRTOS eBook!  See http://www.FreeRTOS.org/Documentation      *\r
30         *                                                                         *\r
31         * This is a concise, step by step, 'hands on' guide that describes both   *\r
32         * general multitasking concepts and FreeRTOS specifics. It presents and   *\r
33         * explains numerous examples that are written using the FreeRTOS API.     *\r
34         * Full source code for all the examples is provided in an accompanying    *\r
35         * .zip file.                                                              *\r
36     *                                                                         *\r
37     ***************************************************************************\r
38     ***************************************************************************\r
39 \r
40         Please ensure to read the configuration and relevant port sections of the\r
41         online documentation.\r
42 \r
43         http://www.FreeRTOS.org - Documentation, latest information, license and \r
44         contact details.\r
45 \r
46         http://www.SafeRTOS.com - A version that is certified for use in safety \r
47         critical systems.\r
48 \r
49         http://www.OpenRTOS.com - Commercial support, development, porting, \r
50         licensing and training services.\r
51 */\r
52 \r
53 /**\r
54  * Create a single persistent task which periodically dynamically creates another \r
55  * four tasks.  The original task is called the creator task, the four tasks it \r
56  * creates are called suicidal tasks.\r
57  *\r
58  * Two of the created suicidal tasks kill one other suicidal task before killing \r
59  * themselves - leaving just the original task remaining.  \r
60  *\r
61  * The creator task must be spawned after all of the other demo application tasks \r
62  * as it keeps a check on the number of tasks under the scheduler control.  The \r
63  * number of tasks it expects to see running should never be greater than the \r
64  * number of tasks that were in existence when the creator task was spawned, plus \r
65  * one set of four suicidal tasks.  If this number is exceeded an error is flagged.\r
66  *\r
67  * \page DeathC death.c\r
68  * \ingroup DemoFiles\r
69  * <HR>\r
70  */\r
71 \r
72 /*\r
73 Changes from V2.0.0\r
74 \r
75         + Delay periods are now specified using variables and constants of\r
76           portTickType rather than unsigned portLONG.\r
77 */\r
78 \r
79 #include <stdlib.h>\r
80 \r
81 /* Scheduler include files. */\r
82 #include "FreeRTOS.h"\r
83 #include "task.h"\r
84 \r
85 /* Demo program include files. */\r
86 #include "death.h"\r
87 #include "print.h"\r
88 \r
89 #define deathSTACK_SIZE         ( ( unsigned portSHORT ) 512 )\r
90 \r
91 /* The task originally created which is responsible for periodically dynamically \r
92 creating another four tasks. */\r
93 static void vCreateTasks( void *pvParameters );\r
94 \r
95 /* The task function of the dynamically created tasks. */\r
96 static void vSuicidalTask( void *pvParameters );\r
97 \r
98 /* A variable which is incremented every time the dynamic tasks are created.  This \r
99 is used to check that the task is still running. */\r
100 static volatile portSHORT sCreationCount = 0;\r
101 \r
102 /* Used to store the number of tasks that were originally running so the creator \r
103 task can tell if any of the suicidal tasks have failed to die. */\r
104 static volatile unsigned portBASE_TYPE uxTasksRunningAtStart = 0;\r
105 static const unsigned portBASE_TYPE uxMaxNumberOfExtraTasksRunning = 5;\r
106 \r
107 /* Used to store a handle to the tasks that should be killed by a suicidal task, \r
108 before it kills itself. */\r
109 xTaskHandle xCreatedTask1, xCreatedTask2;\r
110 \r
111 /*-----------------------------------------------------------*/\r
112 \r
113 void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority )\r
114 {\r
115 unsigned portBASE_TYPE *puxPriority;\r
116 \r
117         /* Create the Creator tasks - passing in as a parameter the priority at which \r
118         the suicidal tasks should be created. */\r
119         puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) );\r
120         *puxPriority = uxPriority;\r
121 \r
122         xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL );\r
123 \r
124         /* Record the number of tasks that are running now so we know if any of the \r
125         suicidal tasks have failed to be killed. */\r
126         uxTasksRunningAtStart = uxTaskGetNumberOfTasks();\r
127 }\r
128 /*-----------------------------------------------------------*/\r
129 \r
130 static void vSuicidalTask( void *pvParameters )\r
131 {\r
132 portDOUBLE d1, d2;\r
133 xTaskHandle xTaskToKill;\r
134 const portTickType xDelay = ( portTickType ) 500 / portTICK_RATE_MS;\r
135 \r
136         if( pvParameters != NULL )\r
137         {\r
138                 /* This task is periodically created four times.  Tow created tasks are \r
139                 passed a handle to the other task so it can kill it before killing itself.  \r
140                 The other task is passed in null. */\r
141                 xTaskToKill = *( xTaskHandle* )pvParameters;\r
142         }\r
143         else\r
144         {\r
145                 xTaskToKill = NULL;\r
146         }\r
147 \r
148         for( ;; )\r
149         {\r
150                 /* Do something random just to use some stack and registers. */\r
151                 d1 = 2.4;\r
152                 d2 = 89.2;\r
153                 d2 *= d1;\r
154                 vTaskDelay( xDelay );\r
155 \r
156                 if( xTaskToKill != NULL )\r
157                 {\r
158                         /* Make sure the other task has a go before we delete it. */\r
159                         vTaskDelay( ( portTickType ) 0 );\r
160                         /* Kill the other task that was created by vCreateTasks(). */\r
161                         vTaskDelete( xTaskToKill );\r
162                         /* Kill ourselves. */\r
163                         vTaskDelete( NULL );\r
164                 }\r
165         }\r
166 }/*lint !e818 !e550 Function prototype must be as per standard for task functions. */\r
167 /*-----------------------------------------------------------*/\r
168 \r
169 static void vCreateTasks( void *pvParameters )\r
170 {\r
171 const portTickType xDelay = ( portTickType ) 1000 / portTICK_RATE_MS;\r
172 unsigned portBASE_TYPE uxPriority;\r
173 const portCHAR * const pcTaskStartMsg = "Create task started.\r\n";\r
174 \r
175         /* Queue a message for printing to say the task has started. */\r
176         vPrintDisplayMessage( &pcTaskStartMsg );\r
177 \r
178         uxPriority = *( unsigned portBASE_TYPE * ) pvParameters;\r
179         vPortFree( pvParameters );\r
180 \r
181         for( ;; )\r
182         {\r
183                 /* Just loop round, delaying then creating the four suicidal tasks. */\r
184                 vTaskDelay( xDelay );\r
185 \r
186                 xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask1 );\r
187                 xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask1, uxPriority, NULL );\r
188 \r
189                 xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask2 );\r
190                 xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask2, uxPriority, NULL );\r
191 \r
192                 ++sCreationCount;\r
193         }\r
194 }\r
195 /*-----------------------------------------------------------*/\r
196 \r
197 /* This is called to check that the creator task is still running and that there \r
198 are not any more than four extra tasks. */\r
199 portBASE_TYPE xIsCreateTaskStillRunning( void )\r
200 {\r
201 static portSHORT sLastCreationCount = 0;\r
202 portSHORT sReturn = pdTRUE;\r
203 unsigned portBASE_TYPE uxTasksRunningNow;\r
204 \r
205         if( sLastCreationCount == sCreationCount )\r
206         {\r
207                 sReturn = pdFALSE;\r
208         }\r
209         \r
210         uxTasksRunningNow = uxTaskGetNumberOfTasks();\r
211 \r
212         if( uxTasksRunningNow < uxTasksRunningAtStart )\r
213         {\r
214                 sReturn = pdFALSE;\r
215         }\r
216         else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning )\r
217         {\r
218                 sReturn = pdFALSE;\r
219         }\r
220         else\r
221         {\r
222                 /* Everything is okay. */\r
223         }\r
224 \r
225         return sReturn;\r
226 }\r
227 \r
228 \r