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