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

Subversion Repositories openfire2

[/] [openfire2/] [trunk/] [sw/] [freertos/] [croutine.h] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 toni32
/*
2
        FreeRTOS.org V4.2.0 - Copyright (C) 2003-2007 Richard Barry.
3
 
4
        This file is part of the FreeRTOS.org distribution.
5
 
6
        FreeRTOS.org is free software; you can redistribute it and/or modify
7
        it under the terms of the GNU General Public License as published by
8
        the Free Software Foundation; either version 2 of the License, or
9
        (at your option) any later version.
10
 
11
        FreeRTOS.org is distributed in the hope that it will be useful,
12
        but WITHOUT ANY WARRANTY; without even the implied warranty of
13
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
        GNU General Public License for more details.
15
 
16
        You should have received a copy of the GNU General Public License
17
        along with FreeRTOS.org; if not, write to the Free Software
18
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
20
        A special exception to the GPL can be applied should you wish to distribute
21
        a combined work that includes FreeRTOS.org, without being obliged to provide
22
        the source code for any proprietary components.  See the licensing section
23
        of http://www.FreeRTOS.org for full details of how and when the exception
24
        can be applied.
25
 
26
        ***************************************************************************
27
        See http://www.FreeRTOS.org for documentation, latest information, license
28
        and contact details.  Please ensure to read the configuration and relevant
29
        port sections of the online documentation.
30
        ***************************************************************************
31
*/
32
#ifndef CO_ROUTINE_H
33
#define CO_ROUTINE_H
34
 
35
#include "list.h"
36
 
37
/* Used to hide the implementation of the co-routine control block.  The
38
control block structure however has to be included in the header due to
39
the macro implementation of the co-routine functionality. */
40
typedef void * xCoRoutineHandle;
41
 
42
/* Defines the prototype to which co-routine functions must conform. */
43
typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );
44
 
45
typedef struct corCoRoutineControlBlock
46
{
47
        crCOROUTINE_CODE                pxCoRoutineFunction;
48
        xListItem                               xGenericListItem;       /*< List item used to place the CRCB in ready and blocked queues. */
49
        xListItem                               xEventListItem;         /*< List item used to place the CRCB in event lists. */
50
        unsigned portBASE_TYPE  uxPriority;                     /*< The priority of the co-routine in relation to other co-routines. */
51
        unsigned portBASE_TYPE  uxIndex;                        /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
52
        unsigned portSHORT              uxState;                        /*< Used internally by the co-routine implementation. */
53
} corCRCB; /* Co-routine control block.  Note must be identical in size down to uxPriority with tskTCB. */
54
 
55
/**
56
 * croutine. h
57
 *<pre>
58
 portBASE_TYPE xCoRoutineCreate(
59
                                 crCOROUTINE_CODE pxCoRoutineCode,
60
                                 unsigned portBASE_TYPE uxPriority,
61
                                 unsigned portBASE_TYPE uxIndex
62
                               );</pre>
63
 *
64
 * Create a new co-routine and add it to the list of co-routines that are
65
 * ready to run.
66
 *
67
 * @param pxCoRoutineCode Pointer to the co-routine function.  Co-routine
68
 * functions require special syntax - see the co-routine section of the WEB
69
 * documentation for more information.
70
 *
71
 * @param uxPriority The priority with respect to other co-routines at which
72
 *  the co-routine will run.
73
 *
74
 * @param uxIndex Used to distinguish between different co-routines that
75
 * execute the same function.  See the example below and the co-routine section
76
 * of the WEB documentation for further information.
77
 *
78
 * @return pdPASS if the co-routine was successfully created and added to a ready
79
 * list, otherwise an error code defined with ProjDefs.h.
80
 *
81
 * Example usage:
82
   <pre>
83
 // Co-routine to be created.
84
 void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
85
 {
86
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
87
 // This may not be necessary for const variables.
88
 static const char cLedToFlash[ 2 ] = { 5, 6 };
89
 static const portTickType xTimeToDelay[ 2 ] = { 200, 400 };
90
 
91
     // Must start every co-routine with a call to crSTART();
92
     crSTART( xHandle );
93
 
94
     for( ;; )
95
     {
96
         // This co-routine just delays for a fixed period, then toggles
97
         // an LED.  Two co-routines are created using this function, so
98
         // the uxIndex parameter is used to tell the co-routine which
99
         // LED to flash and how long to delay.  This assumes xQueue has
100
         // already been created.
101
         vParTestToggleLED( cLedToFlash[ uxIndex ] );
102
         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
103
     }
104
 
105
     // Must end every co-routine with a call to crEND();
106
     crEND();
107
 }
108
 
109
 // Function that creates two co-routines.
110
 void vOtherFunction( void )
111
 {
112
 unsigned char ucParameterToPass;
113
 xTaskHandle xHandle;
114
 
115
     // Create two co-routines at priority 0.  The first is given index 0
116
     // so (from the code above) toggles LED 5 every 200 ticks.  The second
117
     // is given index 1 so toggles LED 6 every 400 ticks.
118
     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
119
     {
120
         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
121
     }
122
 }
123
   </pre>
124
 * \defgroup xCoRoutineCreate xCoRoutineCreate
125
 * \ingroup Tasks
126
 */
