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

Subversion Repositories openrisc

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

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
/*
56
 * Tests the behaviour when data is peeked from a queue when there are
57
 * multiple tasks blocked on the queue.
58
 */
59
 
60
 
61
#include <stdlib.h>
62
 
63
/* Scheduler include files. */
64
#include "FreeRTOS.h"
65
#include "task.h"
66
#include "queue.h"
67
#include "semphr.h"
68
 
69
/* Demo program include files. */
70
#include "QPeek.h"
71
 
72
#define qpeekQUEUE_LENGTH               ( 5 )
73
#define qpeekNO_BLOCK                   ( 0 )
74
#define qpeekSHORT_DELAY                ( 10 )
75
 
76
#define qpeekLOW_PRIORITY                       ( tskIDLE_PRIORITY + 0 )
77
#define qpeekMEDIUM_PRIORITY            ( tskIDLE_PRIORITY + 1 )
78
#define qpeekHIGH_PRIORITY                      ( tskIDLE_PRIORITY + 2 )
79
#define qpeekHIGHEST_PRIORITY           ( tskIDLE_PRIORITY + 3 )
80
 
81
/*-----------------------------------------------------------*/
82
 
83
/*
84
 * The following three tasks are used to demonstrate the peeking behaviour.
85
 * Each task is given a different priority to demonstrate the order in which
86
 * tasks are woken as data is peeked from a queue.
87
 */
88
static void prvLowPriorityPeekTask( void *pvParameters );
89
static void prvMediumPriorityPeekTask( void *pvParameters );
90
static void prvHighPriorityPeekTask( void *pvParameters );
91
static void prvHighestPriorityPeekTask( void *pvParameters );
92
 
93
/*-----------------------------------------------------------*/
94
 
95
/* Flag that will be latched to pdTRUE should any unexpected behaviour be
96
detected in any of the tasks. */
97
static volatile portBASE_TYPE xErrorDetected = pdFALSE;
98
 
99
/* Counter that is incremented on each cycle of a test.  This is used to
100
detect a stalled task - a test that is no longer running. */
101
static volatile unsigned portLONG ulLoopCounter = 0;
102
 
103
/* Handles to the test tasks. */
104
xTaskHandle xMediumPriorityTask, xHighPriorityTask, xHighestPriorityTask;
105
/*-----------------------------------------------------------*/
106
 
107
void vStartQueuePeekTasks( void )
108
{
109
xQueueHandle xQueue;
110
 
111
        /* Create the queue that we are going to use for the test/demo. */
112
        xQueue = xQueueCreate( qpeekQUEUE_LENGTH, sizeof( unsigned portLONG ) );
113
 
114
        /* vQueueAddToRegistry() adds the queue to the queue registry, if one is
115
        in use.  The queue registry is provided as a means for kernel aware
116
        debuggers to locate queues and has no purpose if a kernel aware debugger
117
        is not being used.  The call to vQueueAddToRegistry() will be removed
118
        by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is
119
        defined to be less than 1. */
120
        vQueueAddToRegistry( xQueue, ( signed portCHAR * ) "QPeek_Test_Queue" );
121
 
122
        /* Create the demo tasks and pass it the queue just created.  We are
123
        passing the queue handle by value so it does not matter that it is declared
124
        on the stack here. */
125
        xTaskCreate( prvLowPriorityPeekTask, ( signed portCHAR * )"PeekL", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekLOW_PRIORITY, NULL );
126
        xTaskCreate( prvMediumPriorityPeekTask, ( signed portCHAR * )"PeekM", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask );
127
        xTaskCreate( prvHighPriorityPeekTask, ( signed portCHAR * )"PeekH1", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask );
128
        xTaskCreate( prvHighestPriorityPeekTask, ( signed portCHAR * )"PeekH2", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask );
129
}
130
/*-----------------------------------------------------------*/
131
 
