FreeRTOS v_8.2.1 for LPC1768

Dependents:   frtos_v_8_bluetooth frtos_v_8_pololu frtos_v_8_Final

Committer:
JoaoJardim
Date:
Mon Dec 10 10:04:09 2018 +0000
Revision:
1:2f4de0d9dc8b
Parent:
0:91ad48ad5687
Same implementation as freertos_bluetooth at this time, but with FreeRTOS v_8.2.1

Who changed what in which revision?

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