127
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
128
 
129
 
130
/**
131
 * croutine. h
132
 *<pre>
133
 void vCoRoutineSchedule( void );</pre>
134
 *
135
 * Run a co-routine.
136
 *
137
 * vCoRoutineSchedule() executes the highest priority co-routine that is able
138
 * to run.  The co-routine will execute until it either blocks, yields or is
139
 * preempted by a task.  Co-routines execute cooperatively so one
140
 * co-routine cannot be preempted by another, but can be preempted by a task.
141
 *
142
 * If an application comprises of both tasks and co-routines then
143
 * vCoRoutineSchedule should be called from the idle task (in an idle task
144
 * hook).
145
 *
146
 * Example usage:
147
   <pre>
148
 // This idle task hook will schedule a co-routine each time it is called.
149
 // The rest of the idle task will execute between co-routine calls.
150
 void vApplicationIdleHook( void )
151
 {
152
        vCoRoutineSchedule();
153
 }
154
 
155
 // Alternatively, if you do not require any other part of the idle task to
156
 // execute, the idle task hook can call vCoRoutineScheduler() within an
157
 // infinite loop.
158
 void vApplicationIdleHook( void )
159
 {
160
    for( ;; )
161
    {
162
        vCoRoutineSchedule();
163
    }
164
 }
165
 </pre>
166
 * \defgroup vCoRoutineSchedule vCoRoutineSchedule
167
 * \ingroup Tasks
168
 */
169
void vCoRoutineSchedule( void );
170
 
171
/**
172
 * croutine. h
173
 * <pre>
174
 crSTART( xCoRoutineHandle xHandle );</pre>
175
 *
176
 * This macro MUST always be called at the start of a co-routine function.
177
 *
178
 * Example usage:
179
   <pre>
180
 // Co-routine to be created.
181
 void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
182
 {
183
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
184
 static portLONG ulAVariable;
185
 
186
     // Must start every co-routine with a call to crSTART();
187
     crSTART( xHandle );
188
 
189
     for( ;; )
190
     {
191
          // Co-routine functionality goes here.
192
     }
193
 
194
     // Must end every co-routine with a call to crEND();
195
     crEND();
196
 }</pre>
197
 * \defgroup crSTART crSTART
198
 * \ingroup Tasks
199
 */
200
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0:
201
 
202
/**
203
 * croutine. h
204
 * <pre>
205
 crEND();</pre>
206
 *
207
 * This macro MUST always be called at the end of a co-routine function.
208
 *
209
 * Example usage:
210
   <pre>
211
 // Co-routine to be created.
212
 void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
213
 {
214
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
215
 static portLONG ulAVariable;
216
 
217
     // Must start every co-routine with a call to crSTART();
218
     crSTART( xHandle );
219
 
220
     for( ;; )
221
     {
222
          // Co-routine functionality goes here.
223
     }
224
 
225
     // Must end every co-routine with a call to crEND();
226
     crEND();
227
 }</pre>
228
 * \defgroup crSTART crSTART
229
 * \ingroup Tasks
230
 */
231
#define crEND() }
232
 
