]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/MB96350_Softune_Dice_Kit/SegmentToggleTasks.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Demo / MB96350_Softune_Dice_Kit / SegmentToggleTasks.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  * Defines the tasks and co-routines used to toggle the segments of the two\r
31  * seven segment displays, as described at the top of main.c\r
32  */\r
33 \r
34 \r
35 #include <stdlib.h>\r
36 \r
37 /* Scheduler include files. */\r
38 #include "FreeRTOS.h"\r
39 #include "task.h"\r
40 #include "croutine.h"\r
41 \r
42 /* Demo program include files. */\r
43 #include "partest.h"\r
44 \r
45 /*-----------------------------------------------------------*/\r
46 \r
47 /* One task per segment of the left side display. */\r
48 #define ledNUM_OF_LED_TASKS     ( 7 )\r
49 \r
50 /* Each task toggles at a frequency that is a multiple of 333ms. */\r
51 #define ledFLASH_RATE_BASE      ( ( TickType_t ) 333 )\r
52 \r
53 /* One co-routine per segment of the right hand display. */\r
54 #define ledNUM_OF_LED_CO_ROUTINES       7\r
55 \r
56 /* All co-routines run at the same priority. */\r
57 #define ledCO_ROUTINE_PRIORITY          0\r
58 \r
59 /*-----------------------------------------------------------*/\r
60 \r
61 /* The task that is created 7 times. */\r
62 static void vLEDFlashTask( void *pvParameters );\r
63 \r
64 /* The co-routine that is created 7 times. */\r
65 static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, unsigned short usIndex );\r
66 \r
67 /* This task is created once, but itself creates 7 co-routines. */\r
68 static void vLEDCoRoutineControlTask( void *pvParameters );\r
69 \r
70 /* Handles to each of the 7 tasks.  Used so the tasks can be suspended\r
71 and resumed. */\r
72 static TaskHandle_t xFlashTaskHandles[ ledNUM_OF_LED_TASKS ] = { 0 };\r
73 \r
74 /* Handle to the task in which the co-routines run.  Used so the\r
75 co-routines can be suspended and resumed. */\r
76 static TaskHandle_t xCoroutineTask;\r
77 \r
78 /*-----------------------------------------------------------*/\r
79 \r
80 /**\r
81  * Creates the tasks and co-routines used to toggle the segments of the two\r
82  * seven segment displays, as described at the top of main.c\r
83  */\r
84 void vCreateFlashTasksAndCoRoutines( void )\r
85 {\r
86 signed short sLEDTask;\r
87 \r
88         /* Create the tasks that flash segments on the first LED. */\r
89         for( sLEDTask = 0; sLEDTask < ledNUM_OF_LED_TASKS; ++sLEDTask )\r
90         {\r
91                 /* Spawn the task. */\r
92                 xTaskCreate( vLEDFlashTask, "LEDt", configMINIMAL_STACK_SIZE, ( void * ) sLEDTask, ( tskIDLE_PRIORITY + 1 ), &( xFlashTaskHandles[ sLEDTask ] ) );\r
93         }\r
94 \r
95         /* Create the task in which the co-routines run.  The co-routines themselves\r
96         are created within the task. */\r
97         xTaskCreate( vLEDCoRoutineControlTask, "LEDc", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xCoroutineTask );\r
98 }\r
99 /*-----------------------------------------------------------*/\r
100 \r
101 void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks )\r
102 {\r
103 short sLEDTask;\r
104 \r
105         if( ucIndex == configLEFT_DISPLAY )\r
106         {\r
107                 /* Suspend or resume the tasks that are toggling the segments of the\r
108                 left side display. */\r
109                 for( sLEDTask = 0; sLEDTask < ledNUM_OF_LED_TASKS; ++sLEDTask )\r
110                 {\r
111                         if( xFlashTaskHandles[ sLEDTask ] != NULL )\r
112                         {\r
113                                 if( sSuspendTasks == pdTRUE )\r
114                                 {\r
115                                         vTaskSuspend( xFlashTaskHandles[ sLEDTask ] );\r
116                                 }\r
117                                 else\r
118                                 {\r
119                                         vTaskResume( xFlashTaskHandles[ sLEDTask ] );\r
120                                 }\r
121                         }\r
122                 }\r
123         }\r
124         else\r
125         {\r
126                 /* Suspend or resume the task in which the co-routines are running.  The\r
127                 co-routines toggle the segments of the right side display. */\r
128                 if( sSuspendTasks == pdTRUE )\r
129                 {\r
130                         vTaskSuspend( xCoroutineTask );\r
131                 }\r
132                 else\r
133                 {\r
134                         vTaskResume( xCoroutineTask );\r
135                 }\r
136         }\r
137 }\r
138 /*-----------------------------------------------------------*/\r
139 \r
140 static void vLEDFlashTask( void * pvParameters )\r
141 {\r
142 TickType_t xFlashRate, xLastFlashTime;\r
143 unsigned short usLED;\r
144 \r
145         /* The LED to flash is passed in as the task parameter. */\r
146         usLED = ( unsigned short ) pvParameters;\r
147 \r
148         /* Calculate the rate at which this task is going to toggle its LED. */\r
149         xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( TickType_t ) usLED );\r
150         xFlashRate /= portTICK_PERIOD_MS;\r
151 \r
152         /* We will turn the LED on and off again in the delay period, so each\r
153         delay is only half the total period. */\r
154         xFlashRate /= ( TickType_t ) 2;\r
155 \r
156         /* We need to initialise xLastFlashTime prior to the first call to\r
157         vTaskDelayUntil(). */\r
158         xLastFlashTime = xTaskGetTickCount();\r
159 \r
160         for(;;)\r
161         {\r
162                 /* Delay for half the flash period then turn the LED on. */\r
163                 vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
164                 vParTestToggleLED( usLED );\r
165 \r
166                 /* Delay for half the flash period then turn the LED off. */\r
167                 vTaskDelayUntil( &xLastFlashTime, xFlashRate );\r
168                 vParTestToggleLED( usLED );\r
169         }\r
170 }\r
171 /*-----------------------------------------------------------*/\r
172 \r
173 static void vLEDCoRoutineControlTask( void *pvParameters )\r
174 {\r
175 unsigned short usCoroutine;\r
176 \r
177         ( void ) pvParameters;\r
178 \r
179         /* Create the co-routines - one of each segment of the right side display. */\r
180         for( usCoroutine = 0; usCoroutine < ledNUM_OF_LED_CO_ROUTINES; usCoroutine++ )\r
181         {\r
182                 xCoRoutineCreate( prvFixedDelayCoRoutine, ledCO_ROUTINE_PRIORITY, usCoroutine );\r
183         }\r
184 \r
185         /* This task has nothing else to do except scheduler the co-routines it just\r
186         created. */\r
187         for( ;; )\r
188         {\r
189                 vCoRoutineSchedule();\r
190         }\r
191 }\r
192 /*-----------------------------------------------------------*/\r
193 \r
194 static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, unsigned short usIndex )\r
195 {\r
196 /* The usIndex parameter of the co-routine function is used as an index into\r
197 the xFlashRates array to obtain the delay period to use. */\r
198 static const TickType_t xFlashRates[ ledNUM_OF_LED_CO_ROUTINES ] = { 150 / portTICK_PERIOD_MS,\r
199                                                                                                                                 300 / portTICK_PERIOD_MS,\r
200                                                                                                                                 450 / portTICK_PERIOD_MS,\r
201                                                                                                                                 600 / portTICK_PERIOD_MS,\r
202                                                                                                                                 750 / portTICK_PERIOD_MS,\r
203                                                                                                                                 900 / portTICK_PERIOD_MS,\r
204                                                                                                                                 1050 / portTICK_PERIOD_MS };\r
205 \r
206         /* Co-routines MUST start with a call to crSTART. */\r
207         crSTART( xHandle );\r
208 \r
209         for( ;; )\r
210         {\r
211                 /* Toggle the LED.  An offset of 8 is used to skip over the segments of\r
212                 the left side display which use the low numbers. */\r
213                 vParTestToggleLED( usIndex + 8 );\r
214 \r
215                 /* Delay until it is time to toggle the segment that this co-routine is\r
216                 controlling again. */\r
217                 crDELAY( xHandle, xFlashRates[ usIndex ] );\r
218         }\r
219 \r
220         /* Co-routines MUST end with a call to crEND. */\r
221         crEND();\r
222 }\r
223 /*-----------------------------------------------------------*/\r
224 \r
225 \r