132
static void prvHighestPriorityPeekTask( void *pvParameters )
133
{
134
xQueueHandle xQueue = ( xQueueHandle ) pvParameters;
135
unsigned portLONG ulValue;
136
 
137
        #ifdef USE_STDIO
138
        {
139
                void vPrintDisplayMessage( const portCHAR * const * ppcMessageToSend );
140
 
141
                const portCHAR * const pcTaskStartMsg = "Queue peek test started.\r\n";
142
 
143
                /* Queue a message for printing to say the task has started. */
144
                vPrintDisplayMessage( &pcTaskStartMsg );
145
        }
146
        #endif
147
 
148
        for( ;; )
149
        {
150
                /* Try peeking from the queue.  The queue should be empty so we will
151
                block, allowing the high priority task to execute. */
152
                if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
153
                {
154
                        /* We expected to have received something by the time we unblock. */
155
                        xErrorDetected = pdTRUE;
156
                }
157
 
158
                /* When we reach here the high and medium priority tasks should still
159
                be blocked on the queue.  We unblocked because the low priority task
160
                wrote a value to the queue, which we should have peeked.  Peeking the
161
                data (rather than receiving it) will leave the data on the queue, so
162
                the high priority task should then have also been unblocked, but not
163
                yet executed. */
164
                if( ulValue != 0x11223344 )
165
                {
166
                        /* We did not receive the expected value. */
167
                        xErrorDetected = pdTRUE;
168
                }
169
 
170
                if( uxQueueMessagesWaiting( xQueue ) != 1 )
171
                {
172
                        /* The message should have been left on the queue. */
173
                        xErrorDetected = pdTRUE;
174
                }
175
 
176
                /* Now we are going to actually receive the data, so when the high
177
                priority task runs it will find the queue empty and return to the
178
                blocked state. */
179
                ulValue = 0;
180
                if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
181
                {
182
                        /* We expected to receive the value. */
183
                        xErrorDetected = pdTRUE;
184
                }
185
 
186
                if( ulValue != 0x11223344 )
187
                {
188
                        /* We did not receive the expected value - which should have been
189
                        the same value as was peeked. */
190
                        xErrorDetected = pdTRUE;
191
                }
192
 
193
                /* Now we will block again as the queue is once more empty.  The low
194
                priority task can then execute again. */
195
                if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
196
                {
197
                        /* We expected to have received something by the time we unblock. */
198
                        xErrorDetected = pdTRUE;
199
                }
200
 
201
                /* When we get here the low priority task should have again written to the
202
                queue. */
203
                if( ulValue != 0x01234567 )
204
                {
205
                        /* We did not receive the expected value. */
206
                        xErrorDetected = pdTRUE;
207
                }
208
 
209
                if( uxQueueMessagesWaiting( xQueue ) != 1 )
210
                {
211
                        /* The message should have been left on the queue. */
212
                        xErrorDetected = pdTRUE;
213
                }
214
 
215
                /* We only peeked the data, so suspending ourselves now should enable
216
                the high priority task to also peek the data.  The high priority task
217
                will have been unblocked when we peeked the data as we left the data
218
                in the queue. */
219
                vTaskSuspend( NULL );
220
 
221
 
222
 
223
                /* This time we are going to do the same as the above test, but the
224
                high priority task is going to receive the data, rather than peek it.
225
                This means that the medium priority task should never peek the value. */
226
                if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
227
                {
228
                        xErrorDetected = pdTRUE;
229
                }
230
 
231
                if( ulValue != 0xaabbaabb )
232
                {
233
                        xErrorDetected = pdTRUE;
234
                }
235
 
236
                vTaskSuspend( NULL );
237
        }
238
}
239
/*-----------------------------------------------------------*/
240
 