233
/*
234
 * These macros are intended for internal use by the co-routine implementation
235
 * only.  The macros should not be used directly by application writers.
236
 */
237
#define crSET_STATE0( xHandle ) ( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
238
#define crSET_STATE1( xHandle ) ( ( corCRCB * )xHandle)->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
239
 
240
/**
241
 * croutine. h
242
 *<pre>
243
 crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
244
 *
245
 * Delay a co-routine for a fixed period of time.
246
 *
247
 * crDELAY can only be called from the co-routine function itself - not
248
 * from within a function called by the co-routine function.  This is because
249
 * co-routines do not maintain their own stack.
250
 *
251
 * @param xHandle The handle of the co-routine to delay.  This is the xHandle
252
 * parameter of the co-routine function.
253
 *
254
 * @param xTickToDelay The number of ticks that the co-routine should delay
255
 * for.  The actual amount of time this equates to is defined by
256
 * configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant portTICK_RATE_MS
257
 * can be used to convert ticks to milliseconds.
258
 *
259
 * Example usage:
260
   <pre>
261
 // Co-routine to be created.
262
 void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
263
 {
264
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
265
 // This may not be necessary for const variables.
266
 // We are to delay for 200ms.
267
 static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
268
 
269
     // Must start every co-routine with a call to crSTART();
270
     crSTART( xHandle );
271
 
272
     for( ;; )
273
     {
274
        // Delay for 200ms.
275
        crDELAY( xHandle, xDelayTime );
276
 
277
        // Do something here.
278
     }
279
 
280
     // Must end every co-routine with a call to crEND();
281
     crEND();
282
 }</pre>
283
 * \defgroup crDELAY crDELAY
284
 * \ingroup Tasks
285
 */
286
#define crDELAY( xHandle, xTicksToDelay )                                                                                               \
287
        if( xTicksToDelay > 0 )                                                                                                                          \
288
        {                                                                                                                                                                       \
289
                vCoRoutineAddToDelayedList( xTicksToDelay, NULL );                                                              \
290
        }                                                                                                                                                                       \
291
        crSET_STATE0( xHandle );
292
 
293
/**
294
 * <pre>
295
 crQUEUE_SEND(
296
                  xCoRoutineHandle xHandle,
297
                  xQueueHandle pxQueue,
298
                  void *pvItemToQueue,
299
                  portTickType xTicksToWait,
300
                  portBASE_TYPE *pxResult
301
             )</pre>
302
 *
303
 * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
304
 * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
305
 *
306
 * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
307
 * xQueueSend() and xQueueReceive() can only be used from tasks.
308
 *
309
 * crQUEUE_SEND can only be called from the co-routine function itself - not
310
 * from within a function called by the co-routine function.  This is because
311
 * co-routines do not maintain their own stack.
312
 *
313
 * See the co-routine section of the WEB documentation for information on
314
 * passing data between tasks and co-routines and between ISR's and
315
 * co-routines.
316
 *
317
 * @param xHandle The handle of the calling co-routine.  This is the xHandle
318
 * parameter of the co-routine function.
319
 *
320
 * @param pxQueue The handle of the queue on which the data will be posted.
321
 * The handle is obtained as the return value when the queue is created using
322
 * the xQueueCreate() API function.
323
 *
324
 * @param pvItemToQueue A pointer to the data being posted onto the queue.
325
 * The number of bytes of each queued item is specified when the queue is
326
 * created.  This number of bytes is copied from pvItemToQueue into the queue
327
 * itself.
328
 *
329
 * @param xTickToDelay The number of ticks that the co-routine should block
330
 * to wait for space to become available on the queue, should space not be
331
 * available immediately. The actual amount of time this equates to is defined
332
 * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
333
 * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
334
 * below).
335
 *
336
 * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
337
 * data was successfully posted onto the queue, otherwise it will be set to an
338
 * error defined within ProjDefs.h.
339
 *
340
 * Example usage:
341
   <pre>
342
 // Co-routine function that blocks for a fixed period then posts a number onto
343
 // a queue.
344
 static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
345
 {
346
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
347
 static portBASE_TYPE xNumberToPost = 0;
348
 static portBASE_TYPE xResult;
349
 
350
    // Co-routines must begin with a call to crSTART().
351
    crSTART( xHandle );
352
 
353
    for( ;; )
354
    {
355
        // This assumes the queue has already been created.
356
        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
357
 
358
        if( xResult != pdPASS )
359
        {
360
            // The message was not posted!
361
        }
362
 
363
        // Increment the number to be posted onto the queue.
364
        xNumberToPost++;
365
 
366
        // Delay for 100 ticks.
367
        crDELAY( xHandle, 100 );
368
    }
369
 
370
    // Co-routines must end with a call to crEND().
371
    crEND();
372
 }</pre>
373
 * \defgroup crQUEUE_SEND crQUEUE_SEND
374
 * \ingroup Tasks
375
 */
