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