]> git.sur5r.net Git - freertos/blob - Demo/Common/Minimal/AltPollQ.c
Update to V5.0.0.
[freertos] / Demo / Common / Minimal / AltPollQ.c
1 /*\r
2         FreeRTOS.org V5.0.0 - Copyright (C) 2003-2008 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS.org is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS.org; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS.org, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section\r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26     ***************************************************************************\r
27     ***************************************************************************\r
28     *                                                                         *\r
29     * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *\r
30     * and even write all or part of your application on your behalf.          *\r
31     * See http://www.OpenRTOS.com for details of the services we provide to   *\r
32     * expedite your project.                                                  *\r
33     *                                                                         *\r
34     ***************************************************************************\r
35     ***************************************************************************\r
36 \r
37         Please ensure to read the configuration and relevant port sections of the\r
38         online documentation.\r
39 \r
40         http://www.FreeRTOS.org - Documentation, latest information, license and \r
41         contact details.\r
42 \r
43         http://www.SafeRTOS.com - A version that is certified for use in safety \r
44         critical systems.\r
45 \r
46         http://www.OpenRTOS.com - Commercial support, development, porting, \r
47         licensing and training services.\r
48 */\r
49 \r
50 /*\r
51  * This is a version of PollQ.c that uses the alternative (Alt) API.\r
52  * \r
53  * Creates two tasks that communicate over a single queue.  One task acts as a\r
54  * producer, the other a consumer.\r
55  *\r
56  * The producer loops for three iteration, posting an incrementing number onto the\r
57  * queue each cycle.  It then delays for a fixed period before doing exactly the\r
58  * same again.\r
59  *\r
60  * The consumer loops emptying the queue.  Each item removed from the queue is\r
61  * checked to ensure it contains the expected value.  When the queue is empty it\r
62  * blocks for a fixed period, then does the same again.\r
63  *\r
64  * All queue access is performed without blocking.  The consumer completely empties\r
65  * the queue each time it runs so the producer should never find the queue full.\r
66  *\r
67  * An error is flagged if the consumer obtains an unexpected value or the producer\r
68  * find the queue is full.\r
69  */\r
70 \r
71 /*\r
72 Changes from V2.0.0\r
73 \r
74         + Delay periods are now specified using variables and constants of\r
75           portTickType rather than unsigned portLONG.\r
76 */\r
77 \r
78 #include <stdlib.h>\r
79 \r
80 /* Scheduler include files. */\r
81 #include "FreeRTOS.h"\r
82 #include "task.h"\r
83 #include "queue.h"\r
84 \r
85 /* Demo program include files. */\r
86 #include "AltPollQ.h"\r
87 \r
88 #define pollqSTACK_SIZE                 configMINIMAL_STACK_SIZE\r
89 #define pollqQUEUE_SIZE                 ( 10 )\r
90 #define pollqPRODUCER_DELAY             ( ( portTickType ) 200 / portTICK_RATE_MS )\r
91 #define pollqCONSUMER_DELAY             ( pollqPRODUCER_DELAY - ( portTickType ) ( 20 / portTICK_RATE_MS ) )\r
92 #define pollqNO_DELAY                   ( ( portTickType ) 0 )\r
93 #define pollqVALUES_TO_PRODUCE  ( ( signed portBASE_TYPE ) 3 )\r
94 #define pollqINITIAL_VALUE              ( ( signed portBASE_TYPE ) 0 )\r
95 \r
96 /* The task that posts the incrementing number onto the queue. */\r
97 static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters );\r
98 \r
99 /* The task that empties the queue. */\r
100 static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters );\r
101 \r
102 /* Variables that are used to check that the tasks are still running with no\r
103 errors. */\r
104 static volatile signed portBASE_TYPE xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE;\r
105 \r
106 /*-----------------------------------------------------------*/\r
107 \r
108 void vStartAltPolledQueueTasks( unsigned portBASE_TYPE uxPriority )\r
109 {\r
110 static xQueueHandle xPolledQueue;\r
111 \r
112         /* Create the queue used by the producer and consumer. */\r
113         xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) );\r
114 \r
115         /* Spawn the producer and consumer. */\r
116         xTaskCreate( vPolledQueueConsumer, ( signed portCHAR * ) "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );\r
117         xTaskCreate( vPolledQueueProducer, ( signed portCHAR * ) "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( xTaskHandle * ) NULL );\r
118 }\r
119 /*-----------------------------------------------------------*/\r
120 \r
121 static portTASK_FUNCTION( vPolledQueueProducer, pvParameters )\r
122 {\r
123 unsigned portSHORT usValue = ( unsigned portSHORT ) 0;\r
124 signed portBASE_TYPE xError = pdFALSE, xLoop;\r
125 \r
126         #ifdef USE_STDIO\r
127         void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
128         \r
129                 const portCHAR * const pcTaskStartMsg = "Alt polling queue producer task started.\r\n";\r
130 \r
131                 /* Queue a message for printing to say the task has started. */\r
132                 vPrintDisplayMessage( &pcTaskStartMsg );\r
133         #endif\r
134 \r
135         for( ;; )\r
136         {               \r
137                 for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ )\r
138                 {\r
139                         /* Send an incrementing number on the queue without blocking. */\r
140                         if( xQueueAltSendToBack( *( ( xQueueHandle * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS )\r
141                         {\r
142                                 /* We should never find the queue full so if we get here there\r
143                                 has been an error. */\r
144                                 xError = pdTRUE;\r
145                         }\r
146                         else\r
147                         {\r
148                                 if( xError == pdFALSE )\r
149                                 {\r
150                                         /* If an error has ever been recorded we stop incrementing the\r
151                                         check variable. */\r
152                                         portENTER_CRITICAL();\r
153                                                 xPollingProducerCount++;\r
154                                         portEXIT_CRITICAL();\r
155                                 }\r
156 \r
157                                 /* Update the value we are going to post next time around. */\r
158                                 usValue++;\r
159                         }\r
160                 }\r
161 \r
162                 /* Wait before we start posting again to ensure the consumer runs and\r
163                 empties the queue. */\r
164                 vTaskDelay( pollqPRODUCER_DELAY );\r
165         }\r
166 }  /*lint !e818 Function prototype must conform to API. */\r
167 /*-----------------------------------------------------------*/\r
168 \r
169 static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters )\r
170 {\r
171 unsigned portSHORT usData, usExpectedValue = ( unsigned portSHORT ) 0;\r
172 signed portBASE_TYPE xError = pdFALSE;\r
173 \r
174         #ifdef USE_STDIO\r
175         void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );\r
176         \r
177                 const portCHAR * const pcTaskStartMsg = "Alt blocking queue consumer task started.\r\n";\r
178 \r
179                 /* Queue a message for printing to say the task has started. */\r
180                 vPrintDisplayMessage( &pcTaskStartMsg );\r
181         #endif\r
182 \r
183         for( ;; )\r
184         {               \r
185                 /* Loop until the queue is empty. */\r
186                 while( uxQueueMessagesWaiting( *( ( xQueueHandle * ) pvParameters ) ) )\r
187                 {\r
188                         if( xQueueAltReceive( *( ( xQueueHandle * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS )\r
189                         {\r
190                                 if( usData != usExpectedValue )\r
191                                 {\r
192                                         /* This is not what we expected to receive so an error has\r
193                                         occurred. */\r
194                                         xError = pdTRUE;\r
195 \r
196                                         /* Catch-up to the value we received so our next expected\r
197                                         value should again be correct. */\r
198                                         usExpectedValue = usData;\r
199                                 }\r
200                                 else\r
201                                 {\r
202                                         if( xError == pdFALSE )\r
203                                         {\r
204                                                 /* Only increment the check variable if no errors have\r
205                                                 occurred. */\r
206                                                 portENTER_CRITICAL();\r
207                                                         xPollingConsumerCount++;\r
208                                                 portEXIT_CRITICAL();\r
209                                         }\r
210                                 }\r
211 \r
212                                 /* Next time round we would expect the number to be one higher. */\r
213                                 usExpectedValue++;\r
214                         }\r
215                 }\r
216 \r
217                 /* Now the queue is empty we block, allowing the producer to place more\r
218                 items in the queue. */\r
219                 vTaskDelay( pollqCONSUMER_DELAY );\r
220         }\r
221 } /*lint !e818 Function prototype must conform to API. */\r
222 /*-----------------------------------------------------------*/\r
223 \r
224 /* This is called to check that all the created tasks are still running with no errors. */\r
225 portBASE_TYPE xAreAltPollingQueuesStillRunning( void )\r
226 {\r
227 portBASE_TYPE xReturn;\r
228 \r
229         /* Check both the consumer and producer poll count to check they have both\r
230         been changed since out last trip round.  We do not need a critical section\r
231         around the check variables as this is called from a higher priority than\r
232         the other tasks that access the same variables. */\r
233         if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) ||\r
234                 ( xPollingProducerCount == pollqINITIAL_VALUE )\r
235           )\r
236         {\r
237                 xReturn = pdFALSE;\r
238         }\r
239         else\r
240         {\r
241                 xReturn = pdTRUE;\r
242         }\r
243 \r
244         /* Set the check variables back down so we know if they have been\r
245         incremented the next time around. */\r
246         xPollingConsumerCount = pollqINITIAL_VALUE;\r
247         xPollingProducerCount = pollqINITIAL_VALUE;\r
248 \r
249         return xReturn;\r
250 }\r