241
static void prvHighPriorityPeekTask( void *pvParameters )
242
{
243
xQueueHandle xQueue = ( xQueueHandle ) pvParameters;
244
unsigned portLONG ulValue;
245
 
246
        for( ;; )
247
        {
248
                /* Try peeking from the queue.  The queue should be empty so we will
249
                block, allowing the medium priority task to execute.  Both the high
250
                and highest priority tasks will then be blocked on the queue. */
251
                if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
252
                {
253
                        /* We expected to have received something by the time we unblock. */
254
                        xErrorDetected = pdTRUE;
255
                }
256
 
257
                /* When we get here the highest priority task should have peeked the data
258
                (unblocking this task) then suspended (allowing this task to also peek
259
                the data). */
260
                if( ulValue != 0x01234567 )
261
                {
262
                        /* We did not receive the expected value. */
263
                        xErrorDetected = pdTRUE;
264
                }
265
 
266
                if( uxQueueMessagesWaiting( xQueue ) != 1 )
267
                {
268
                        /* The message should have been left on the queue. */
269
                        xErrorDetected = pdTRUE;
270
                }
271
 
272
                /* We only peeked the data, so suspending ourselves now should enable
273
                the medium priority task to also peek the data.  The medium priority task
274
                will have been unblocked when we peeked the data as we left the data
275
                in the queue. */
276
                vTaskSuspend( NULL );
277
 
278
 
279
                /* This time we are going actually receive the value, so the medium
280
                priority task will never peek the data - we removed it from the queue. */
281
                if( xQueueReceive( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
282
                {
283
                        xErrorDetected = pdTRUE;
284
                }
285
 
286
                if( ulValue != 0xaabbaabb )
287
                {
288
                        xErrorDetected = pdTRUE;
289
                }
290
 
291
                vTaskSuspend( NULL );
292
        }
293
}
294
/*-----------------------------------------------------------*/
295
 
296
static void prvMediumPriorityPeekTask( void *pvParameters )
297
{
298
xQueueHandle xQueue = ( xQueueHandle ) pvParameters;
299
unsigned portLONG ulValue;
300
 
301
        for( ;; )
302
        {
303
                /* Try peeking from the queue.  The queue should be empty so we will
304
                block, allowing the low priority task to execute.  The highest, high
305
                and medium priority tasks will then all be blocked on the queue. */
306
                if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS )
307
                {
308
                        /* We expected to have received something by the time we unblock. */
309
                        xErrorDetected = pdTRUE;
310
                }
311
 
312
                /* When we get here the high priority task should have peeked the data
313
                (unblocking this task) then suspended (allowing this task to also peek
314
                the data). */
315
                if( ulValue != 0x01234567 )
316
                {
317
                        /* We did not receive the expected value. */
318
                        xErrorDetected = pdTRUE;
319
                }
320
 
321
                if( uxQueueMessagesWaiting( xQueue ) != 1 )
322
                {
323
                        /* The message should have been left on the queue. */
324
                        xErrorDetected = pdTRUE;
325
                }
326
 
327
                /* Just so we know the test is still running. */
328
                ulLoopCounter++;
329
 
330
                /* Now we can suspend ourselves so the low priority task can execute
331
                again. */
332
                vTaskSuspend( NULL );
333
        }
334
}
335
/*-----------------------------------------------------------*/
336
 
337
static void prvLowPriorityPeekTask( void *pvParameters )
338
{
339
xQueueHandle xQueue = ( xQueueHandle ) pvParameters;
340
unsigned portLONG ulValue;
341
 
342
        for( ;; )
343
        {
344
                /* Write some data to the queue.  This should unblock the highest
345
                priority task that is waiting to peek data from the queue. */
346
                ulValue = 0x11223344;
347
                if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
348
                {
349
                        /* We were expecting the queue to be empty so we should not of
350
                        had a problem writing to the queue. */
351
                        xErrorDetected = pdTRUE;
352
                }
353
 
354
                /* By the time we get here the data should have been removed from
355
                the queue. */
356
                if( uxQueueMessagesWaiting( xQueue ) != 0 )
357
                {
358
                        xErrorDetected = pdTRUE;
359
                }
360
 
361
                /* Write another value to the queue, again waking the highest priority
362
                task that is blocked on the queue. */
363
                ulValue = 0x01234567;
364
                if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
365
                {
366
                        /* We were expecting the queue to be empty so we should not of
367
                        had a problem writing to the queue. */
368
                        xErrorDetected = pdTRUE;
369
                }
370
 
371
                /* All the other tasks should now have successfully peeked the data.
372
                The data is still in the queue so we should be able to receive it. */
373
                ulValue = 0;
374
                if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
375
                {
376
                        /* We expected to receive the data. */
377
                        xErrorDetected = pdTRUE;
378
                }
379
 
380
                if( ulValue != 0x01234567 )
381
                {
382
                        /* We did not receive the expected value. */
383
                }
384
 
385
                /* Lets just delay a while as this is an intensive test as we don't
386
                want to starve other tests of processing time. */
387
                vTaskDelay( qpeekSHORT_DELAY );
388
 
389
                /* Unsuspend the other tasks so we can repeat the test - this time
390
                however not all the other tasks will peek the data as the high
391
                priority task is actually going to remove it from the queue.  Send
392
                to front is used just to be different.  As the queue is empty it
393
                makes no difference to the result. */
394
                vTaskResume( xMediumPriorityTask );
395
                vTaskResume( xHighPriorityTask );
396
                vTaskResume( xHighestPriorityTask );
397
 
398
                ulValue = 0xaabbaabb;
399
                if( xQueueSendToFront( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS )
400
                {
401
                        /* We were expecting the queue to be empty so we should not of
402
                        had a problem writing to the queue. */
403
                        xErrorDetected = pdTRUE;
404
                }
405
 
406
                /* This time we should find that the queue is empty.  The high priority
407
                task actually removed the data rather than just peeking it. */
408
                if( xQueuePeek( xQueue, &ulValue, qpeekNO_BLOCK ) != errQUEUE_EMPTY )
409
                {
410
                        /* We expected to receive the data. */
411
                        xErrorDetected = pdTRUE;
412
                }
413
 
414
                /* Unsuspend the highest and high priority tasks so we can go back
415
                and repeat the whole thing.  The medium priority task should not be
416
                suspended as it was not able to peek the data in this last case. */
417
                vTaskResume( xHighPriorityTask );
418
                vTaskResume( xHighestPriorityTask );
419
 
420
                /* Lets just delay a while as this is an intensive test as we don't
421
                want to starve other tests of processing time. */
422
                vTaskDelay( qpeekSHORT_DELAY );
423
        }
424
}
425
/*-----------------------------------------------------------*/
426
 
427
/* This is called to check that all the created tasks are still running. */
428
portBASE_TYPE xAreQueuePeekTasksStillRunning( void )
429
{
430
static unsigned portLONG ulLastLoopCounter = 0;
431
 
432
        /* If the demo task is still running then we expect the loopcounter to
433
        have incremented since this function was last called. */
434
        if( ulLastLoopCounter == ulLoopCounter )
435
        {
436
                xErrorDetected = pdTRUE;
437
        }
438
 
439
        ulLastLoopCounter = ulLoopCounter;
440
 
441
        /* Errors detected in the task itself will have latched xErrorDetected
442
        to true. */
443
 
444
        return !xErrorDetected;
445
}
446
 

powered by: WebSVN 2.1.0

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