376
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult )                 \
377
{                                                                                                                                                                               \
378
        *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, xTicksToWait );                                       \
379
        if( *pxResult == errQUEUE_BLOCKED )                                                                                                     \
380
        {                                                                                                                                                                       \
381
                crSET_STATE0( xHandle );                                                                                                                \
382
                *pxResult = xQueueCRSend( pxQueue, pvItemToQueue, 0 );                                                   \
383
        }                                                                                                                                                                       \
384
        if( *pxResult == errQUEUE_YIELD )                                                                                                       \
385
        {                                                                                                                                                                       \
386
                crSET_STATE1( xHandle );                                                                                                                \
387
                *pxResult = pdPASS;                                                                                                                             \
388
        }                                                                                                                                                                       \
389
}
390
 
391
/**
392
 * croutine. h
393
 * <pre>
394
  crQUEUE_RECEIVE(
395
                     xCoRoutineHandle xHandle,
396
                     xQueueHandle pxQueue,
397
                     void *pvBuffer,
398
                     portTickType xTicksToWait,
399
                     portBASE_TYPE *pxResult
400
                 )</pre>
401
 *
402
 * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
403
 * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
404
 *
405
 * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
406
 * xQueueSend() and xQueueReceive() can only be used from tasks.
407
 *
408
 * crQUEUE_RECEIVE can only be called from the co-routine function itself - not
409
 * from within a function called by the co-routine function.  This is because
410
 * co-routines do not maintain their own stack.
411
 *
412
 * See the co-routine section of the WEB documentation for information on
413
 * passing data between tasks and co-routines and between ISR's and
414
 * co-routines.
415
 *
416
 * @param xHandle The handle of the calling co-routine.  This is the xHandle
417
 * parameter of the co-routine function.
418
 *
419
 * @param pxQueue The handle of the queue from which the data will be received.
420
 * The handle is obtained as the return value when the queue is created using
421
 * the xQueueCreate() API function.
422
 *
423
 * @param pvBuffer The buffer into which the received item is to be copied.
424
 * The number of bytes of each queued item is specified when the queue is
425
 * created.  This number of bytes is copied into pvBuffer.
426
 *
427
 * @param xTickToDelay The number of ticks that the co-routine should block
428
 * to wait for data to become available from the queue, should data not be
429
 * available immediately. The actual amount of time this equates to is defined
430
 * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
431
 * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
432
 * crQUEUE_SEND example).
433
 *
434
 * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
435
 * data was successfully retrieved from the queue, otherwise it will be set to
436
 * an error code as defined within ProjDefs.h.
437
 *
438
 * Example usage:
439
 <pre>
440
 // A co-routine receives the number of an LED to flash from a queue.  It
441
 // blocks on the queue until the number is received.
442
 static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
443
 {
444
 // Variables in co-routines must be declared static if they must maintain value across a blocking call.
445
 static portBASE_TYPE xResult;
446
 static unsigned portBASE_TYPE uxLEDToFlash;
447
 
448
    // All co-routines must start with a call to crSTART().
449
    crSTART( xHandle );
450
 
451
    for( ;; )
452
    {
453
        // Wait for data to become available on the queue.
454
        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
455
 
456
        if( xResult == pdPASS )
457
        {
458
            // We received the LED to flash - flash it!
459
            vParTestToggleLED( uxLEDToFlash );
460
        }
461
    }
462
 
463
    crEND();
464
 }</pre>
465
 * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
466
 * \ingroup Tasks
467
 */
