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