2 * FreeRTOS Kernel V10.0.0
\r
3 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\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
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
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
23 * http://www.FreeRTOS.org
\r
24 * http://aws.amazon.com/freertos
\r
26 * 1 tab == 4 spaces!
\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
37 /* Scheduler include files. */
\r
38 #include "FreeRTOS.h"
\r
40 #include "croutine.h"
\r
42 /* Demo program include files. */
\r
43 #include "partest.h"
\r
45 /*-----------------------------------------------------------*/
\r
47 /* One task per segment of the left side display. */
\r
48 #define ledNUM_OF_LED_TASKS ( 7 )
\r
50 /* Each task toggles at a frequency that is a multiple of 333ms. */
\r
51 #define ledFLASH_RATE_BASE ( ( TickType_t ) 333 )
\r
53 /* One co-routine per segment of the right hand display. */
\r
54 #define ledNUM_OF_LED_CO_ROUTINES 7
\r
56 /* All co-routines run at the same priority. */
\r
57 #define ledCO_ROUTINE_PRIORITY 0
\r
59 /*-----------------------------------------------------------*/
\r
61 /* The task that is created 7 times. */
\r
62 static void vLEDFlashTask( void *pvParameters );
\r
64 /* The co-routine that is created 7 times. */
\r
65 static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, unsigned short usIndex );
\r
67 /* This task is created once, but itself creates 7 co-routines. */
\r
68 static void vLEDCoRoutineControlTask( void *pvParameters );
\r
70 /* Handles to each of the 7 tasks. Used so the tasks can be suspended
\r
72 static TaskHandle_t xFlashTaskHandles[ ledNUM_OF_LED_TASKS ] = { 0 };
\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
78 /*-----------------------------------------------------------*/
\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
84 void vCreateFlashTasksAndCoRoutines( void )
\r
86 signed short sLEDTask;
\r
88 /* Create the tasks that flash segments on the first LED. */
\r
89 for( sLEDTask = 0; sLEDTask < ledNUM_OF_LED_TASKS; ++sLEDTask )
\r
91 /* Spawn the task. */
\r
92 xTaskCreate( vLEDFlashTask, "LEDt", configMINIMAL_STACK_SIZE, ( void * ) sLEDTask, ( tskIDLE_PRIORITY + 1 ), &( xFlashTaskHandles[ sLEDTask ] ) );
\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
99 /*-----------------------------------------------------------*/
\r
101 void vSuspendFlashTasks( unsigned char ucIndex, short sSuspendTasks )
\r
105 if( ucIndex == configLEFT_DISPLAY )
\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
111 if( xFlashTaskHandles[ sLEDTask ] != NULL )
\r
113 if( sSuspendTasks == pdTRUE )
\r
115 vTaskSuspend( xFlashTaskHandles[ sLEDTask ] );
\r
119 vTaskResume( xFlashTaskHandles[ sLEDTask ] );
\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
130 vTaskSuspend( xCoroutineTask );
\r
134 vTaskResume( xCoroutineTask );
\r
138 /*-----------------------------------------------------------*/
\r
140 static void vLEDFlashTask( void * pvParameters )
\r
142 TickType_t xFlashRate, xLastFlashTime;
\r
143 unsigned short usLED;
\r
145 /* The LED to flash is passed in as the task parameter. */
\r
146 usLED = ( unsigned short ) pvParameters;
\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
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
156 /* We need to initialise xLastFlashTime prior to the first call to
\r
157 vTaskDelayUntil(). */
\r
158 xLastFlashTime = xTaskGetTickCount();
\r
162 /* Delay for half the flash period then turn the LED on. */
\r
163 vTaskDelayUntil( &xLastFlashTime, xFlashRate );
\r
164 vParTestToggleLED( usLED );
\r
166 /* Delay for half the flash period then turn the LED off. */
\r
167 vTaskDelayUntil( &xLastFlashTime, xFlashRate );
\r
168 vParTestToggleLED( usLED );
\r
171 /*-----------------------------------------------------------*/
\r
173 static void vLEDCoRoutineControlTask( void *pvParameters )
\r
175 unsigned short usCoroutine;
\r
177 ( void ) pvParameters;
\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
182 xCoRoutineCreate( prvFixedDelayCoRoutine, ledCO_ROUTINE_PRIORITY, usCoroutine );
\r
185 /* This task has nothing else to do except scheduler the co-routines it just
\r
189 vCoRoutineSchedule();
\r
192 /*-----------------------------------------------------------*/
\r
194 static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, unsigned short usIndex )
\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
206 /* Co-routines MUST start with a call to crSTART. */
\r
207 crSTART( xHandle );
\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
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
220 /* Co-routines MUST end with a call to crEND. */
\r
223 /*-----------------------------------------------------------*/
\r