]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/Tensilica_Simulator_Xplorer_XCC/main_blinky.c
Update version number in readiness for V10.3.0 release. Sync SVN with reviewed releas...
[freertos] / FreeRTOS / Demo / Tensilica_Simulator_Xplorer_XCC / main_blinky.c
1 /*\r
2  * FreeRTOS Kernel V10.3.0\r
3  * Copyright (C) 2020 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.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 /******************************************************************************\r
29  * NOTE:  This file only contains the source code that is specific to the\r
30  * basic demo.  Generic functions, such FreeRTOS hook functions, are defined\r
31  * in main.c.\r
32  ******************************************************************************\r
33  *\r
34  * main_blinky() creates one queue, one software timer, and two tasks. It then\r
35  * starts the scheduler.\r
36  *\r
37  * The Queue Send Task:\r
38  * The queue send task is implemented by the prvQueueSendTask() function in\r
39  * this file.  It uses vTaskDelayUntil() to create a periodic task that sends\r
40  * the value 100 to the queue every 200 milliseconds.\r
41  *\r
42  * The Queue Send Software Timer:\r
43  * The timer is an auto-reload timer with a period of two seconds.  The timer's\r
44  * callback function writes the value 200 to the queue.  The callback function\r
45  * is implemented by prvQueueSendTimerCallback() within this file.\r
46  *\r
47  * The Queue Receive Task:\r
48  * The queue receive task is implemented by the prvQueueReceiveTask() function\r
49  * in this file.  prvQueueReceiveTask() waits for data to arrive on the queue.\r
50  * When data is received, the task checks the value of the data, then outputs a\r
51  * message to indicate if the data came from the queue send task or the queue\r
52  * send software timer.\r
53  *\r
54  * Expected Behavior:\r
55  * - The queue send task writes to the queue every 200ms, so every 200ms the\r
56  *   queue receive task will output a message indicating that data was received\r
57  *   on the queue from the queue send task.\r
58  * - The queue send software timer has a period of two seconds, so every two\r
59  *   seconds the queue receive task will output a message indicating that data\r
60  *   was received on the queue from the queue send software timer.\r
61  */\r
62 \r
63 /* Standard includes. */\r
64 #include <stdio.h>\r
65 \r
66 /* Kernel includes. */\r
67 #include "FreeRTOS.h"\r
68 #include "task.h"\r
69 #include "timers.h"\r
70 #include "semphr.h"\r
71 \r
72 /**\r
73  * Priorities at which the tasks are created.\r
74  */\r
75 #define mainQUEUE_RECEIVE_TASK_PRIORITY         ( tskIDLE_PRIORITY + 2 )\r
76 #define mainQUEUE_SEND_TASK_PRIORITY            ( tskIDLE_PRIORITY + 1 )\r
77 \r
78 /**\r
79  * The rate at which data is sent to the queue.  The times are converted from\r
80  * milliseconds to ticks using the pdMS_TO_TICKS() macro.\r
81  */\r
82 #define mainTASK_SEND_FREQUENCY_MS                      pdMS_TO_TICKS( 200UL )\r
83 #define mainTIMER_SEND_FREQUENCY_MS                     pdMS_TO_TICKS( 2000UL )\r
84 \r
85 /**\r
86  * The number of items the queue can hold at once.\r
87  */\r
88 #define mainQUEUE_LENGTH                                        ( 2 )\r
89 \r
90 /**\r
91  * The values sent to the queue receive task from the queue send task and the\r
92  * queue send software timer respectively.\r
93  */\r
94 #define mainVALUE_SENT_FROM_TASK                        ( 100UL )\r
95 #define mainVALUE_SENT_FROM_TIMER                       ( 200UL )\r
96 /*-----------------------------------------------------------*/\r
97 \r
98 /**\r
99  * The tasks as described in the comments at the top of this file.\r
100  */\r
101 static void prvQueueReceiveTask( void *pvParameters );\r
102 static void prvQueueSendTask( void *pvParameters );\r
103 \r
104 /**\r
105  * The callback function executed when the software timer expires.\r
106  */\r
107 static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle );\r
108 /*-----------------------------------------------------------*/\r
109 \r
110 /**\r
111  * The queue used by both tasks.\r
112  */\r
113 static QueueHandle_t xQueue = NULL;\r
114 \r
115 /**\r
116  * A software timer that is started from the tick hook.\r
117  */\r
118 static TimerHandle_t xTimer = NULL;\r
119 /*-----------------------------------------------------------*/\r
120 \r
121 void main_blinky( void )\r
122 {\r
123 const TickType_t xTimerPeriod = mainTIMER_SEND_FREQUENCY_MS;\r
124 \r
125         /* Create the queue. */\r
126         xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );\r
127 \r
128         if( xQueue != NULL )\r
129         {\r
130                 /* Start the two tasks as described in the comments at the top of this\r
131                  * file. */\r
132                 xTaskCreate( prvQueueReceiveTask,                       /* The function that implements the task. */\r
133                                         "Rx",                                                   /* The text name assigned to the task - for debug only as it is not used by the kernel. */\r
134                                         configMINIMAL_STACK_SIZE,               /* The size of the stack to allocate to the task. */\r
135                                         NULL,                                                   /* The parameter passed to the task - not used in this simple case. */\r
136                                         mainQUEUE_RECEIVE_TASK_PRIORITY,/* The priority assigned to the task. */\r
137                                         NULL );                                                 /* The task handle is not required, so NULL is passed. */\r
138 \r
139                 xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );\r
140 \r
141                 /* Create the software timer, but don't start it yet. */\r
142                 xTimer = xTimerCreate( "Timer",                         /* The text name assigned to the software timer - for debug only as it is not used by the kernel. */\r
143                                                                 xTimerPeriod,           /* The period of the software timer in ticks. */\r
144                                                                 pdTRUE,                         /* xAutoReload is set to pdTRUE. */\r
145                                                                 NULL,                           /* The timer's ID is not used. */\r
146                                                                 prvQueueSendTimerCallback );/* The function executed when the timer expires. */\r
147 \r
148                 if( xTimer != NULL )\r
149                 {\r
150                         xTimerStart( xTimer, 0 );\r
151                 }\r
152 \r
153                 /* Start the tasks and timer running. */\r
154                 vTaskStartScheduler();\r
155         }\r
156 \r
157         /* If all is well, the scheduler will now be running, and the following\r
158          * line will never be reached.  If the following line does execute, then\r
159          * there was insufficient FreeRTOS heap memory available for the idle and/or\r
160          * timer tasks  to be created.  See the memory management section on the\r
161          * FreeRTOS web site for more details. */\r
162         for( ;; );\r
163 }\r
164 /*-----------------------------------------------------------*/\r
165 \r
166 static void prvQueueSendTask( void *pvParameters )\r
167 {\r
168 TickType_t xNextWakeTime;\r
169 const TickType_t xBlockTime = mainTASK_SEND_FREQUENCY_MS;\r
170 const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;\r
171 \r
172         /* Prevent the compiler warning about the unused parameter. */\r
173         ( void ) pvParameters;\r
174 \r
175         /* Initialise xNextWakeTime - this only needs to be done once. */\r
176         xNextWakeTime = xTaskGetTickCount();\r
177 \r
178         for( ;; )\r
179         {\r
180                 /* Place this task in the blocked state until it is time to run again.\r
181                  * The block time is specified in ticks, pdMS_TO_TICKS() was used to\r
182                  * convert a time specified in milliseconds into a time specified in ticks.\r
183                  * While in the Blocked state this task will not consume any CPU time. */\r
184                 vTaskDelayUntil( &xNextWakeTime, xBlockTime );\r
185 \r
186                 /* Send to the queue - causing the queue receive task to unblock and\r
187                  * write to the console.  0 is used as the block time so the send operation\r
188                  * will not block - it shouldn't need to block as the queue should always\r
189                  * have at least one space at this point in the code. */\r
190                 xQueueSend( xQueue, &ulValueToSend, 0U );\r
191         }\r
192 }\r
193 /*-----------------------------------------------------------*/\r
194 \r
195 static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle )\r
196 {\r
197 const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TIMER;\r
198 \r
199         /* This is the software timer callback function.  The software timer has a\r
200          * period of two seconds and is reset each time a key is pressed.  This\r
201          * callback function will execute if the timer expires, which will only happen\r
202          * if a key is not pressed for two seconds. */\r
203 \r
204         /* Avoid compiler warnings resulting from the unused parameter. */\r
205         ( void ) xTimerHandle;\r
206 \r
207         /* Send to the queue - causing the queue receive task to unblock and\r
208          * write out a message.  This function is called from the timer/daemon task,\r
209          * so must not block.  Hence the block time is set to 0. */\r
210         xQueueSend( xQueue, &ulValueToSend, 0U );\r
211 }\r
212 /*-----------------------------------------------------------*/\r
213 \r
214 static void prvQueueReceiveTask( void *pvParameters )\r
215 {\r
216 uint32_t ulReceivedValue;\r
217 \r
218         /* Prevent the compiler warning about the unused parameter. */\r
219         ( void ) pvParameters;\r
220 \r
221         for( ;; )\r
222         {\r
223                 /* Wait until something arrives in the queue - this task will block\r
224                  * indefinitely provided INCLUDE_vTaskSuspend is set to 1 in\r
225                  * FreeRTOSConfig.h.  It will not use any CPU time while it is in the\r
226                  * Blocked state. */\r
227                 xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );\r
228 \r
229                 /* To get here something must have been received from the queue, but\r
230                  * is it an expected value? This is the only task that uses stdout so its\r
231                  * ok to call printf() directly. Do not call printf from any other task. */\r
232                 if( ulReceivedValue == mainVALUE_SENT_FROM_TASK )\r
233                 {\r
234                         printf( "Message received from task\r\n" );\r
235                 }\r
236                 else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER )\r
237                 {\r
238                         printf( "Message received from software timer\r\n" );\r
239                 }\r
240                 else\r
241                 {\r
242                         printf( "Unexpected message\r\n" );\r
243                 }\r
244 \r
245                 fflush( stdout );\r
246         }\r
247 }\r
248 /*-----------------------------------------------------------*/\r