]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Common/Full/death.c
Update license information text files for the CLI, TCP and UDP products to be correct...
[freertos] / FreeRTOS / Demo / Common / Full / death.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\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
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 /**\r
30  * Create a single persistent task which periodically dynamically creates another \r
31  * four tasks.  The original task is called the creator task, the four tasks it \r
32  * creates are called suicidal tasks.\r
33  *\r
34  * Two of the created suicidal tasks kill one other suicidal task before killing \r
35  * themselves - leaving just the original task remaining.  \r
36  *\r
37  * The creator task must be spawned after all of the other demo application tasks \r
38  * as it keeps a check on the number of tasks under the scheduler control.  The \r
39  * number of tasks it expects to see running should never be greater than the \r
40  * number of tasks that were in existence when the creator task was spawned, plus \r
41  * one set of four suicidal tasks.  If this number is exceeded an error is flagged.\r
42  *\r
43  * \page DeathC death.c\r
44  * \ingroup DemoFiles\r
45  * <HR>\r
46  */\r
47 \r
48 /*\r
49 Changes from V2.0.0\r
50 \r
51         + Delay periods are now specified using variables and constants of\r
52           TickType_t rather than unsigned long.\r
53 */\r
54 \r
55 #include <stdlib.h>\r
56 \r
57 /* Scheduler include files. */\r
58 #include "FreeRTOS.h"\r
59 #include "task.h"\r
60 \r
61 /* Demo program include files. */\r
62 #include "death.h"\r
63 #include "print.h"\r
64 \r
65 #define deathSTACK_SIZE         ( ( unsigned short ) 512 )\r
66 \r
67 /* The task originally created which is responsible for periodically dynamically \r
68 creating another four tasks. */\r
69 static void vCreateTasks( void *pvParameters );\r
70 \r
71 /* The task function of the dynamically created tasks. */\r
72 static void vSuicidalTask( void *pvParameters );\r
73 \r
74 /* A variable which is incremented every time the dynamic tasks are created.  This \r
75 is used to check that the task is still running. */\r
76 static volatile short sCreationCount = 0;\r
77 \r
78 /* Used to store the number of tasks that were originally running so the creator \r
79 task can tell if any of the suicidal tasks have failed to die. */\r
80 static volatile unsigned portBASE_TYPE uxTasksRunningAtStart = 0;\r
81 static const unsigned portBASE_TYPE uxMaxNumberOfExtraTasksRunning = 5;\r
82 \r
83 /* Used to store a handle to the tasks that should be killed by a suicidal task, \r
84 before it kills itself. */\r
85 TaskHandle_t xCreatedTask1, xCreatedTask2;\r
86 \r
87 /*-----------------------------------------------------------*/\r
88 \r
89 void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority )\r
90 {\r
91 unsigned portBASE_TYPE *puxPriority;\r
92 \r
93         /* Create the Creator tasks - passing in as a parameter the priority at which \r
94         the suicidal tasks should be created. */\r
95         puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) );\r
96         *puxPriority = uxPriority;\r
97 \r
98         xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL );\r
99 \r
100         /* Record the number of tasks that are running now so we know if any of the \r
101         suicidal tasks have failed to be killed. */\r
102         uxTasksRunningAtStart = uxTaskGetNumberOfTasks();\r
103 }\r
104 /*-----------------------------------------------------------*/\r
105 \r
106 static void vSuicidalTask( void *pvParameters )\r
107 {\r
108 portDOUBLE d1, d2;\r
109 TaskHandle_t xTaskToKill;\r
110 const TickType_t xDelay = ( TickType_t ) 500 / portTICK_PERIOD_MS;\r
111 \r
112         if( pvParameters != NULL )\r
113         {\r
114                 /* This task is periodically created four times.  Tow created tasks are \r
115                 passed a handle to the other task so it can kill it before killing itself.  \r
116                 The other task is passed in null. */\r
117                 xTaskToKill = *( TaskHandle_t* )pvParameters;\r
118         }\r
119         else\r
120         {\r
121                 xTaskToKill = NULL;\r
122         }\r
123 \r
124         for( ;; )\r
125         {\r
126                 /* Do something random just to use some stack and registers. */\r
127                 d1 = 2.4;\r
128                 d2 = 89.2;\r
129                 d2 *= d1;\r
130                 vTaskDelay( xDelay );\r
131 \r
132                 if( xTaskToKill != NULL )\r
133                 {\r
134                         /* Make sure the other task has a go before we delete it. */\r
135                         vTaskDelay( ( TickType_t ) 0 );\r
136                         /* Kill the other task that was created by vCreateTasks(). */\r
137                         vTaskDelete( xTaskToKill );\r
138                         /* Kill ourselves. */\r
139                         vTaskDelete( NULL );\r
140                 }\r
141         }\r
142 }/*lint !e818 !e550 Function prototype must be as per standard for task functions. */\r
143 /*-----------------------------------------------------------*/\r
144 \r
145 static void vCreateTasks( void *pvParameters )\r
146 {\r
147 const TickType_t xDelay = ( TickType_t ) 1000 / portTICK_PERIOD_MS;\r
148 unsigned portBASE_TYPE uxPriority;\r
149 const char * const pcTaskStartMsg = "Create task started.\r\n";\r
150 \r
151         /* Queue a message for printing to say the task has started. */\r
152         vPrintDisplayMessage( &pcTaskStartMsg );\r
153 \r
154         uxPriority = *( unsigned portBASE_TYPE * ) pvParameters;\r
155         vPortFree( pvParameters );\r
156 \r
157         for( ;; )\r
158         {\r
159                 /* Just loop round, delaying then creating the four suicidal tasks. */\r
160                 vTaskDelay( xDelay );\r
161 \r
162                 xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask1 );\r
163                 xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask1, uxPriority, NULL );\r
164 \r
165                 xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask2 );\r
166                 xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask2, uxPriority, NULL );\r
167 \r
168                 ++sCreationCount;\r
169         }\r
170 }\r
171 /*-----------------------------------------------------------*/\r
172 \r
173 /* This is called to check that the creator task is still running and that there \r
174 are not any more than four extra tasks. */\r
175 portBASE_TYPE xIsCreateTaskStillRunning( void )\r
176 {\r
177 static short sLastCreationCount = 0;\r
178 short sReturn = pdTRUE;\r
179 unsigned portBASE_TYPE uxTasksRunningNow;\r
180 \r
181         if( sLastCreationCount == sCreationCount )\r
182         {\r
183                 sReturn = pdFALSE;\r
184         }\r
185         \r
186         uxTasksRunningNow = uxTaskGetNumberOfTasks();\r
187 \r
188         if( uxTasksRunningNow < uxTasksRunningAtStart )\r
189         {\r
190                 sReturn = pdFALSE;\r
191         }\r
192         else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning )\r
193         {\r
194                 sReturn = pdFALSE;\r
195         }\r
196         else\r
197         {\r
198                 /* Everything is okay. */\r
199         }\r
200 \r
201         return sReturn;\r
202 }\r
203 \r
204 \r