OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [Minimal/] [AltPollQ.c] - Blame information for rev 609

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.