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