468
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult )                   \
469
{                                                                                                                                                                               \
470
        *pxResult = xQueueCRReceive( pxQueue, pvBuffer, xTicksToWait );                                         \
471
        if( *pxResult == errQUEUE_BLOCKED )                                                                                             \
472
        {                                                                                                                                                                       \
473
                crSET_STATE0( xHandle );                                                                                                                \
474
                *pxResult = xQueueCRReceive( pxQueue, pvBuffer, 0 );                                                     \
475
        }                                                                                                                                                                       \
476
        if( *pxResult == errQUEUE_YIELD )                                                                                                       \
477
        {                                                                                                                                                                       \
478
                crSET_STATE1( xHandle );                                                                                                                \
479
                *pxResult = pdPASS;                                                                                                                             \
480
        }                                                                                                                                                                       \
481
}
482
 
483
/**
484
 * croutine. h
485
 * <pre>
486
  crQUEUE_SEND_FROM_ISR(
487
                            xQueueHandle pxQueue,
488
                            void *pvItemToQueue,
489
                            portBASE_TYPE xCoRoutinePreviouslyWoken
490
                       )</pre>
491
 *
492
 * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
493
 * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
494
 * functions used by tasks.
495
 *
496
 * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
497
 * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
498
 * xQueueReceiveFromISR() can only be used to pass data between a task and and
499
 * ISR.
500
 *
501
 * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
502
 * that is being used from within a co-routine.
503
 *
504
 * See the co-routine section of the WEB documentation for information on
505
 * passing data between tasks and co-routines and between ISR's and
506
 * co-routines.
507
 *
508
 * @param xQueue The handle to the queue on which the item is to be posted.
509
 *
510
 * @param pvItemToQueue A pointer to the item that is to be placed on the
511
 * queue.  The size of the items the queue will hold was defined when the
512
 * queue was created, so this many bytes will be copied from pvItemToQueue
513
 * into the queue storage area.
514
 *
515
 * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
516
 * the same queue multiple times from a single interrupt.  The first call
517
 * should always pass in pdFALSE.  Subsequent calls should pass in
518
 * the value returned from the previous call.
519
 *
520
 * @return pdTRUE if a co-routine was woken by posting onto the queue.  This is
521
 * used by the ISR to determine if a context switch may be required following
522
 * the ISR.
523
 *
524
 * Example usage:
525
 <pre>
526
 // A co-routine that blocks on a queue waiting for characters to be received.
527
 static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
528
 {
529
 portCHAR cRxedChar;
530
 portBASE_TYPE xResult;
531
 
532
     // All co-routines must start with a call to crSTART().
533
     crSTART( xHandle );
534
 
535
     for( ;; )
536
     {
537
         // Wait for data to become available on the queue.  This assumes the
538
         // queue xCommsRxQueue has already been created!
539
         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
540
 
541
         // Was a character received?
542
         if( xResult == pdPASS )
543
         {
544
             // Process the character here.
545
         }
546
     }
547
 
548
     // All co-routines must end with a call to crEND().
549
     crEND();
550
 }
551
 
552
 // An ISR that uses a queue to send characters received on a serial port to
553
 // a co-routine.
554
 void vUART_ISR( void )
555
 {
556
 portCHAR cRxedChar;
557
 portBASE_TYPE xCRWokenByPost = pdFALSE;
558
 
559
     // We loop around reading characters until there are none left in the UART.
560
     while( UART_RX_REG_NOT_EMPTY() )
561
     {
562
         // Obtain the character from the UART.
563
         cRxedChar = UART_RX_REG;
564
 
565
         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
566
         // the first time around the loop.  If the post causes a co-routine
567
         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
568
         // In this manner we can ensure that if more than one co-routine is
569
         // blocked on the queue only one is woken by this ISR no matter how
570
         // many characters are posted to the queue.
571
         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
572
     }
573
 }</pre>
574
 * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
575
 * \ingroup Tasks
576
 */
577
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken )
578
 
579
 
