TI's CC3100 websocket camera demo with Arducam mini ov5642 and freertos. Should work with other M3's. Work in progress test demo.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers croutine.h Source File

croutine.h

00001 /*
00002     FreeRTOS V8.2.1 - Copyright (C) 2015 Real Time Engineers Ltd.
00003     All rights reserved
00004 
00005     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
00006 
00007     This file is part of the FreeRTOS distribution.
00008 
00009     FreeRTOS is free software; you can redistribute it and/or modify it under
00010     the terms of the GNU General Public License (version 2) as published by the
00011     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
00012 
00013     ***************************************************************************
00014     >>!   NOTE: The modification to the GPL is included to allow you to     !<<
00015     >>!   distribute a combined work that includes FreeRTOS without being   !<<
00016     >>!   obliged to provide the source code for proprietary components     !<<
00017     >>!   outside of the FreeRTOS kernel.                                   !<<
00018     ***************************************************************************
00019 
00020     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
00021     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00022     FOR A PARTICULAR PURPOSE.  Full license text is available on the following
00023     link: http://www.freertos.org/a00114.html
00024 
00025     ***************************************************************************
00026      *                                                                       *
00027      *    FreeRTOS provides completely free yet professionally developed,    *
00028      *    robust, strictly quality controlled, supported, and cross          *
00029      *    platform software that is more than just the market leader, it     *
00030      *    is the industry's de facto standard.                               *
00031      *                                                                       *
00032      *    Help yourself get started quickly while simultaneously helping     *
00033      *    to support the FreeRTOS project by purchasing a FreeRTOS           *
00034      *    tutorial book, reference manual, or both:                          *
00035      *    http://www.FreeRTOS.org/Documentation                              *
00036      *                                                                       *
00037     ***************************************************************************
00038 
00039     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
00040     the FAQ page "My application does not run, what could be wrong?".  Have you
00041     defined configASSERT()?
00042 
00043     http://www.FreeRTOS.org/support - In return for receiving this top quality
00044     embedded software for free we request you assist our global community by
00045     participating in the support forum.
00046 
00047     http://www.FreeRTOS.org/training - Investing in training allows your team to
00048     be as productive as possible as early as possible.  Now you can receive
00049     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
00050     Ltd, and the world's leading authority on the world's leading RTOS.
00051 
00052     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
00053     including FreeRTOS+Trace - an indispensable productivity tool, a DOS
00054     compatible FAT file system, and our tiny thread aware UDP/IP stack.
00055 
00056     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
00057     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
00058 
00059     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
00060     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
00061     licenses offer ticketed support, indemnification and commercial middleware.
00062 
00063     http://www.SafeRTOS.com - High Integrity Systems also provide a safety
00064     engineered and independently SIL3 certified version for use in safety and
00065     mission critical applications that require provable dependability.
00066 
00067     1 tab == 4 spaces!
00068 */
00069 
00070 #ifndef CO_ROUTINE_H
00071 #define CO_ROUTINE_H
00072 
00073 #ifndef INC_FREERTOS_H
00074     #error "include FreeRTOS.h must appear in source files before include croutine.h"
00075 #endif
00076 
00077 #include "list.h"
00078 
00079 #ifdef __cplusplus
00080 extern "C" {
00081 #endif
00082 
00083 /* Used to hide the implementation of the co-routine control block.  The
00084 control block structure however has to be included in the header due to
00085 the macro implementation of the co-routine functionality. */
00086 typedef void * CoRoutineHandle_t;
00087 
00088 /* Defines the prototype to which co-routine functions must conform. */
00089 typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t );
00090 
00091 typedef struct corCoRoutineControlBlock
00092 {
00093     crCOROUTINE_CODE    pxCoRoutineFunction;
00094     ListItem_t          xGenericListItem;   /*< List item used to place the CRCB in ready and blocked queues. */
00095     ListItem_t          xEventListItem;     /*< List item used to place the CRCB in event lists. */
00096     UBaseType_t         uxPriority;         /*< The priority of the co-routine in relation to other co-routines. */
00097     UBaseType_t         uxIndex;            /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
00098     uint16_t            uxState;            /*< Used internally by the co-routine implementation. */
00099 } CRCB_t; /* Co-routine control block.  Note must be identical in size down to uxPriority with TCB_t. */
00100 
00101 /**
00102  * croutine. h
00103  *<pre>
00104  BaseType_t xCoRoutineCreate(
00105                                  crCOROUTINE_CODE pxCoRoutineCode,
00106                                  UBaseType_t uxPriority,
00107                                  UBaseType_t uxIndex
00108                                );</pre>
00109  *
00110  * Create a new co-routine and add it to the list of co-routines that are
00111  * ready to run.
00112  *
00113  * @param pxCoRoutineCode Pointer to the co-routine function.  Co-routine
00114  * functions require special syntax - see the co-routine section of the WEB
00115  * documentation for more information.
00116  *
00117  * @param uxPriority The priority with respect to other co-routines at which
00118  *  the co-routine will run.
00119  *
00120  * @param uxIndex Used to distinguish between different co-routines that
00121  * execute the same function.  See the example below and the co-routine section
00122  * of the WEB documentation for further information.
00123  *
00124  * @return pdPASS if the co-routine was successfully created and added to a ready
00125  * list, otherwise an error code defined with ProjDefs.h.
00126  *
00127  * Example usage:
00128    <pre>
00129  // Co-routine to be created.
00130  void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
00131  {
00132  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
00133  // This may not be necessary for const variables.
00134  static const char cLedToFlash[ 2 ] = { 5, 6 };
00135  static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
00136 
00137      // Must start every co-routine with a call to crSTART();
00138      crSTART( xHandle );
00139 
00140      for( ;; )
00141      {
00142          // This co-routine just delays for a fixed period, then toggles
00143          // an LED.  Two co-routines are created using this function, so
00144          // the uxIndex parameter is used to tell the co-routine which
00145          // LED to flash and how int32_t to delay.  This assumes xQueue has
00146          // already been created.
00147          vParTestToggleLED( cLedToFlash[ uxIndex ] );
00148          crDELAY( xHandle, uxFlashRates[ uxIndex ] );
00149      }
00150 
00151      // Must end every co-routine with a call to crEND();
00152      crEND();
00153  }
00154 
00155  // Function that creates two co-routines.
00156  void vOtherFunction( void )
00157  {
00158  uint8_t ucParameterToPass;
00159  TaskHandle_t xHandle;
00160 
00161      // Create two co-routines at priority 0.  The first is given index 0
00162      // so (from the code above) toggles LED 5 every 200 ticks.  The second
00163      // is given index 1 so toggles LED 6 every 400 ticks.
00164      for( uxIndex = 0; uxIndex < 2; uxIndex++ )
00165      {
00166          xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
00167      }
00168  }
00169    </pre>
00170  * \defgroup xCoRoutineCreate xCoRoutineCreate
00171  * \ingroup Tasks
00172  */
00173 BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex );
00174 
00175 
00176 /**
00177  * croutine. h
00178  *<pre>
00179  void vCoRoutineSchedule( void );</pre>
00180  *
00181  * Run a co-routine.
00182  *
00183  * vCoRoutineSchedule() executes the highest priority co-routine that is able
00184  * to run.  The co-routine will execute until it either blocks, yields or is
00185  * preempted by a task.  Co-routines execute cooperatively so one
00186  * co-routine cannot be preempted by another, but can be preempted by a task.
00187  *
00188  * If an application comprises of both tasks and co-routines then
00189  * vCoRoutineSchedule should be called from the idle task (in an idle task
00190  * hook).
00191  *
00192  * Example usage:
00193    <pre>
00194  // This idle task hook will schedule a co-routine each time it is called.
00195  // The rest of the idle task will execute between co-routine calls.
00196  void vApplicationIdleHook( void )
00197  {
00198     vCoRoutineSchedule();
00199  }
00200 
00201  // Alternatively, if you do not require any other part of the idle task to
00202  // execute, the idle task hook can call vCoRoutineScheduler() within an
00203  // infinite loop.
00204  void vApplicationIdleHook( void )
00205  {
00206     for( ;; )
00207     {
00208         vCoRoutineSchedule();
00209     }
00210  }
00211  </pre>
00212  * \defgroup vCoRoutineSchedule vCoRoutineSchedule
00213  * \ingroup Tasks
00214  */
00215 void vCoRoutineSchedule( void );
00216 
00217 /**
00218  * croutine. h
00219  * <pre>
00220  crSTART( CoRoutineHandle_t xHandle );</pre>
00221  *
00222  * This macro MUST always be called at the start of a co-routine function.
00223  *
00224  * Example usage:
00225    <pre>
00226  // Co-routine to be created.
00227  void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
00228  {
00229  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
00230  static int32_t ulAVariable;
00231 
00232      // Must start every co-routine with a call to crSTART();
00233      crSTART( xHandle );
00234 
00235      for( ;; )
00236      {
00237           // Co-routine functionality goes here.
00238      }
00239 
00240      // Must end every co-routine with a call to crEND();
00241      crEND();
00242  }</pre>
00243  * \defgroup crSTART crSTART
00244  * \ingroup Tasks
00245  */
00246 #define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0:
00247 
00248 /**
00249  * croutine. h
00250  * <pre>
00251  crEND();</pre>
00252  *
00253  * This macro MUST always be called at the end of a co-routine function.
00254  *
00255  * Example usage:
00256    <pre>
00257  // Co-routine to be created.
00258  void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
00259  {
00260  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
00261  static int32_t ulAVariable;
00262 
00263      // Must start every co-routine with a call to crSTART();
00264      crSTART( xHandle );
00265 
00266      for( ;; )
00267      {
00268           // Co-routine functionality goes here.
00269      }
00270 
00271      // Must end every co-routine with a call to crEND();
00272      crEND();
00273  }</pre>
00274  * \defgroup crSTART crSTART
00275  * \ingroup Tasks
00276  */
00277 #define crEND() }
00278 
00279 /*
00280  * These macros are intended for internal use by the co-routine implementation
00281  * only.  The macros should not be used directly by application writers.
00282  */
00283 #define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
00284 #define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
00285 
00286 /**
00287  * croutine. h
00288  *<pre>
00289  crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
00290  *
00291  * Delay a co-routine for a fixed period of time.
00292  *
00293  * crDELAY can only be called from the co-routine function itself - not
00294  * from within a function called by the co-routine function.  This is because
00295  * co-routines do not maintain their own stack.
00296  *
00297  * @param xHandle The handle of the co-routine to delay.  This is the xHandle
00298  * parameter of the co-routine function.
00299  *
00300  * @param xTickToDelay The number of ticks that the co-routine should delay
00301  * for.  The actual amount of time this equates to is defined by
00302  * configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant portTICK_PERIOD_MS
00303  * can be used to convert ticks to milliseconds.
00304  *
00305  * Example usage:
00306    <pre>
00307  // Co-routine to be created.
00308  void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
00309  {
00310  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
00311  // This may not be necessary for const variables.
00312  // We are to delay for 200ms.
00313  static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
00314 
00315      // Must start every co-routine with a call to crSTART();
00316      crSTART( xHandle );
00317 
00318      for( ;; )
00319      {
00320         // Delay for 200ms.
00321         crDELAY( xHandle, xDelayTime );
00322 
00323         // Do something here.
00324      }
00325 
00326      // Must end every co-routine with a call to crEND();
00327      crEND();
00328  }</pre>
00329  * \defgroup crDELAY crDELAY
00330  * \ingroup Tasks
00331  */
00332 #define crDELAY( xHandle, xTicksToDelay )                                               \
00333     if( ( xTicksToDelay ) > 0 )                                                         \
00334     {                                                                                   \
00335         vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL );                          \
00336     }                                                                                   \
00337     crSET_STATE0( ( xHandle ) );
00338 
00339 /**
00340  * <pre>
00341  crQUEUE_SEND(
00342                   CoRoutineHandle_t xHandle,
00343                   QueueHandle_t pxQueue,
00344                   void *pvItemToQueue,
00345                   TickType_t xTicksToWait,
00346                   BaseType_t *pxResult
00347              )</pre>
00348  *
00349  * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
00350  * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
00351  *
00352  * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
00353  * xQueueSend() and xQueueReceive() can only be used from tasks.
00354  *
00355  * crQUEUE_SEND can only be called from the co-routine function itself - not
00356  * from within a function called by the co-routine function.  This is because
00357  * co-routines do not maintain their own stack.
00358  *
00359  * See the co-routine section of the WEB documentation for information on
00360  * passing data between tasks and co-routines and between ISR's and
00361  * co-routines.
00362  *
00363  * @param xHandle The handle of the calling co-routine.  This is the xHandle
00364  * parameter of the co-routine function.
00365  *
00366  * @param pxQueue The handle of the queue on which the data will be posted.
00367  * The handle is obtained as the return value when the queue is created using
00368  * the xQueueCreate() API function.
00369  *
00370  * @param pvItemToQueue A pointer to the data being posted onto the queue.
00371  * The number of bytes of each queued item is specified when the queue is
00372  * created.  This number of bytes is copied from pvItemToQueue into the queue
00373  * itself.
00374  *
00375  * @param xTickToDelay The number of ticks that the co-routine should block
00376  * to wait for space to become available on the queue, should space not be
00377  * available immediately. The actual amount of time this equates to is defined
00378  * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
00379  * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example
00380  * below).
00381  *
00382  * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
00383  * data was successfully posted onto the queue, otherwise it will be set to an
00384  * error defined within ProjDefs.h.
00385  *
00386  * Example usage:
00387    <pre>
00388  // Co-routine function that blocks for a fixed period then posts a number onto
00389  // a queue.
00390  static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
00391  {
00392  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
00393  static BaseType_t xNumberToPost = 0;
00394  static BaseType_t xResult;
00395 
00396     // Co-routines must begin with a call to crSTART().
00397     crSTART( xHandle );
00398 
00399     for( ;; )
00400     {
00401         // This assumes the queue has already been created.
00402         crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
00403 
00404         if( xResult != pdPASS )
00405         {
00406             // The message was not posted!
00407         }
00408 
00409         // Increment the number to be posted onto the queue.
00410         xNumberToPost++;
00411 
00412         // Delay for 100 ticks.
00413         crDELAY( xHandle, 100 );
00414     }
00415 
00416     // Co-routines must end with a call to crEND().
00417     crEND();
00418  }</pre>
00419  * \defgroup crQUEUE_SEND crQUEUE_SEND
00420  * \ingroup Tasks
00421  */
00422 #define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult )         \
00423 {                                                                                       \
00424     *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) );   \
00425     if( *( pxResult ) == errQUEUE_BLOCKED )                                             \
00426     {                                                                                   \
00427         crSET_STATE0( ( xHandle ) );                                                    \
00428         *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 );                  \
00429     }                                                                                   \
00430     if( *pxResult == errQUEUE_YIELD )                                                   \
00431     {                                                                                   \
00432         crSET_STATE1( ( xHandle ) );                                                    \
00433         *pxResult = pdPASS;                                                             \
00434     }                                                                                   \
00435 }
00436 
00437 /**
00438  * croutine. h
00439  * <pre>
00440   crQUEUE_RECEIVE(
00441                      CoRoutineHandle_t xHandle,
00442                      QueueHandle_t pxQueue,
00443                      void *pvBuffer,
00444                      TickType_t xTicksToWait,
00445                      BaseType_t *pxResult
00446                  )</pre>
00447  *
00448  * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
00449  * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
00450  *
00451  * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
00452  * xQueueSend() and xQueueReceive() can only be used from tasks.
00453  *
00454  * crQUEUE_RECEIVE can only be called from the co-routine function itself - not
00455  * from within a function called by the co-routine function.  This is because
00456  * co-routines do not maintain their own stack.
00457  *
00458  * See the co-routine section of the WEB documentation for information on
00459  * passing data between tasks and co-routines and between ISR's and
00460  * co-routines.
00461  *
00462  * @param xHandle The handle of the calling co-routine.  This is the xHandle
00463  * parameter of the co-routine function.
00464  *
00465  * @param pxQueue The handle of the queue from which the data will be received.
00466  * The handle is obtained as the return value when the queue is created using
00467  * the xQueueCreate() API function.
00468  *
00469  * @param pvBuffer The buffer into which the received item is to be copied.
00470  * The number of bytes of each queued item is specified when the queue is
00471  * created.  This number of bytes is copied into pvBuffer.
00472  *
00473  * @param xTickToDelay The number of ticks that the co-routine should block
00474  * to wait for data to become available from the queue, should data not be
00475  * available immediately. The actual amount of time this equates to is defined
00476  * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
00477  * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the
00478  * crQUEUE_SEND example).
00479  *
00480  * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
00481  * data was successfully retrieved from the queue, otherwise it will be set to
00482  * an error code as defined within ProjDefs.h.
00483  *
00484  * Example usage:
00485  <pre>
00486  // A co-routine receives the number of an LED to flash from a queue.  It
00487  // blocks on the queue until the number is received.
00488  static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
00489  {
00490  // Variables in co-routines must be declared static if they must maintain value across a blocking call.
00491  static BaseType_t xResult;
00492  static UBaseType_t uxLEDToFlash;
00493 
00494     // All co-routines must start with a call to crSTART().
00495     crSTART( xHandle );
00496 
00497     for( ;; )
00498     {
00499         // Wait for data to become available on the queue.
00500         crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
00501 
00502         if( xResult == pdPASS )
00503         {
00504             // We received the LED to flash - flash it!
00505             vParTestToggleLED( uxLEDToFlash );
00506         }
00507     }
00508 
00509     crEND();
00510  }</pre>
00511  * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
00512  * \ingroup Tasks
00513  */
00514 #define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult )           \
00515 {                                                                                       \
00516     *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) );     \
00517     if( *( pxResult ) == errQUEUE_BLOCKED )                                             \
00518     {                                                                                   \
00519         crSET_STATE0( ( xHandle ) );                                                    \
00520         *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 );                \
00521     }                                                                                   \
00522     if( *( pxResult ) == errQUEUE_YIELD )                                               \
00523     {                                                                                   \
00524         crSET_STATE1( ( xHandle ) );                                                    \
00525         *( pxResult ) = pdPASS;                                                         \
00526     }                                                                                   \
00527 }
00528 
00529 /**
00530  * croutine. h
00531  * <pre>
00532   crQUEUE_SEND_FROM_ISR(
00533                             QueueHandle_t pxQueue,
00534                             void *pvItemToQueue,
00535                             BaseType_t xCoRoutinePreviouslyWoken
00536                        )</pre>
00537  *
00538  * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
00539  * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
00540  * functions used by tasks.
00541  *
00542  * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
00543  * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
00544  * xQueueReceiveFromISR() can only be used to pass data between a task and and
00545  * ISR.
00546  *
00547  * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
00548  * that is being used from within a co-routine.
00549  *
00550  * See the co-routine section of the WEB documentation for information on
00551  * passing data between tasks and co-routines and between ISR's and
00552  * co-routines.
00553  *
00554  * @param xQueue The handle to the queue on which the item is to be posted.
00555  *
00556  * @param pvItemToQueue A pointer to the item that is to be placed on the
00557  * queue.  The size of the items the queue will hold was defined when the
00558  * queue was created, so this many bytes will be copied from pvItemToQueue
00559  * into the queue storage area.
00560  *
00561  * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
00562  * the same queue multiple times from a single interrupt.  The first call
00563  * should always pass in pdFALSE.  Subsequent calls should pass in
00564  * the value returned from the previous call.
00565  *
00566  * @return pdTRUE if a co-routine was woken by posting onto the queue.  This is
00567  * used by the ISR to determine if a context switch may be required following
00568  * the ISR.
00569  *
00570  * Example usage:
00571  <pre>
00572  // A co-routine that blocks on a queue waiting for characters to be received.
00573  static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
00574  {
00575  char cRxedChar;
00576  BaseType_t xResult;
00577 
00578      // All co-routines must start with a call to crSTART().
00579      crSTART( xHandle );
00580 
00581      for( ;; )
00582      {
00583          // Wait for data to become available on the queue.  This assumes the
00584          // queue xCommsRxQueue has already been created!
00585          crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
00586 
00587          // Was a character received?
00588          if( xResult == pdPASS )
00589          {
00590              // Process the character here.
00591          }
00592      }
00593 
00594      // All co-routines must end with a call to crEND().
00595      crEND();
00596  }
00597 
00598  // An ISR that uses a queue to send characters received on a serial port to
00599  // a co-routine.
00600  void vUART_ISR( void )
00601  {
00602  char cRxedChar;
00603  BaseType_t xCRWokenByPost = pdFALSE;
00604 
00605      // We loop around reading characters until there are none left in the UART.
00606      while( UART_RX_REG_NOT_EMPTY() )
00607      {
00608          // Obtain the character from the UART.
00609          cRxedChar = UART_RX_REG;
00610 
00611          // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
00612          // the first time around the loop.  If the post causes a co-routine
00613          // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
00614          // In this manner we can ensure that if more than one co-routine is
00615          // blocked on the queue only one is woken by this ISR no matter how
00616          // many characters are posted to the queue.
00617          xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
00618      }
00619  }</pre>
00620  * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
00621  * \ingroup Tasks
00622  */
00623 #define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
00624 
00625 
00626 /**
00627  * croutine. h
00628  * <pre>
00629   crQUEUE_SEND_FROM_ISR(
00630                             QueueHandle_t pxQueue,
00631                             void *pvBuffer,
00632                             BaseType_t * pxCoRoutineWoken
00633                        )</pre>
00634  *
00635  * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
00636  * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
00637  * functions used by tasks.
00638  *
00639  * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
00640  * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
00641  * xQueueReceiveFromISR() can only be used to pass data between a task and and
00642  * ISR.
00643  *
00644  * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
00645  * from a queue that is being used from within a co-routine (a co-routine
00646  * posted to the queue).
00647  *
00648  * See the co-routine section of the WEB documentation for information on
00649  * passing data between tasks and co-routines and between ISR's and
00650  * co-routines.
00651  *
00652  * @param xQueue The handle to the queue on which the item is to be posted.
00653  *
00654  * @param pvBuffer A pointer to a buffer into which the received item will be
00655  * placed.  The size of the items the queue will hold was defined when the
00656  * queue was created, so this many bytes will be copied from the queue into
00657  * pvBuffer.
00658  *
00659  * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
00660  * available on the queue.  If crQUEUE_RECEIVE_FROM_ISR causes such a
00661  * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
00662  * *pxCoRoutineWoken will remain unchanged.
00663  *
00664  * @return pdTRUE an item was successfully received from the queue, otherwise
00665  * pdFALSE.
00666  *
00667  * Example usage:
00668  <pre>
00669  // A co-routine that posts a character to a queue then blocks for a fixed
00670  // period.  The character is incremented each time.
00671  static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
00672  {
00673  // cChar holds its value while this co-routine is blocked and must therefore
00674  // be declared static.
00675  static char cCharToTx = 'a';
00676  BaseType_t xResult;
00677 
00678      // All co-routines must start with a call to crSTART().
00679      crSTART( xHandle );
00680 
00681      for( ;; )
00682      {
00683          // Send the next character to the queue.
00684          crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
00685 
00686          if( xResult == pdPASS )
00687          {
00688              // The character was successfully posted to the queue.
00689          }
00690          else
00691          {
00692             // Could not post the character to the queue.
00693          }
00694 
00695          // Enable the UART Tx interrupt to cause an interrupt in this
00696          // hypothetical UART.  The interrupt will obtain the character
00697          // from the queue and send it.
00698          ENABLE_RX_INTERRUPT();
00699 
00700          // Increment to the next character then block for a fixed period.
00701          // cCharToTx will maintain its value across the delay as it is
00702          // declared static.
00703          cCharToTx++;
00704          if( cCharToTx > 'x' )
00705          {
00706             cCharToTx = 'a';
00707          }
00708          crDELAY( 100 );
00709      }
00710 
00711      // All co-routines must end with a call to crEND().
00712      crEND();
00713  }
00714 
00715  // An ISR that uses a queue to receive characters to send on a UART.
00716  void vUART_ISR( void )
00717  {
00718  char cCharToTx;
00719  BaseType_t xCRWokenByPost = pdFALSE;
00720 
00721      while( UART_TX_REG_EMPTY() )
00722      {
00723          // Are there any characters in the queue waiting to be sent?
00724          // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
00725          // is woken by the post - ensuring that only a single co-routine is
00726          // woken no matter how many times we go around this loop.
00727          if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
00728          {
00729              SEND_CHARACTER( cCharToTx );
00730          }
00731      }
00732  }</pre>
00733  * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
00734  * \ingroup Tasks
00735  */
00736 #define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
00737 
00738 /*
00739  * This function is intended for internal use by the co-routine macros only.
00740  * The macro nature of the co-routine implementation requires that the
00741  * prototype appears here.  The function should not be used by application
00742  * writers.
00743  *
00744  * Removes the current co-routine from its ready list and places it in the
00745  * appropriate delayed list.
00746  */
00747 void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList );
00748 
00749 /*
00750  * This function is intended for internal use by the queue implementation only.
00751  * The function should not be used by application writers.
00752  *
00753  * Removes the highest priority co-routine from the event list and places it in
00754  * the pending ready list.
00755  */
00756 BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList );
00757 
00758 #ifdef __cplusplus
00759 }
00760 #endif
00761 
00762 #endif /* CO_ROUTINE_H */
00763