]> begriffs open source - cmsis-freertos/blob - Demo/MB96350_Softune_Dice_Kit/SegmentToggleTasks.c
Initial commit
[cmsis-freertos] / Demo / MB96350_Softune_Dice_Kit / SegmentToggleTasks.c
1 /*
2     FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
3     All rights reserved
4
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
6
7     This file is part of the FreeRTOS distribution.
8
9     FreeRTOS is free software; you can redistribute it and/or modify it under
10     the terms of the GNU General Public License (version 2) as published by the
11     Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
12
13     ***************************************************************************
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<
16     >>!   obliged to provide the source code for proprietary components     !<<
17     >>!   outside of the FreeRTOS kernel.                                   !<<
18     ***************************************************************************
19
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following
23     link: http://www.freertos.org/a00114.html
24
25     ***************************************************************************
26      *                                                                       *
27      *    FreeRTOS provides completely free yet professionally developed,    *
28      *    robust, strictly quality controlled, supported, and cross          *
29      *    platform software that is more than just the market leader, it     *
30      *    is the industry's de facto standard.                               *
31      *                                                                       *
32      *    Help yourself get started quickly while simultaneously helping     *
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *
34      *    tutorial book, reference manual, or both:                          *
35      *    http://www.FreeRTOS.org/Documentation                              *
36      *                                                                       *
37     ***************************************************************************
38
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
40     the FAQ page "My application does not run, what could be wrong?".  Have you
41     defined configASSERT()?
42
43     http://www.FreeRTOS.org/support - In return for receiving this top quality
44     embedded software for free we request you assist our global community by
45     participating in the support forum.
46
47     http://www.FreeRTOS.org/training - Investing in training allows your team to
48     be as productive as possible as early as possible.  Now you can receive
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
50     Ltd, and the world's leading authority on the world's leading RTOS.
51
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.
55
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
58
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
61     licenses offer ticketed support, indemnification and commercial middleware.
62
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety
64     engineered and independently SIL3 certified version for use in safety and
65     mission critical applications that require provable dependability.
66
67     1 tab == 4 spaces!
68 */
69
70 /**
71  * Defines the tasks and co-routines used to toggle the segments of the two
72  * seven segment displays, as described at the top of main.c
73  */
74
75
76 #include <stdlib.h>
77
78 /* Scheduler include files. */
79 #include "FreeRTOS.h"
80 #include "task.h"
81 #include "croutine.h"
82
83 /* Demo program include files. */
84 #include "partest.h"
85
86 /*-----------------------------------------------------------*/
87
88 /* One task per segment of the left side display. */
89 #define ledNUM_OF_LED_TASKS     ( 7 )
90
91 /* Each task toggles at a frequency that is a multiple of 333ms. */
92 #define ledFLASH_RATE_BASE      ( ( TickType_t ) 333 )
93
94 /* One co-routine per segment of the right hand display. */
95 #define ledNUM_OF_LED_CO_ROUTINES       7
96
97 /* All co-routines run at the same priority. */
98 #define ledCO_ROUTINE_PRIORITY          0
99
100 /*-----------------------------------------------------------*/
101
102 /* The task that is created 7 times. */
103 static void vLEDFlashTask( void *pvParameters );
104
105 /* The co-routine that is created 7 times. */
106 static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, unsigned short usIndex );
107
108 /* This task is created once, but itself creates 7 co-routines. */
109 static void vLEDCoRoutineControlTask( void *pvParameters );
110
111 /* Handles to each of the 7 tasks.  Used so the tasks can be suspended
112 and resumed. */
113 static TaskHandle_t xFlashTaskHandles[ ledNUM_OF_LED_TASKS ] = { 0 };
114
115 /* Handle to the task in which the co-routines run.  Used so the
116 co-routines can be suspended and resumed. */
117 static TaskHandle_t xCoroutineTask;
118
119 /*-----------------------------------------------------------*/
120
121 /**
122  * Creates the tasks and co-routines used to toggle the segments of the two
123  * seven segment displays, as described at the top of main.c
124  */
125 void vCreateFlashTasksAndCoRoutines( void )
126 {
127 signed short sLEDTask;
128
129         /* Create the tasks that flash segments on the first LED. */
130         for( sLEDTask = 0; sLEDTask < ledNUM_OF_LED_TASKS; ++sLEDTask )
131         {
132                 /* Spawn the task. */
133                 xTaskCreate( vLEDFlashTask, "LEDt", configMINIMAL_STACK_SIZE, ( void * ) sLEDTask, ( tskIDLE_PRIORITY + 1 ), &( xFlashTaskHandles[ sLEDTask ] ) );
134         }
135
136         /* Create the task in which the co-routines run.  The co-routines themselves
137         are created within the task. */
138         xTaskCreate( vLEDCoRoutineControlTask, "LEDc", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, &xCoroutineTask );
139 }
140 /*-----------------------------------------------------------*/
141
142 void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks )
143 {
144 short sLEDTask;
145
146         if( ucIndex == configLEFT_DISPLAY )
147         {
148                 /* Suspend or resume the tasks that are toggling the segments of the
149                 left side display. */
150                 for( sLEDTask = 0; sLEDTask < ledNUM_OF_LED_TASKS; ++sLEDTask )
151                 {
152                         if( xFlashTaskHandles[ sLEDTask ] != NULL )
153                         {
154                                 if( sSuspendTasks == pdTRUE )
155                                 {
156                                         vTaskSuspend( xFlashTaskHandles[ sLEDTask ] );
157                                 }
158                                 else
159                                 {
160                                         vTaskResume( xFlashTaskHandles[ sLEDTask ] );
161                                 }
162                         }
163                 }
164         }
165         else
166         {
167                 /* Suspend or resume the task in which the co-routines are running.  The
168                 co-routines toggle the segments of the right side display. */
169                 if( sSuspendTasks == pdTRUE )
170                 {
171                         vTaskSuspend( xCoroutineTask );
172                 }
173                 else
174                 {
175                         vTaskResume( xCoroutineTask );
176                 }
177         }
178 }
179 /*-----------------------------------------------------------*/
180
181 static void vLEDFlashTask( void * pvParameters )
182 {
183 TickType_t xFlashRate, xLastFlashTime;
184 unsigned short usLED;
185
186         /* The LED to flash is passed in as the task parameter. */
187         usLED = ( unsigned short ) pvParameters;
188
189         /* Calculate the rate at which this task is going to toggle its LED. */
190         xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( TickType_t ) usLED );
191         xFlashRate /= portTICK_PERIOD_MS;
192
193         /* We will turn the LED on and off again in the delay period, so each
194         delay is only half the total period. */
195         xFlashRate /= ( TickType_t ) 2;
196
197         /* We need to initialise xLastFlashTime prior to the first call to
198         vTaskDelayUntil(). */
199         xLastFlashTime = xTaskGetTickCount();
200
201         for(;;)
202         {
203                 /* Delay for half the flash period then turn the LED on. */
204                 vTaskDelayUntil( &xLastFlashTime, xFlashRate );
205                 vParTestToggleLED( usLED );
206
207                 /* Delay for half the flash period then turn the LED off. */
208                 vTaskDelayUntil( &xLastFlashTime, xFlashRate );
209                 vParTestToggleLED( usLED );
210         }
211 }
212 /*-----------------------------------------------------------*/
213
214 static void vLEDCoRoutineControlTask( void *pvParameters )
215 {
216 unsigned short usCoroutine;
217
218         ( void ) pvParameters;
219
220         /* Create the co-routines - one of each segment of the right side display. */
221         for( usCoroutine = 0; usCoroutine < ledNUM_OF_LED_CO_ROUTINES; usCoroutine++ )
222         {
223                 xCoRoutineCreate( prvFixedDelayCoRoutine, ledCO_ROUTINE_PRIORITY, usCoroutine );
224         }
225
226         /* This task has nothing else to do except scheduler the co-routines it just
227         created. */
228         for( ;; )
229         {
230                 vCoRoutineSchedule();
231         }
232 }
233 /*-----------------------------------------------------------*/
234
235 static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, unsigned short usIndex )
236 {
237 /* The usIndex parameter of the co-routine function is used as an index into
238 the xFlashRates array to obtain the delay period to use. */
239 static const TickType_t xFlashRates[ ledNUM_OF_LED_CO_ROUTINES ] = { 150 / portTICK_PERIOD_MS,
240                                                                                                                                 300 / portTICK_PERIOD_MS,
241                                                                                                                                 450 / portTICK_PERIOD_MS,
242                                                                                                                                 600 / portTICK_PERIOD_MS,
243                                                                                                                                 750 / portTICK_PERIOD_MS,
244                                                                                                                                 900 / portTICK_PERIOD_MS,
245                                                                                                                                 1050 / portTICK_PERIOD_MS };
246
247         /* Co-routines MUST start with a call to crSTART. */
248         crSTART( xHandle );
249
250         for( ;; )
251         {
252                 /* Toggle the LED.  An offset of 8 is used to skip over the segments of
253                 the left side display which use the low numbers. */
254                 vParTestToggleLED( usIndex + 8 );
255
256                 /* Delay until it is time to toggle the segment that this co-routine is
257                 controlling again. */
258                 crDELAY( xHandle, xFlashRates[ usIndex ] );
259         }
260
261         /* Co-routines MUST end with a call to crEND. */
262         crEND();
263 }
264 /*-----------------------------------------------------------*/
265
266