580
/**
581
 * croutine. h
582
 * <pre>
583
  crQUEUE_SEND_FROM_ISR(
584
                            xQueueHandle pxQueue,
585
                            void *pvBuffer,
586
                            portBASE_TYPE * pxCoRoutineWoken
587
                       )</pre>
588
 *
589
 * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
590
 * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
591
 * functions used by tasks.
592
 *
593
 * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
594
 * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
595
 * xQueueReceiveFromISR() can only be used to pass data between a task and and
596
 * ISR.
597
 *
598
 * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
599
 * from a queue that is being used from within a co-routine (a co-routine
600
 * posted to the queue).
601
 *
602
 * See the co-routine section of the WEB documentation for information on
603
 * passing data between tasks and co-routines and between ISR's and
604
 * co-routines.
605
 *
606
 * @param xQueue The handle to the queue on which the item is to be posted.
607
 *
608
 * @param pvBuffer A pointer to a buffer into which the received item will be
609
 * placed.  The size of the items the queue will hold was defined when the
610
 * queue was created, so this many bytes will be copied from the queue into
611
 * pvBuffer.
612
 *
613
 * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
614
 * available on the queue.  If crQUEUE_RECEIVE_FROM_ISR causes such a
615
 * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
616
 * *pxCoRoutineWoken will remain unchanged.
617
 *
618
 * @return pdTRUE an item was successfully received from the queue, otherwise
619
 * pdFALSE.
620
 *
621
 * Example usage:
622
 <pre>
623
 // A co-routine that posts a character to a queue then blocks for a fixed
624
 // period.  The character is incremented each time.
625
 static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
626
 {
627
 // cChar holds its value while this co-routine is blocked and must therefore
628
 // be declared static.
629
 static portCHAR cCharToTx = 'a';
630
 portBASE_TYPE xResult;
631
 
632
     // All co-routines must start with a call to crSTART().
633
     crSTART( xHandle );
634
 
635
     for( ;; )
636
     {
637
         // Send the next character to the queue.
638
         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
639
 
640
         if( xResult == pdPASS )
641
         {
642
             // The character was successfully posted to the queue.
643
         }
644
                 else
645
                 {
646
                        // Could not post the character to the queue.
647
                 }
648
 
649
         // Enable the UART Tx interrupt to cause an interrupt in this
650
                 // hypothetical UART.  The interrupt will obtain the character
651
                 // from the queue and send it.
652
                 ENABLE_RX_INTERRUPT();
653
 
654
                 // Increment to the next character then block for a fixed period.
655
                 // cCharToTx will maintain its value across the delay as it is
656
                 // declared static.
657
                 cCharToTx++;
658
                 if( cCharToTx > 'x' )
659
                 {
660
                        cCharToTx = 'a';
661
                 }
662
                 crDELAY( 100 );
663
     }
664
 
665
     // All co-routines must end with a call to crEND().
666
     crEND();
667
 }
668
 
669
 // An ISR that uses a queue to receive characters to send on a UART.
670
 void vUART_ISR( void )
671
 {
672
 portCHAR cCharToTx;
673
 portBASE_TYPE xCRWokenByPost = pdFALSE;
674
 
675
     while( UART_TX_REG_EMPTY() )
676
     {
677
         // Are there any characters in the queue waiting to be sent?
678
                 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
679
                 // is woken by the post - ensuring that only a single co-routine is
680
                 // woken no matter how many times we go around this loop.
681
         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
682
                 {
683
                         SEND_CHARACTER( cCharToTx );
684
                 }
685
     }
686
 }</pre>
687
 * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
688
 * \ingroup Tasks
689
 */
690
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( pxQueue, pvBuffer, pxCoRoutineWoken )
691
 
692
/*
693
 * This function is intended for internal use by the co-routine macros only.
694
 * The macro nature of the co-routine implementation requires that the
695
 * prototype appears here.  The function should not be used by application
696
 * writers.
697
 *
698
 * Removes the current co-routine from its ready list and places it in the
699
 * appropriate delayed list.
700
 */
701
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );
702
 
703
/*
704
 * This function is intended for internal use by the queue implementation only.
705
 * The function should not be used by application writers.
706
 *
707
 * Removes the highest priority co-routine from the event list and places it in
708
 * the pending ready list.
709
 */
710
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
711
 
712
 
713
#endif /* CO_ROUTINE_H */

powered by: WebSVN 2.1.0

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