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.

Committer:
kenjiArai
Date:
Sat Jan 01 11:17:45 2011 +0000
Revision:
0:d4960fcea8ff

        

Who changed what in which revision?

UserRevisionLine numberNew 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 #include <stdlib.h>
kenjiArai 0:d4960fcea8ff 55 #include <string.h>
kenjiArai 0:d4960fcea8ff 56
kenjiArai 0:d4960fcea8ff 57 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
kenjiArai 0:d4960fcea8ff 58 all the API functions to use the MPU wrappers. That should only be done when
kenjiArai 0:d4960fcea8ff 59 task.h is included from an application file. */
kenjiArai 0:d4960fcea8ff 60 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
kenjiArai 0:d4960fcea8ff 61
kenjiArai 0:d4960fcea8ff 62 #include "FreeRTOS.h"
kenjiArai 0:d4960fcea8ff 63 #include "task.h"
kenjiArai 0:d4960fcea8ff 64 #include "croutine.h"
kenjiArai 0:d4960fcea8ff 65
kenjiArai 0:d4960fcea8ff 66 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
kenjiArai 0:d4960fcea8ff 67
kenjiArai 0:d4960fcea8ff 68 /*-----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 69 * PUBLIC LIST API documented in list.h
kenjiArai 0:d4960fcea8ff 70 *----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 71
kenjiArai 0:d4960fcea8ff 72 /* Constants used with the cRxLock and cTxLock structure members. */
kenjiArai 0:d4960fcea8ff 73 #define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )
kenjiArai 0:d4960fcea8ff 74 #define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 75
kenjiArai 0:d4960fcea8ff 76 #define queueERRONEOUS_UNBLOCK ( -1 )
kenjiArai 0:d4960fcea8ff 77
kenjiArai 0:d4960fcea8ff 78 /* For internal use only. */
kenjiArai 0:d4960fcea8ff 79 #define queueSEND_TO_BACK ( 0 )
kenjiArai 0:d4960fcea8ff 80 #define queueSEND_TO_FRONT ( 1 )
kenjiArai 0:d4960fcea8ff 81
kenjiArai 0:d4960fcea8ff 82 /* Effectively make a union out of the xQUEUE structure. */
kenjiArai 0:d4960fcea8ff 83 #define pxMutexHolder pcTail
kenjiArai 0:d4960fcea8ff 84 #define uxQueueType pcHead
kenjiArai 0:d4960fcea8ff 85 #define uxRecursiveCallCount pcReadFrom
kenjiArai 0:d4960fcea8ff 86 #define queueQUEUE_IS_MUTEX NULL
kenjiArai 0:d4960fcea8ff 87
kenjiArai 0:d4960fcea8ff 88 /* Semaphores do not actually store or copy data, so have an items size of
kenjiArai 0:d4960fcea8ff 89 zero. */
kenjiArai 0:d4960fcea8ff 90 #define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 )
kenjiArai 0:d4960fcea8ff 91 #define queueDONT_BLOCK ( ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 92 #define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 93
kenjiArai 0:d4960fcea8ff 94 #ifdef __cplusplus
kenjiArai 0:d4960fcea8ff 95 extern "C" {
kenjiArai 0:d4960fcea8ff 96 #endif
kenjiArai 0:d4960fcea8ff 97 /*
kenjiArai 0:d4960fcea8ff 98 * Definition of the queue used by the scheduler.
kenjiArai 0:d4960fcea8ff 99 * Items are queued by copy, not reference.
kenjiArai 0:d4960fcea8ff 100 */
kenjiArai 0:d4960fcea8ff 101 typedef struct QueueDefinition
kenjiArai 0:d4960fcea8ff 102 {
kenjiArai 0:d4960fcea8ff 103 signed char *pcHead; /*< Points to the beginning of the queue storage area. */
kenjiArai 0:d4960fcea8ff 104 signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
kenjiArai 0:d4960fcea8ff 105
kenjiArai 0:d4960fcea8ff 106 signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
kenjiArai 0:d4960fcea8ff 107 signed char *pcReadFrom; /*< Points to the last place that a queued item was read from. */
kenjiArai 0:d4960fcea8ff 108
kenjiArai 0:d4960fcea8ff 109 xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
kenjiArai 0:d4960fcea8ff 110 xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
kenjiArai 0:d4960fcea8ff 111
kenjiArai 0:d4960fcea8ff 112 volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */
kenjiArai 0:d4960fcea8ff 113 unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
kenjiArai 0:d4960fcea8ff 114 unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */
kenjiArai 0:d4960fcea8ff 115
kenjiArai 0:d4960fcea8ff 116 signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
kenjiArai 0:d4960fcea8ff 117 signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
kenjiArai 0:d4960fcea8ff 118
kenjiArai 0:d4960fcea8ff 119 } xQUEUE;
kenjiArai 0:d4960fcea8ff 120 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 121
kenjiArai 0:d4960fcea8ff 122 /*
kenjiArai 0:d4960fcea8ff 123 * Inside this file xQueueHandle is a pointer to a xQUEUE structure.
kenjiArai 0:d4960fcea8ff 124 * To keep the definition private the API header file defines it as a
kenjiArai 0:d4960fcea8ff 125 * pointer to void.
kenjiArai 0:d4960fcea8ff 126 */
kenjiArai 0:d4960fcea8ff 127 typedef xQUEUE * xQueueHandle;
kenjiArai 0:d4960fcea8ff 128
kenjiArai 0:d4960fcea8ff 129 #if 0
kenjiArai 0:d4960fcea8ff 130 /*
kenjiArai 0:d4960fcea8ff 131 * Prototypes for public functions are included here so we don't have to
kenjiArai 0:d4960fcea8ff 132 * include the API header file (as it defines xQueueHandle differently). These
kenjiArai 0:d4960fcea8ff 133 * functions are documented in the API header file.
kenjiArai 0:d4960fcea8ff 134 */
kenjiArai 0:d4960fcea8ff 135 xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 136 signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 137 unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 138 void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 139 signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 140 signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 141 signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 142 xQueueHandle xQueueCreateMutex( void ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 143 xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 144 portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 145 portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 146 signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 147 signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 148 signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 149 signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 150 unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 151
kenjiArai 0:d4960fcea8ff 152 /*
kenjiArai 0:d4960fcea8ff 153 * Co-routine queue functions differ from task queue functions. Co-routines are
kenjiArai 0:d4960fcea8ff 154 * an optional component.
kenjiArai 0:d4960fcea8ff 155 */
kenjiArai 0:d4960fcea8ff 156 #if configUSE_CO_ROUTINES == 1
kenjiArai 0:d4960fcea8ff 157 signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 158 signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 159 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 160 signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 161 #endif
kenjiArai 0:d4960fcea8ff 162 #else
kenjiArai 0:d4960fcea8ff 163 /*
kenjiArai 0:d4960fcea8ff 164 * Prototypes for public functions are included here so we don't have to
kenjiArai 0:d4960fcea8ff 165 * include the API header file (as it defines xQueueHandle differently). These
kenjiArai 0:d4960fcea8ff 166 * functions are documented in the API header file.
kenjiArai 0:d4960fcea8ff 167 */
kenjiArai 0:d4960fcea8ff 168 xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );
kenjiArai 0:d4960fcea8ff 169 signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
kenjiArai 0:d4960fcea8ff 170 unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue );
kenjiArai 0:d4960fcea8ff 171 void vQueueDelete( xQueueHandle xQueue );
kenjiArai 0:d4960fcea8ff 172 signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition );
kenjiArai 0:d4960fcea8ff 173 signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
kenjiArai 0:d4960fcea8ff 174 signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken );
kenjiArai 0:d4960fcea8ff 175 xQueueHandle xQueueCreateMutex( void );
kenjiArai 0:d4960fcea8ff 176 xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );
kenjiArai 0:d4960fcea8ff 177 portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime );
kenjiArai 0:d4960fcea8ff 178 portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex );
kenjiArai 0:d4960fcea8ff 179 signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
kenjiArai 0:d4960fcea8ff 180 signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
kenjiArai 0:d4960fcea8ff 181 signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue );
kenjiArai 0:d4960fcea8ff 182 signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue );
kenjiArai 0:d4960fcea8ff 183 unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue );
kenjiArai 0:d4960fcea8ff 184
kenjiArai 0:d4960fcea8ff 185 /*
kenjiArai 0:d4960fcea8ff 186 * Co-routine queue functions differ from task queue functions. Co-routines are
kenjiArai 0:d4960fcea8ff 187 * an optional component.
kenjiArai 0:d4960fcea8ff 188 */
kenjiArai 0:d4960fcea8ff 189 #if configUSE_CO_ROUTINES == 1
kenjiArai 0:d4960fcea8ff 190 signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken );
kenjiArai 0:d4960fcea8ff 191 signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken );
kenjiArai 0:d4960fcea8ff 192 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait );
kenjiArai 0:d4960fcea8ff 193 signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait );
kenjiArai 0:d4960fcea8ff 194 #endif
kenjiArai 0:d4960fcea8ff 195 #endif
kenjiArai 0:d4960fcea8ff 196 /*
kenjiArai 0:d4960fcea8ff 197 * The queue registry is just a means for kernel aware debuggers to locate
kenjiArai 0:d4960fcea8ff 198 * queue structures. It has no other purpose so is an optional component.
kenjiArai 0:d4960fcea8ff 199 */
kenjiArai 0:d4960fcea8ff 200 //#if configQUEUE_REGISTRY_SIZE > 0
kenjiArai 0:d4960fcea8ff 201
kenjiArai 0:d4960fcea8ff 202 /* The type stored within the queue registry array. This allows a name
kenjiArai 0:d4960fcea8ff 203 to be assigned to each queue making kernel aware debugging a little
kenjiArai 0:d4960fcea8ff 204 more user friendly. */
kenjiArai 0:d4960fcea8ff 205 typedef struct QUEUE_REGISTRY_ITEM
kenjiArai 0:d4960fcea8ff 206 {
kenjiArai 0:d4960fcea8ff 207 signed char *pcQueueName;
kenjiArai 0:d4960fcea8ff 208 xQueueHandle xHandle;
kenjiArai 0:d4960fcea8ff 209 } xQueueRegistryItem;
kenjiArai 0:d4960fcea8ff 210
kenjiArai 0:d4960fcea8ff 211 /* The queue registry is simply an array of xQueueRegistryItem structures.
kenjiArai 0:d4960fcea8ff 212 The pcQueueName member of a structure being NULL is indicative of the
kenjiArai 0:d4960fcea8ff 213 array position being vacant. */
kenjiArai 0:d4960fcea8ff 214 xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
kenjiArai 0:d4960fcea8ff 215
kenjiArai 0:d4960fcea8ff 216 /* Removes a queue from the registry by simply setting the pcQueueName
kenjiArai 0:d4960fcea8ff 217 member to NULL. */
kenjiArai 0:d4960fcea8ff 218 static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 219 //void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 220 extern void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName );
kenjiArai 0:d4960fcea8ff 221 //#endif
kenjiArai 0:d4960fcea8ff 222
kenjiArai 0:d4960fcea8ff 223 /*
kenjiArai 0:d4960fcea8ff 224 * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not
kenjiArai 0:d4960fcea8ff 225 * prevent an ISR from adding or removing items to the queue, but does prevent
kenjiArai 0:d4960fcea8ff 226 * an ISR from removing tasks from the queue event lists. If an ISR finds a
kenjiArai 0:d4960fcea8ff 227 * queue is locked it will instead increment the appropriate queue lock count
kenjiArai 0:d4960fcea8ff 228 * to indicate that a task may require unblocking. When the queue in unlocked
kenjiArai 0:d4960fcea8ff 229 * these lock counts are inspected, and the appropriate action taken.
kenjiArai 0:d4960fcea8ff 230 */
kenjiArai 0:d4960fcea8ff 231 static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 232
kenjiArai 0:d4960fcea8ff 233 /*
kenjiArai 0:d4960fcea8ff 234 * Uses a critical section to determine if there is any data in a queue.
kenjiArai 0:d4960fcea8ff 235 *
kenjiArai 0:d4960fcea8ff 236 * @return pdTRUE if the queue contains no items, otherwise pdFALSE.
kenjiArai 0:d4960fcea8ff 237 */
kenjiArai 0:d4960fcea8ff 238 static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 239
kenjiArai 0:d4960fcea8ff 240 /*
kenjiArai 0:d4960fcea8ff 241 * Uses a critical section to determine if there is any space in a queue.
kenjiArai 0:d4960fcea8ff 242 *
kenjiArai 0:d4960fcea8ff 243 * @return pdTRUE if there is no space, otherwise pdFALSE;
kenjiArai 0:d4960fcea8ff 244 */
kenjiArai 0:d4960fcea8ff 245 static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 246
kenjiArai 0:d4960fcea8ff 247 /*
kenjiArai 0:d4960fcea8ff 248 * Copies an item into the queue, either at the front of the queue or the
kenjiArai 0:d4960fcea8ff 249 * back of the queue.
kenjiArai 0:d4960fcea8ff 250 */
kenjiArai 0:d4960fcea8ff 251 #if 0
kenjiArai 0:d4960fcea8ff 252 static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 253 #else
kenjiArai 0:d4960fcea8ff 254 void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition );
kenjiArai 0:d4960fcea8ff 255 #endif
kenjiArai 0:d4960fcea8ff 256 /*
kenjiArai 0:d4960fcea8ff 257 * Copies an item out of a queue.
kenjiArai 0:d4960fcea8ff 258 */
kenjiArai 0:d4960fcea8ff 259 // Modified by Kenji Arai / JH1PJL, October 31st,2010
kenjiArai 0:d4960fcea8ff 260 #if 0
kenjiArai 0:d4960fcea8ff 261 static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION;
kenjiArai 0:d4960fcea8ff 262 #else
kenjiArai 0:d4960fcea8ff 263 void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer );
kenjiArai 0:d4960fcea8ff 264 #endif
kenjiArai 0:d4960fcea8ff 265 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 266
kenjiArai 0:d4960fcea8ff 267 /*
kenjiArai 0:d4960fcea8ff 268 * Macro to mark a queue as locked. Locking a queue prevents an ISR from
kenjiArai 0:d4960fcea8ff 269 * accessing the queue event lists.
kenjiArai 0:d4960fcea8ff 270 */
kenjiArai 0:d4960fcea8ff 271 #define prvLockQueue( pxQueue ) \
kenjiArai 0:d4960fcea8ff 272 { \
kenjiArai 0:d4960fcea8ff 273 taskENTER_CRITICAL(); \
kenjiArai 0:d4960fcea8ff 274 { \
kenjiArai 0:d4960fcea8ff 275 if( pxQueue->xRxLock == queueUNLOCKED ) \
kenjiArai 0:d4960fcea8ff 276 { \
kenjiArai 0:d4960fcea8ff 277 pxQueue->xRxLock = queueLOCKED_UNMODIFIED; \
kenjiArai 0:d4960fcea8ff 278 } \
kenjiArai 0:d4960fcea8ff 279 if( pxQueue->xTxLock == queueUNLOCKED ) \
kenjiArai 0:d4960fcea8ff 280 { \
kenjiArai 0:d4960fcea8ff 281 pxQueue->xTxLock = queueLOCKED_UNMODIFIED; \
kenjiArai 0:d4960fcea8ff 282 } \
kenjiArai 0:d4960fcea8ff 283 } \
kenjiArai 0:d4960fcea8ff 284 taskEXIT_CRITICAL(); \
kenjiArai 0:d4960fcea8ff 285 }
kenjiArai 0:d4960fcea8ff 286 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 287
kenjiArai 0:d4960fcea8ff 288 #ifdef __cplusplus
kenjiArai 0:d4960fcea8ff 289 }
kenjiArai 0:d4960fcea8ff 290 #endif
kenjiArai 0:d4960fcea8ff 291 /*-----------------------------------------------------------
kenjiArai 0:d4960fcea8ff 292 * PUBLIC QUEUE MANAGEMENT API documented in queue.h
kenjiArai 0:d4960fcea8ff 293 *----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 294
kenjiArai 0:d4960fcea8ff 295 xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize )
kenjiArai 0:d4960fcea8ff 296 {
kenjiArai 0:d4960fcea8ff 297 xQUEUE *pxNewQueue;
kenjiArai 0:d4960fcea8ff 298 size_t xQueueSizeInBytes;
kenjiArai 0:d4960fcea8ff 299
kenjiArai 0:d4960fcea8ff 300 /* Allocate the new queue structure. */
kenjiArai 0:d4960fcea8ff 301 if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 302 {
kenjiArai 0:d4960fcea8ff 303 pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
kenjiArai 0:d4960fcea8ff 304 if( pxNewQueue != NULL )
kenjiArai 0:d4960fcea8ff 305 {
kenjiArai 0:d4960fcea8ff 306 /* Create the list of pointers to queue items. The queue is one byte
kenjiArai 0:d4960fcea8ff 307 longer than asked for to make wrap checking easier/faster. */
kenjiArai 0:d4960fcea8ff 308 xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;
kenjiArai 0:d4960fcea8ff 309
kenjiArai 0:d4960fcea8ff 310 pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );
kenjiArai 0:d4960fcea8ff 311 if( pxNewQueue->pcHead != NULL )
kenjiArai 0:d4960fcea8ff 312 {
kenjiArai 0:d4960fcea8ff 313 /* Initialise the queue members as described above where the
kenjiArai 0:d4960fcea8ff 314 queue type is defined. */
kenjiArai 0:d4960fcea8ff 315 pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize );
kenjiArai 0:d4960fcea8ff 316 pxNewQueue->uxMessagesWaiting = 0;
kenjiArai 0:d4960fcea8ff 317 pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
kenjiArai 0:d4960fcea8ff 318 pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize );
kenjiArai 0:d4960fcea8ff 319 pxNewQueue->uxLength = uxQueueLength;
kenjiArai 0:d4960fcea8ff 320 pxNewQueue->uxItemSize = uxItemSize;
kenjiArai 0:d4960fcea8ff 321 pxNewQueue->xRxLock = queueUNLOCKED;
kenjiArai 0:d4960fcea8ff 322 pxNewQueue->xTxLock = queueUNLOCKED;
kenjiArai 0:d4960fcea8ff 323
kenjiArai 0:d4960fcea8ff 324 /* Likewise ensure the event queues start with the correct state. */
kenjiArai 0:d4960fcea8ff 325 vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
kenjiArai 0:d4960fcea8ff 326 vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
kenjiArai 0:d4960fcea8ff 327
kenjiArai 0:d4960fcea8ff 328 traceQUEUE_CREATE( pxNewQueue );
kenjiArai 0:d4960fcea8ff 329 return pxNewQueue;
kenjiArai 0:d4960fcea8ff 330 }
kenjiArai 0:d4960fcea8ff 331 else
kenjiArai 0:d4960fcea8ff 332 {
kenjiArai 0:d4960fcea8ff 333 traceQUEUE_CREATE_FAILED();
kenjiArai 0:d4960fcea8ff 334 vPortFree( pxNewQueue );
kenjiArai 0:d4960fcea8ff 335 }
kenjiArai 0:d4960fcea8ff 336 }
kenjiArai 0:d4960fcea8ff 337 }
kenjiArai 0:d4960fcea8ff 338
kenjiArai 0:d4960fcea8ff 339 /* Will only reach here if we could not allocate enough memory or no memory
kenjiArai 0:d4960fcea8ff 340 was required. */
kenjiArai 0:d4960fcea8ff 341 return NULL;
kenjiArai 0:d4960fcea8ff 342 }
kenjiArai 0:d4960fcea8ff 343 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 344
kenjiArai 0:d4960fcea8ff 345 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 346
kenjiArai 0:d4960fcea8ff 347 xQueueHandle xQueueCreateMutex( void )
kenjiArai 0:d4960fcea8ff 348 {
kenjiArai 0:d4960fcea8ff 349 xQUEUE *pxNewQueue;
kenjiArai 0:d4960fcea8ff 350
kenjiArai 0:d4960fcea8ff 351 /* Allocate the new queue structure. */
kenjiArai 0:d4960fcea8ff 352 pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
kenjiArai 0:d4960fcea8ff 353 if( pxNewQueue != NULL )
kenjiArai 0:d4960fcea8ff 354 {
kenjiArai 0:d4960fcea8ff 355 /* Information required for priority inheritance. */
kenjiArai 0:d4960fcea8ff 356 pxNewQueue->pxMutexHolder = NULL;
kenjiArai 0:d4960fcea8ff 357 pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;
kenjiArai 0:d4960fcea8ff 358
kenjiArai 0:d4960fcea8ff 359 /* Queues used as a mutex no data is actually copied into or out
kenjiArai 0:d4960fcea8ff 360 of the queue. */
kenjiArai 0:d4960fcea8ff 361 pxNewQueue->pcWriteTo = NULL;
kenjiArai 0:d4960fcea8ff 362 pxNewQueue->pcReadFrom = NULL;
kenjiArai 0:d4960fcea8ff 363
kenjiArai 0:d4960fcea8ff 364 /* Each mutex has a length of 1 (like a binary semaphore) and
kenjiArai 0:d4960fcea8ff 365 an item size of 0 as nothing is actually copied into or out
kenjiArai 0:d4960fcea8ff 366 of the mutex. */
kenjiArai 0:d4960fcea8ff 367 pxNewQueue->uxMessagesWaiting = 0;
kenjiArai 0:d4960fcea8ff 368 pxNewQueue->uxLength = 1;
kenjiArai 0:d4960fcea8ff 369 pxNewQueue->uxItemSize = 0;
kenjiArai 0:d4960fcea8ff 370 pxNewQueue->xRxLock = queueUNLOCKED;
kenjiArai 0:d4960fcea8ff 371 pxNewQueue->xTxLock = queueUNLOCKED;
kenjiArai 0:d4960fcea8ff 372
kenjiArai 0:d4960fcea8ff 373 /* Ensure the event queues start with the correct state. */
kenjiArai 0:d4960fcea8ff 374 vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
kenjiArai 0:d4960fcea8ff 375 vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
kenjiArai 0:d4960fcea8ff 376
kenjiArai 0:d4960fcea8ff 377 /* Start with the semaphore in the expected state. */
kenjiArai 0:d4960fcea8ff 378 xQueueGenericSend( pxNewQueue, NULL, 0, queueSEND_TO_BACK );
kenjiArai 0:d4960fcea8ff 379
kenjiArai 0:d4960fcea8ff 380 traceCREATE_MUTEX( pxNewQueue );
kenjiArai 0:d4960fcea8ff 381 }
kenjiArai 0:d4960fcea8ff 382 else
kenjiArai 0:d4960fcea8ff 383 {
kenjiArai 0:d4960fcea8ff 384 traceCREATE_MUTEX_FAILED();
kenjiArai 0:d4960fcea8ff 385 }
kenjiArai 0:d4960fcea8ff 386
kenjiArai 0:d4960fcea8ff 387 return pxNewQueue;
kenjiArai 0:d4960fcea8ff 388 }
kenjiArai 0:d4960fcea8ff 389
kenjiArai 0:d4960fcea8ff 390 #endif /* configUSE_MUTEXES */
kenjiArai 0:d4960fcea8ff 391 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 392
kenjiArai 0:d4960fcea8ff 393 #if configUSE_RECURSIVE_MUTEXES == 1
kenjiArai 0:d4960fcea8ff 394
kenjiArai 0:d4960fcea8ff 395 portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex )
kenjiArai 0:d4960fcea8ff 396 {
kenjiArai 0:d4960fcea8ff 397 portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 398
kenjiArai 0:d4960fcea8ff 399 /* If this is the task that holds the mutex then pxMutexHolder will not
kenjiArai 0:d4960fcea8ff 400 change outside of this task. If this task does not hold the mutex then
kenjiArai 0:d4960fcea8ff 401 pxMutexHolder can never coincidentally equal the tasks handle, and as
kenjiArai 0:d4960fcea8ff 402 this is the only condition we are interested in it does not matter if
kenjiArai 0:d4960fcea8ff 403 pxMutexHolder is accessed simultaneously by another task. Therefore no
kenjiArai 0:d4960fcea8ff 404 mutual exclusion is required to test the pxMutexHolder variable. */
kenjiArai 0:d4960fcea8ff 405 if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
kenjiArai 0:d4960fcea8ff 406 {
kenjiArai 0:d4960fcea8ff 407 traceGIVE_MUTEX_RECURSIVE( pxMutex );
kenjiArai 0:d4960fcea8ff 408
kenjiArai 0:d4960fcea8ff 409 /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to
kenjiArai 0:d4960fcea8ff 410 the task handle, therefore no underflow check is required. Also,
kenjiArai 0:d4960fcea8ff 411 uxRecursiveCallCount is only modified by the mutex holder, and as
kenjiArai 0:d4960fcea8ff 412 there can only be one, no mutual exclusion is required to modify the
kenjiArai 0:d4960fcea8ff 413 uxRecursiveCallCount member. */
kenjiArai 0:d4960fcea8ff 414 ( pxMutex->uxRecursiveCallCount )--;
kenjiArai 0:d4960fcea8ff 415
kenjiArai 0:d4960fcea8ff 416 /* Have we unwound the call count? */
kenjiArai 0:d4960fcea8ff 417 if( pxMutex->uxRecursiveCallCount == 0 )
kenjiArai 0:d4960fcea8ff 418 {
kenjiArai 0:d4960fcea8ff 419 /* Return the mutex. This will automatically unblock any other
kenjiArai 0:d4960fcea8ff 420 task that might be waiting to access the mutex. */
kenjiArai 0:d4960fcea8ff 421 xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );
kenjiArai 0:d4960fcea8ff 422 }
kenjiArai 0:d4960fcea8ff 423
kenjiArai 0:d4960fcea8ff 424 xReturn = pdPASS;
kenjiArai 0:d4960fcea8ff 425 }
kenjiArai 0:d4960fcea8ff 426 else
kenjiArai 0:d4960fcea8ff 427 {
kenjiArai 0:d4960fcea8ff 428 /* We cannot give the mutex because we are not the holder. */
kenjiArai 0:d4960fcea8ff 429 xReturn = pdFAIL;
kenjiArai 0:d4960fcea8ff 430
kenjiArai 0:d4960fcea8ff 431 traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex );
kenjiArai 0:d4960fcea8ff 432 }
kenjiArai 0:d4960fcea8ff 433
kenjiArai 0:d4960fcea8ff 434 return xReturn;
kenjiArai 0:d4960fcea8ff 435 }
kenjiArai 0:d4960fcea8ff 436
kenjiArai 0:d4960fcea8ff 437 #endif /* configUSE_RECURSIVE_MUTEXES */
kenjiArai 0:d4960fcea8ff 438 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 439
kenjiArai 0:d4960fcea8ff 440 #if configUSE_RECURSIVE_MUTEXES == 1
kenjiArai 0:d4960fcea8ff 441
kenjiArai 0:d4960fcea8ff 442 portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle pxMutex, portTickType xBlockTime )
kenjiArai 0:d4960fcea8ff 443 {
kenjiArai 0:d4960fcea8ff 444 portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 445
kenjiArai 0:d4960fcea8ff 446 /* Comments regarding mutual exclusion as per those within
kenjiArai 0:d4960fcea8ff 447 xQueueGiveMutexRecursive(). */
kenjiArai 0:d4960fcea8ff 448
kenjiArai 0:d4960fcea8ff 449 traceTAKE_MUTEX_RECURSIVE( pxMutex );
kenjiArai 0:d4960fcea8ff 450
kenjiArai 0:d4960fcea8ff 451 if( pxMutex->pxMutexHolder == xTaskGetCurrentTaskHandle() )
kenjiArai 0:d4960fcea8ff 452 {
kenjiArai 0:d4960fcea8ff 453 ( pxMutex->uxRecursiveCallCount )++;
kenjiArai 0:d4960fcea8ff 454 xReturn = pdPASS;
kenjiArai 0:d4960fcea8ff 455 }
kenjiArai 0:d4960fcea8ff 456 else
kenjiArai 0:d4960fcea8ff 457 {
kenjiArai 0:d4960fcea8ff 458 xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );
kenjiArai 0:d4960fcea8ff 459
kenjiArai 0:d4960fcea8ff 460 /* pdPASS will only be returned if we successfully obtained the mutex,
kenjiArai 0:d4960fcea8ff 461 we may have blocked to reach here. */
kenjiArai 0:d4960fcea8ff 462 if( xReturn == pdPASS )
kenjiArai 0:d4960fcea8ff 463 {
kenjiArai 0:d4960fcea8ff 464 ( pxMutex->uxRecursiveCallCount )++;
kenjiArai 0:d4960fcea8ff 465 }
kenjiArai 0:d4960fcea8ff 466 }
kenjiArai 0:d4960fcea8ff 467
kenjiArai 0:d4960fcea8ff 468 return xReturn;
kenjiArai 0:d4960fcea8ff 469 }
kenjiArai 0:d4960fcea8ff 470
kenjiArai 0:d4960fcea8ff 471 #endif /* configUSE_RECURSIVE_MUTEXES */
kenjiArai 0:d4960fcea8ff 472 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 473
kenjiArai 0:d4960fcea8ff 474 #if configUSE_COUNTING_SEMAPHORES == 1
kenjiArai 0:d4960fcea8ff 475
kenjiArai 0:d4960fcea8ff 476 xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )
kenjiArai 0:d4960fcea8ff 477 {
kenjiArai 0:d4960fcea8ff 478 xQueueHandle pxHandle;
kenjiArai 0:d4960fcea8ff 479
kenjiArai 0:d4960fcea8ff 480 pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH );
kenjiArai 0:d4960fcea8ff 481
kenjiArai 0:d4960fcea8ff 482 if( pxHandle != NULL )
kenjiArai 0:d4960fcea8ff 483 {
kenjiArai 0:d4960fcea8ff 484 pxHandle->uxMessagesWaiting = uxInitialCount;
kenjiArai 0:d4960fcea8ff 485
kenjiArai 0:d4960fcea8ff 486 traceCREATE_COUNTING_SEMAPHORE();
kenjiArai 0:d4960fcea8ff 487 }
kenjiArai 0:d4960fcea8ff 488 else
kenjiArai 0:d4960fcea8ff 489 {
kenjiArai 0:d4960fcea8ff 490 traceCREATE_COUNTING_SEMAPHORE_FAILED();
kenjiArai 0:d4960fcea8ff 491 }
kenjiArai 0:d4960fcea8ff 492
kenjiArai 0:d4960fcea8ff 493 return pxHandle;
kenjiArai 0:d4960fcea8ff 494 }
kenjiArai 0:d4960fcea8ff 495
kenjiArai 0:d4960fcea8ff 496 #endif /* configUSE_COUNTING_SEMAPHORES */
kenjiArai 0:d4960fcea8ff 497 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 498
kenjiArai 0:d4960fcea8ff 499 signed portBASE_TYPE xQueueGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
kenjiArai 0:d4960fcea8ff 500 {
kenjiArai 0:d4960fcea8ff 501 signed portBASE_TYPE xEntryTimeSet = pdFALSE;
kenjiArai 0:d4960fcea8ff 502 xTimeOutType xTimeOut;
kenjiArai 0:d4960fcea8ff 503
kenjiArai 0:d4960fcea8ff 504 /* This function relaxes the coding standard somewhat to allow return
kenjiArai 0:d4960fcea8ff 505 statements within the function itself. This is done in the interest
kenjiArai 0:d4960fcea8ff 506 of execution time efficiency. */
kenjiArai 0:d4960fcea8ff 507 for( ;; )
kenjiArai 0:d4960fcea8ff 508 {
kenjiArai 0:d4960fcea8ff 509 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 510 {
kenjiArai 0:d4960fcea8ff 511 /* Is there room on the queue now? To be running we must be
kenjiArai 0:d4960fcea8ff 512 the highest priority task wanting to access the queue. */
kenjiArai 0:d4960fcea8ff 513 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
kenjiArai 0:d4960fcea8ff 514 {
kenjiArai 0:d4960fcea8ff 515 traceQUEUE_SEND( pxQueue );
kenjiArai 0:d4960fcea8ff 516 prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
kenjiArai 0:d4960fcea8ff 517
kenjiArai 0:d4960fcea8ff 518 /* If there was a task waiting for data to arrive on the
kenjiArai 0:d4960fcea8ff 519 queue then unblock it now. */
kenjiArai 0:d4960fcea8ff 520 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
kenjiArai 0:d4960fcea8ff 521 {
kenjiArai 0:d4960fcea8ff 522 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
kenjiArai 0:d4960fcea8ff 523 {
kenjiArai 0:d4960fcea8ff 524 /* The unblocked task has a priority higher than
kenjiArai 0:d4960fcea8ff 525 our own so yield immediately. Yes it is ok to do
kenjiArai 0:d4960fcea8ff 526 this from within the critical section - the kernel
kenjiArai 0:d4960fcea8ff 527 takes care of that. */
kenjiArai 0:d4960fcea8ff 528 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 529 }
kenjiArai 0:d4960fcea8ff 530 }
kenjiArai 0:d4960fcea8ff 531
kenjiArai 0:d4960fcea8ff 532 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 533
kenjiArai 0:d4960fcea8ff 534 /* Return to the original privilege level before exiting the
kenjiArai 0:d4960fcea8ff 535 function. */
kenjiArai 0:d4960fcea8ff 536 return pdPASS;
kenjiArai 0:d4960fcea8ff 537 }
kenjiArai 0:d4960fcea8ff 538 else
kenjiArai 0:d4960fcea8ff 539 {
kenjiArai 0:d4960fcea8ff 540 if( xTicksToWait == ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 541 {
kenjiArai 0:d4960fcea8ff 542 /* The queue was full and no block time is specified (or
kenjiArai 0:d4960fcea8ff 543 the block time has expired) so leave now. */
kenjiArai 0:d4960fcea8ff 544 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 545
kenjiArai 0:d4960fcea8ff 546 /* Return to the original privilege level before exiting
kenjiArai 0:d4960fcea8ff 547 the function. */
kenjiArai 0:d4960fcea8ff 548 traceQUEUE_SEND_FAILED( pxQueue );
kenjiArai 0:d4960fcea8ff 549 return errQUEUE_FULL;
kenjiArai 0:d4960fcea8ff 550 }
kenjiArai 0:d4960fcea8ff 551 else if( xEntryTimeSet == pdFALSE )
kenjiArai 0:d4960fcea8ff 552 {
kenjiArai 0:d4960fcea8ff 553 /* The queue was full and a block time was specified so
kenjiArai 0:d4960fcea8ff 554 configure the timeout structure. */
kenjiArai 0:d4960fcea8ff 555 vTaskSetTimeOutState( &xTimeOut );
kenjiArai 0:d4960fcea8ff 556 xEntryTimeSet = pdTRUE;
kenjiArai 0:d4960fcea8ff 557 }
kenjiArai 0:d4960fcea8ff 558 }
kenjiArai 0:d4960fcea8ff 559 }
kenjiArai 0:d4960fcea8ff 560 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 561
kenjiArai 0:d4960fcea8ff 562 /* Interrupts and other tasks can send to and receive from the queue
kenjiArai 0:d4960fcea8ff 563 now the critical section has been exited. */
kenjiArai 0:d4960fcea8ff 564
kenjiArai 0:d4960fcea8ff 565 vTaskSuspendAll();
kenjiArai 0:d4960fcea8ff 566 prvLockQueue( pxQueue );
kenjiArai 0:d4960fcea8ff 567
kenjiArai 0:d4960fcea8ff 568 /* Update the timeout state to see if it has expired yet. */
kenjiArai 0:d4960fcea8ff 569 if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
kenjiArai 0:d4960fcea8ff 570 {
kenjiArai 0:d4960fcea8ff 571 if( prvIsQueueFull( pxQueue ) )
kenjiArai 0:d4960fcea8ff 572 {
kenjiArai 0:d4960fcea8ff 573 traceBLOCKING_ON_QUEUE_SEND( pxQueue );
kenjiArai 0:d4960fcea8ff 574 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
kenjiArai 0:d4960fcea8ff 575
kenjiArai 0:d4960fcea8ff 576 /* Unlocking the queue means queue events can effect the
kenjiArai 0:d4960fcea8ff 577 event list. It is possible that interrupts occurring now
kenjiArai 0:d4960fcea8ff 578 remove this task from the event list again - but as the
kenjiArai 0:d4960fcea8ff 579 scheduler is suspended the task will go onto the pending
kenjiArai 0:d4960fcea8ff 580 ready last instead of the actual ready list. */
kenjiArai 0:d4960fcea8ff 581 prvUnlockQueue( pxQueue );
kenjiArai 0:d4960fcea8ff 582
kenjiArai 0:d4960fcea8ff 583 /* Resuming the scheduler will move tasks from the pending
kenjiArai 0:d4960fcea8ff 584 ready list into the ready list - so it is feasible that this
kenjiArai 0:d4960fcea8ff 585 task is already in a ready list before it yields - in which
kenjiArai 0:d4960fcea8ff 586 case the yield will not cause a context switch unless there
kenjiArai 0:d4960fcea8ff 587 is also a higher priority task in the pending ready list. */
kenjiArai 0:d4960fcea8ff 588 if( !xTaskResumeAll() )
kenjiArai 0:d4960fcea8ff 589 {
kenjiArai 0:d4960fcea8ff 590 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 591 }
kenjiArai 0:d4960fcea8ff 592 }
kenjiArai 0:d4960fcea8ff 593 else
kenjiArai 0:d4960fcea8ff 594 {
kenjiArai 0:d4960fcea8ff 595 /* Try again. */
kenjiArai 0:d4960fcea8ff 596 prvUnlockQueue( pxQueue );
kenjiArai 0:d4960fcea8ff 597 ( void ) xTaskResumeAll();
kenjiArai 0:d4960fcea8ff 598 }
kenjiArai 0:d4960fcea8ff 599 }
kenjiArai 0:d4960fcea8ff 600 else
kenjiArai 0:d4960fcea8ff 601 {
kenjiArai 0:d4960fcea8ff 602 /* The timeout has expired. */
kenjiArai 0:d4960fcea8ff 603 prvUnlockQueue( pxQueue );
kenjiArai 0:d4960fcea8ff 604 ( void ) xTaskResumeAll();
kenjiArai 0:d4960fcea8ff 605
kenjiArai 0:d4960fcea8ff 606 /* Return to the original privilege level before exiting the
kenjiArai 0:d4960fcea8ff 607 function. */
kenjiArai 0:d4960fcea8ff 608 traceQUEUE_SEND_FAILED( pxQueue );
kenjiArai 0:d4960fcea8ff 609 return errQUEUE_FULL;
kenjiArai 0:d4960fcea8ff 610 }
kenjiArai 0:d4960fcea8ff 611 }
kenjiArai 0:d4960fcea8ff 612 }
kenjiArai 0:d4960fcea8ff 613 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 614
kenjiArai 0:d4960fcea8ff 615 #if configUSE_ALTERNATIVE_API == 1
kenjiArai 0:d4960fcea8ff 616
kenjiArai 0:d4960fcea8ff 617 signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
kenjiArai 0:d4960fcea8ff 618 {
kenjiArai 0:d4960fcea8ff 619 signed portBASE_TYPE xEntryTimeSet = pdFALSE;
kenjiArai 0:d4960fcea8ff 620 xTimeOutType xTimeOut;
kenjiArai 0:d4960fcea8ff 621
kenjiArai 0:d4960fcea8ff 622 for( ;; )
kenjiArai 0:d4960fcea8ff 623 {
kenjiArai 0:d4960fcea8ff 624 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 625 {
kenjiArai 0:d4960fcea8ff 626 /* Is there room on the queue now? To be running we must be
kenjiArai 0:d4960fcea8ff 627 the highest priority task wanting to access the queue. */
kenjiArai 0:d4960fcea8ff 628 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
kenjiArai 0:d4960fcea8ff 629 {
kenjiArai 0:d4960fcea8ff 630 traceQUEUE_SEND( pxQueue );
kenjiArai 0:d4960fcea8ff 631 prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
kenjiArai 0:d4960fcea8ff 632
kenjiArai 0:d4960fcea8ff 633 /* If there was a task waiting for data to arrive on the
kenjiArai 0:d4960fcea8ff 634 queue then unblock it now. */
kenjiArai 0:d4960fcea8ff 635 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
kenjiArai 0:d4960fcea8ff 636 {
kenjiArai 0:d4960fcea8ff 637 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
kenjiArai 0:d4960fcea8ff 638 {
kenjiArai 0:d4960fcea8ff 639 /* The unblocked task has a priority higher than
kenjiArai 0:d4960fcea8ff 640 our own so yield immediately. */
kenjiArai 0:d4960fcea8ff 641 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 642 }
kenjiArai 0:d4960fcea8ff 643 }
kenjiArai 0:d4960fcea8ff 644
kenjiArai 0:d4960fcea8ff 645 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 646 return pdPASS;
kenjiArai 0:d4960fcea8ff 647 }
kenjiArai 0:d4960fcea8ff 648 else
kenjiArai 0:d4960fcea8ff 649 {
kenjiArai 0:d4960fcea8ff 650 if( xTicksToWait == ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 651 {
kenjiArai 0:d4960fcea8ff 652 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 653 return errQUEUE_FULL;
kenjiArai 0:d4960fcea8ff 654 }
kenjiArai 0:d4960fcea8ff 655 else if( xEntryTimeSet == pdFALSE )
kenjiArai 0:d4960fcea8ff 656 {
kenjiArai 0:d4960fcea8ff 657 vTaskSetTimeOutState( &xTimeOut );
kenjiArai 0:d4960fcea8ff 658 xEntryTimeSet = pdTRUE;
kenjiArai 0:d4960fcea8ff 659 }
kenjiArai 0:d4960fcea8ff 660 }
kenjiArai 0:d4960fcea8ff 661 }
kenjiArai 0:d4960fcea8ff 662 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 663
kenjiArai 0:d4960fcea8ff 664 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 665 {
kenjiArai 0:d4960fcea8ff 666 if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
kenjiArai 0:d4960fcea8ff 667 {
kenjiArai 0:d4960fcea8ff 668 if( prvIsQueueFull( pxQueue ) )
kenjiArai 0:d4960fcea8ff 669 {
kenjiArai 0:d4960fcea8ff 670 traceBLOCKING_ON_QUEUE_SEND( pxQueue );
kenjiArai 0:d4960fcea8ff 671 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
kenjiArai 0:d4960fcea8ff 672 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 673 }
kenjiArai 0:d4960fcea8ff 674 }
kenjiArai 0:d4960fcea8ff 675 else
kenjiArai 0:d4960fcea8ff 676 {
kenjiArai 0:d4960fcea8ff 677 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 678 traceQUEUE_SEND_FAILED( pxQueue );
kenjiArai 0:d4960fcea8ff 679 return errQUEUE_FULL;
kenjiArai 0:d4960fcea8ff 680 }
kenjiArai 0:d4960fcea8ff 681 }
kenjiArai 0:d4960fcea8ff 682 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 683 }
kenjiArai 0:d4960fcea8ff 684 }
kenjiArai 0:d4960fcea8ff 685
kenjiArai 0:d4960fcea8ff 686 #endif /* configUSE_ALTERNATIVE_API */
kenjiArai 0:d4960fcea8ff 687 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 688
kenjiArai 0:d4960fcea8ff 689 #if configUSE_ALTERNATIVE_API == 1
kenjiArai 0:d4960fcea8ff 690
kenjiArai 0:d4960fcea8ff 691 signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
kenjiArai 0:d4960fcea8ff 692 {
kenjiArai 0:d4960fcea8ff 693 signed portBASE_TYPE xEntryTimeSet = pdFALSE;
kenjiArai 0:d4960fcea8ff 694 xTimeOutType xTimeOut;
kenjiArai 0:d4960fcea8ff 695 signed char *pcOriginalReadPosition;
kenjiArai 0:d4960fcea8ff 696
kenjiArai 0:d4960fcea8ff 697 for( ;; )
kenjiArai 0:d4960fcea8ff 698 {
kenjiArai 0:d4960fcea8ff 699 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 700 {
kenjiArai 0:d4960fcea8ff 701 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 702 {
kenjiArai 0:d4960fcea8ff 703 /* Remember our read position in case we are just peeking. */
kenjiArai 0:d4960fcea8ff 704 pcOriginalReadPosition = pxQueue->pcReadFrom;
kenjiArai 0:d4960fcea8ff 705
kenjiArai 0:d4960fcea8ff 706 prvCopyDataFromQueue( pxQueue, pvBuffer );
kenjiArai 0:d4960fcea8ff 707
kenjiArai 0:d4960fcea8ff 708 if( xJustPeeking == pdFALSE )
kenjiArai 0:d4960fcea8ff 709 {
kenjiArai 0:d4960fcea8ff 710 traceQUEUE_RECEIVE( pxQueue );
kenjiArai 0:d4960fcea8ff 711
kenjiArai 0:d4960fcea8ff 712 /* We are actually removing data. */
kenjiArai 0:d4960fcea8ff 713 --( pxQueue->uxMessagesWaiting );
kenjiArai 0:d4960fcea8ff 714
kenjiArai 0:d4960fcea8ff 715 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 716 {
kenjiArai 0:d4960fcea8ff 717 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
kenjiArai 0:d4960fcea8ff 718 {
kenjiArai 0:d4960fcea8ff 719 /* Record the information required to implement
kenjiArai 0:d4960fcea8ff 720 priority inheritance should it become necessary. */
kenjiArai 0:d4960fcea8ff 721 pxQueue->pxMutexHolder = xTaskGetCurrentTaskHandle();
kenjiArai 0:d4960fcea8ff 722 }
kenjiArai 0:d4960fcea8ff 723 }
kenjiArai 0:d4960fcea8ff 724 #endif
kenjiArai 0:d4960fcea8ff 725
kenjiArai 0:d4960fcea8ff 726 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
kenjiArai 0:d4960fcea8ff 727 {
kenjiArai 0:d4960fcea8ff 728 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
kenjiArai 0:d4960fcea8ff 729 {
kenjiArai 0:d4960fcea8ff 730 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 731 }
kenjiArai 0:d4960fcea8ff 732 }
kenjiArai 0:d4960fcea8ff 733 }
kenjiArai 0:d4960fcea8ff 734 else
kenjiArai 0:d4960fcea8ff 735 {
kenjiArai 0:d4960fcea8ff 736 traceQUEUE_PEEK( pxQueue );
kenjiArai 0:d4960fcea8ff 737
kenjiArai 0:d4960fcea8ff 738 /* We are not removing the data, so reset our read
kenjiArai 0:d4960fcea8ff 739 pointer. */
kenjiArai 0:d4960fcea8ff 740 pxQueue->pcReadFrom = pcOriginalReadPosition;
kenjiArai 0:d4960fcea8ff 741
kenjiArai 0:d4960fcea8ff 742 /* The data is being left in the queue, so see if there are
kenjiArai 0:d4960fcea8ff 743 any other tasks waiting for the data. */
kenjiArai 0:d4960fcea8ff 744 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
kenjiArai 0:d4960fcea8ff 745 {
kenjiArai 0:d4960fcea8ff 746 /* Tasks that are removed from the event list will get added to
kenjiArai 0:d4960fcea8ff 747 the pending ready list as the scheduler is still suspended. */
kenjiArai 0:d4960fcea8ff 748 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 749 {
kenjiArai 0:d4960fcea8ff 750 /* The task waiting has a higher priority than this task. */
kenjiArai 0:d4960fcea8ff 751 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 752 }
kenjiArai 0:d4960fcea8ff 753 }
kenjiArai 0:d4960fcea8ff 754
kenjiArai 0:d4960fcea8ff 755 }
kenjiArai 0:d4960fcea8ff 756
kenjiArai 0:d4960fcea8ff 757 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 758 return pdPASS;
kenjiArai 0:d4960fcea8ff 759 }
kenjiArai 0:d4960fcea8ff 760 else
kenjiArai 0:d4960fcea8ff 761 {
kenjiArai 0:d4960fcea8ff 762 if( xTicksToWait == ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 763 {
kenjiArai 0:d4960fcea8ff 764 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 765 traceQUEUE_RECEIVE_FAILED( pxQueue );
kenjiArai 0:d4960fcea8ff 766 return errQUEUE_EMPTY;
kenjiArai 0:d4960fcea8ff 767 }
kenjiArai 0:d4960fcea8ff 768 else if( xEntryTimeSet == pdFALSE )
kenjiArai 0:d4960fcea8ff 769 {
kenjiArai 0:d4960fcea8ff 770 vTaskSetTimeOutState( &xTimeOut );
kenjiArai 0:d4960fcea8ff 771 xEntryTimeSet = pdTRUE;
kenjiArai 0:d4960fcea8ff 772 }
kenjiArai 0:d4960fcea8ff 773 }
kenjiArai 0:d4960fcea8ff 774 }
kenjiArai 0:d4960fcea8ff 775 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 776
kenjiArai 0:d4960fcea8ff 777 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 778 {
kenjiArai 0:d4960fcea8ff 779 if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
kenjiArai 0:d4960fcea8ff 780 {
kenjiArai 0:d4960fcea8ff 781 if( prvIsQueueEmpty( pxQueue ) )
kenjiArai 0:d4960fcea8ff 782 {
kenjiArai 0:d4960fcea8ff 783 traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
kenjiArai 0:d4960fcea8ff 784
kenjiArai 0:d4960fcea8ff 785 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 786 {
kenjiArai 0:d4960fcea8ff 787 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
kenjiArai 0:d4960fcea8ff 788 {
kenjiArai 0:d4960fcea8ff 789 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 790 vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
kenjiArai 0:d4960fcea8ff 791 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 792 }
kenjiArai 0:d4960fcea8ff 793 }
kenjiArai 0:d4960fcea8ff 794 #endif
kenjiArai 0:d4960fcea8ff 795
kenjiArai 0:d4960fcea8ff 796 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
kenjiArai 0:d4960fcea8ff 797 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 798 }
kenjiArai 0:d4960fcea8ff 799 }
kenjiArai 0:d4960fcea8ff 800 else
kenjiArai 0:d4960fcea8ff 801 {
kenjiArai 0:d4960fcea8ff 802 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 803 traceQUEUE_RECEIVE_FAILED( pxQueue );
kenjiArai 0:d4960fcea8ff 804 return errQUEUE_EMPTY;
kenjiArai 0:d4960fcea8ff 805 }
kenjiArai 0:d4960fcea8ff 806 }
kenjiArai 0:d4960fcea8ff 807 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 808 }
kenjiArai 0:d4960fcea8ff 809 }
kenjiArai 0:d4960fcea8ff 810
kenjiArai 0:d4960fcea8ff 811
kenjiArai 0:d4960fcea8ff 812 #endif /* configUSE_ALTERNATIVE_API */
kenjiArai 0:d4960fcea8ff 813 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 814
kenjiArai 0:d4960fcea8ff 815 // Modified by Kenji Arai / JH1PJL, October 30th,2010
kenjiArai 0:d4960fcea8ff 816 // move to port_asm.c
kenjiArai 0:d4960fcea8ff 817 #if 0
kenjiArai 0:d4960fcea8ff 818 signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition )
kenjiArai 0:d4960fcea8ff 819 {
kenjiArai 0:d4960fcea8ff 820 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 821 unsigned portBASE_TYPE uxSavedInterruptStatus;
kenjiArai 0:d4960fcea8ff 822
kenjiArai 0:d4960fcea8ff 823 /* Similar to xQueueGenericSend, except we don't block if there is no room
kenjiArai 0:d4960fcea8ff 824 in the queue. Also we don't directly wake a task that was blocked on a
kenjiArai 0:d4960fcea8ff 825 queue read, instead we return a flag to say whether a context switch is
kenjiArai 0:d4960fcea8ff 826 required or not (i.e. has a task with a higher priority than us been woken
kenjiArai 0:d4960fcea8ff 827 by this post). */
kenjiArai 0:d4960fcea8ff 828 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
kenjiArai 0:d4960fcea8ff 829 {
kenjiArai 0:d4960fcea8ff 830 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
kenjiArai 0:d4960fcea8ff 831 {
kenjiArai 0:d4960fcea8ff 832 traceQUEUE_SEND_FROM_ISR( pxQueue );
kenjiArai 0:d4960fcea8ff 833
kenjiArai 0:d4960fcea8ff 834 prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
kenjiArai 0:d4960fcea8ff 835
kenjiArai 0:d4960fcea8ff 836 /* If the queue is locked we do not alter the event list. This will
kenjiArai 0:d4960fcea8ff 837 be done when the queue is unlocked later. */
kenjiArai 0:d4960fcea8ff 838 if( pxQueue->xTxLock == queueUNLOCKED )
kenjiArai 0:d4960fcea8ff 839 {
kenjiArai 0:d4960fcea8ff 840 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
kenjiArai 0:d4960fcea8ff 841 {
kenjiArai 0:d4960fcea8ff 842 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 843 {
kenjiArai 0:d4960fcea8ff 844 /* The task waiting has a higher priority so record that a
kenjiArai 0:d4960fcea8ff 845 context switch is required. */
kenjiArai 0:d4960fcea8ff 846 *pxHigherPriorityTaskWoken = pdTRUE;
kenjiArai 0:d4960fcea8ff 847 }
kenjiArai 0:d4960fcea8ff 848 }
kenjiArai 0:d4960fcea8ff 849 }
kenjiArai 0:d4960fcea8ff 850 else
kenjiArai 0:d4960fcea8ff 851 {
kenjiArai 0:d4960fcea8ff 852 /* Increment the lock count so the task that unlocks the queue
kenjiArai 0:d4960fcea8ff 853 knows that data was posted while it was locked. */
kenjiArai 0:d4960fcea8ff 854 ++( pxQueue->xTxLock );
kenjiArai 0:d4960fcea8ff 855 }
kenjiArai 0:d4960fcea8ff 856
kenjiArai 0:d4960fcea8ff 857 xReturn = pdPASS;
kenjiArai 0:d4960fcea8ff 858 }
kenjiArai 0:d4960fcea8ff 859 else
kenjiArai 0:d4960fcea8ff 860 {
kenjiArai 0:d4960fcea8ff 861 traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );
kenjiArai 0:d4960fcea8ff 862 xReturn = errQUEUE_FULL;
kenjiArai 0:d4960fcea8ff 863 }
kenjiArai 0:d4960fcea8ff 864 }
kenjiArai 0:d4960fcea8ff 865 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
kenjiArai 0:d4960fcea8ff 866
kenjiArai 0:d4960fcea8ff 867 return xReturn;
kenjiArai 0:d4960fcea8ff 868 }
kenjiArai 0:d4960fcea8ff 869 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 870 #endif
kenjiArai 0:d4960fcea8ff 871
kenjiArai 0:d4960fcea8ff 872 signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
kenjiArai 0:d4960fcea8ff 873 {
kenjiArai 0:d4960fcea8ff 874 signed portBASE_TYPE xEntryTimeSet = pdFALSE;
kenjiArai 0:d4960fcea8ff 875 xTimeOutType xTimeOut;
kenjiArai 0:d4960fcea8ff 876 signed char *pcOriginalReadPosition;
kenjiArai 0:d4960fcea8ff 877
kenjiArai 0:d4960fcea8ff 878 /* This function relaxes the coding standard somewhat to allow return
kenjiArai 0:d4960fcea8ff 879 statements within the function itself. This is done in the interest
kenjiArai 0:d4960fcea8ff 880 of execution time efficiency. */
kenjiArai 0:d4960fcea8ff 881
kenjiArai 0:d4960fcea8ff 882 for( ;; )
kenjiArai 0:d4960fcea8ff 883 {
kenjiArai 0:d4960fcea8ff 884 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 885 {
kenjiArai 0:d4960fcea8ff 886 /* Is there data in the queue now? To be running we must be
kenjiArai 0:d4960fcea8ff 887 the highest priority task wanting to access the queue. */
kenjiArai 0:d4960fcea8ff 888 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 889 {
kenjiArai 0:d4960fcea8ff 890 /* Remember our read position in case we are just peeking. */
kenjiArai 0:d4960fcea8ff 891 pcOriginalReadPosition = pxQueue->pcReadFrom;
kenjiArai 0:d4960fcea8ff 892
kenjiArai 0:d4960fcea8ff 893 prvCopyDataFromQueue( pxQueue, pvBuffer );
kenjiArai 0:d4960fcea8ff 894
kenjiArai 0:d4960fcea8ff 895 if( xJustPeeking == pdFALSE )
kenjiArai 0:d4960fcea8ff 896 {
kenjiArai 0:d4960fcea8ff 897 traceQUEUE_RECEIVE( pxQueue );
kenjiArai 0:d4960fcea8ff 898
kenjiArai 0:d4960fcea8ff 899 /* We are actually removing data. */
kenjiArai 0:d4960fcea8ff 900 --( pxQueue->uxMessagesWaiting );
kenjiArai 0:d4960fcea8ff 901
kenjiArai 0:d4960fcea8ff 902 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 903 {
kenjiArai 0:d4960fcea8ff 904 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
kenjiArai 0:d4960fcea8ff 905 {
kenjiArai 0:d4960fcea8ff 906 /* Record the information required to implement
kenjiArai 0:d4960fcea8ff 907 priority inheritance should it become necessary. */
kenjiArai 0:d4960fcea8ff 908 // Modified by Kenji Arai / JH1PJL, October 31st,2010
kenjiArai 0:d4960fcea8ff 909 pxQueue->pxMutexHolder = (signed char *) xTaskGetCurrentTaskHandle();
kenjiArai 0:d4960fcea8ff 910 }
kenjiArai 0:d4960fcea8ff 911 }
kenjiArai 0:d4960fcea8ff 912 #endif
kenjiArai 0:d4960fcea8ff 913
kenjiArai 0:d4960fcea8ff 914 if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
kenjiArai 0:d4960fcea8ff 915 {
kenjiArai 0:d4960fcea8ff 916 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
kenjiArai 0:d4960fcea8ff 917 {
kenjiArai 0:d4960fcea8ff 918 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 919 }
kenjiArai 0:d4960fcea8ff 920 }
kenjiArai 0:d4960fcea8ff 921 }
kenjiArai 0:d4960fcea8ff 922 else
kenjiArai 0:d4960fcea8ff 923 {
kenjiArai 0:d4960fcea8ff 924 traceQUEUE_PEEK( pxQueue );
kenjiArai 0:d4960fcea8ff 925
kenjiArai 0:d4960fcea8ff 926 /* We are not removing the data, so reset our read
kenjiArai 0:d4960fcea8ff 927 pointer. */
kenjiArai 0:d4960fcea8ff 928 pxQueue->pcReadFrom = pcOriginalReadPosition;
kenjiArai 0:d4960fcea8ff 929
kenjiArai 0:d4960fcea8ff 930 /* The data is being left in the queue, so see if there are
kenjiArai 0:d4960fcea8ff 931 any other tasks waiting for the data. */
kenjiArai 0:d4960fcea8ff 932 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
kenjiArai 0:d4960fcea8ff 933 {
kenjiArai 0:d4960fcea8ff 934 /* Tasks that are removed from the event list will get added to
kenjiArai 0:d4960fcea8ff 935 the pending ready list as the scheduler is still suspended. */
kenjiArai 0:d4960fcea8ff 936 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 937 {
kenjiArai 0:d4960fcea8ff 938 /* The task waiting has a higher priority than this task. */
kenjiArai 0:d4960fcea8ff 939 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 940 }
kenjiArai 0:d4960fcea8ff 941 }
kenjiArai 0:d4960fcea8ff 942
kenjiArai 0:d4960fcea8ff 943 }
kenjiArai 0:d4960fcea8ff 944
kenjiArai 0:d4960fcea8ff 945 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 946 return pdPASS;
kenjiArai 0:d4960fcea8ff 947 }
kenjiArai 0:d4960fcea8ff 948 else
kenjiArai 0:d4960fcea8ff 949 {
kenjiArai 0:d4960fcea8ff 950 if( xTicksToWait == ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 951 {
kenjiArai 0:d4960fcea8ff 952 /* The queue was empty and no block time is specified (or
kenjiArai 0:d4960fcea8ff 953 the block time has expired) so leave now. */
kenjiArai 0:d4960fcea8ff 954 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 955 traceQUEUE_RECEIVE_FAILED( pxQueue );
kenjiArai 0:d4960fcea8ff 956 return errQUEUE_EMPTY;
kenjiArai 0:d4960fcea8ff 957 }
kenjiArai 0:d4960fcea8ff 958 else if( xEntryTimeSet == pdFALSE )
kenjiArai 0:d4960fcea8ff 959 {
kenjiArai 0:d4960fcea8ff 960 /* The queue was empty and a block time was specified so
kenjiArai 0:d4960fcea8ff 961 configure the timeout structure. */
kenjiArai 0:d4960fcea8ff 962 vTaskSetTimeOutState( &xTimeOut );
kenjiArai 0:d4960fcea8ff 963 xEntryTimeSet = pdTRUE;
kenjiArai 0:d4960fcea8ff 964 }
kenjiArai 0:d4960fcea8ff 965 }
kenjiArai 0:d4960fcea8ff 966 }
kenjiArai 0:d4960fcea8ff 967 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 968
kenjiArai 0:d4960fcea8ff 969 /* Interrupts and other tasks can send to and receive from the queue
kenjiArai 0:d4960fcea8ff 970 now the critical section has been exited. */
kenjiArai 0:d4960fcea8ff 971
kenjiArai 0:d4960fcea8ff 972 vTaskSuspendAll();
kenjiArai 0:d4960fcea8ff 973 prvLockQueue( pxQueue );
kenjiArai 0:d4960fcea8ff 974
kenjiArai 0:d4960fcea8ff 975 /* Update the timeout state to see if it has expired yet. */
kenjiArai 0:d4960fcea8ff 976 if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
kenjiArai 0:d4960fcea8ff 977 {
kenjiArai 0:d4960fcea8ff 978 if( prvIsQueueEmpty( pxQueue ) )
kenjiArai 0:d4960fcea8ff 979 {
kenjiArai 0:d4960fcea8ff 980 traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
kenjiArai 0:d4960fcea8ff 981
kenjiArai 0:d4960fcea8ff 982 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 983 {
kenjiArai 0:d4960fcea8ff 984 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
kenjiArai 0:d4960fcea8ff 985 {
kenjiArai 0:d4960fcea8ff 986 portENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 987 {
kenjiArai 0:d4960fcea8ff 988 // Modified by Kenji Arai / JH1PJL, October 31st,2010
kenjiArai 0:d4960fcea8ff 989 //vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
kenjiArai 0:d4960fcea8ff 990 vTaskPriorityInherit( ( xTaskHandle * ) pxQueue->pxMutexHolder );
kenjiArai 0:d4960fcea8ff 991 }
kenjiArai 0:d4960fcea8ff 992 portEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 993 }
kenjiArai 0:d4960fcea8ff 994 }
kenjiArai 0:d4960fcea8ff 995 #endif
kenjiArai 0:d4960fcea8ff 996
kenjiArai 0:d4960fcea8ff 997 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
kenjiArai 0:d4960fcea8ff 998 prvUnlockQueue( pxQueue );
kenjiArai 0:d4960fcea8ff 999 if( !xTaskResumeAll() )
kenjiArai 0:d4960fcea8ff 1000 {
kenjiArai 0:d4960fcea8ff 1001 portYIELD_WITHIN_API();
kenjiArai 0:d4960fcea8ff 1002 }
kenjiArai 0:d4960fcea8ff 1003 }
kenjiArai 0:d4960fcea8ff 1004 else
kenjiArai 0:d4960fcea8ff 1005 {
kenjiArai 0:d4960fcea8ff 1006 /* Try again. */
kenjiArai 0:d4960fcea8ff 1007 prvUnlockQueue( pxQueue );
kenjiArai 0:d4960fcea8ff 1008 ( void ) xTaskResumeAll();
kenjiArai 0:d4960fcea8ff 1009 }
kenjiArai 0:d4960fcea8ff 1010 }
kenjiArai 0:d4960fcea8ff 1011 else
kenjiArai 0:d4960fcea8ff 1012 {
kenjiArai 0:d4960fcea8ff 1013 prvUnlockQueue( pxQueue );
kenjiArai 0:d4960fcea8ff 1014 ( void ) xTaskResumeAll();
kenjiArai 0:d4960fcea8ff 1015 traceQUEUE_RECEIVE_FAILED( pxQueue );
kenjiArai 0:d4960fcea8ff 1016 return errQUEUE_EMPTY;
kenjiArai 0:d4960fcea8ff 1017 }
kenjiArai 0:d4960fcea8ff 1018 }
kenjiArai 0:d4960fcea8ff 1019 }
kenjiArai 0:d4960fcea8ff 1020 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1021
kenjiArai 0:d4960fcea8ff 1022 // Modified by Kenji Arai / JH1PJL, October 30th,2010
kenjiArai 0:d4960fcea8ff 1023 // move to port_asm.c
kenjiArai 0:d4960fcea8ff 1024 #if 0
kenjiArai 0:d4960fcea8ff 1025 signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken )
kenjiArai 0:d4960fcea8ff 1026 {
kenjiArai 0:d4960fcea8ff 1027 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1028 unsigned portBASE_TYPE uxSavedInterruptStatus;
kenjiArai 0:d4960fcea8ff 1029
kenjiArai 0:d4960fcea8ff 1030 uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
kenjiArai 0:d4960fcea8ff 1031 {
kenjiArai 0:d4960fcea8ff 1032 /* We cannot block from an ISR, so check there is data available. */
kenjiArai 0:d4960fcea8ff 1033 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 1034 {
kenjiArai 0:d4960fcea8ff 1035 traceQUEUE_RECEIVE_FROM_ISR( pxQueue );
kenjiArai 0:d4960fcea8ff 1036
kenjiArai 0:d4960fcea8ff 1037 prvCopyDataFromQueue( pxQueue, pvBuffer );
kenjiArai 0:d4960fcea8ff 1038 --( pxQueue->uxMessagesWaiting );
kenjiArai 0:d4960fcea8ff 1039
kenjiArai 0:d4960fcea8ff 1040 /* If the queue is locked we will not modify the event list. Instead
kenjiArai 0:d4960fcea8ff 1041 we update the lock count so the task that unlocks the queue will know
kenjiArai 0:d4960fcea8ff 1042 that an ISR has removed data while the queue was locked. */
kenjiArai 0:d4960fcea8ff 1043 if( pxQueue->xRxLock == queueUNLOCKED )
kenjiArai 0:d4960fcea8ff 1044 {
kenjiArai 0:d4960fcea8ff 1045 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
kenjiArai 0:d4960fcea8ff 1046 {
kenjiArai 0:d4960fcea8ff 1047 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 1048 {
kenjiArai 0:d4960fcea8ff 1049 /* The task waiting has a higher priority than us so
kenjiArai 0:d4960fcea8ff 1050 force a context switch. */
kenjiArai 0:d4960fcea8ff 1051 *pxTaskWoken = pdTRUE;
kenjiArai 0:d4960fcea8ff 1052 }
kenjiArai 0:d4960fcea8ff 1053 }
kenjiArai 0:d4960fcea8ff 1054 }
kenjiArai 0:d4960fcea8ff 1055 else
kenjiArai 0:d4960fcea8ff 1056 {
kenjiArai 0:d4960fcea8ff 1057 /* Increment the lock count so the task that unlocks the queue
kenjiArai 0:d4960fcea8ff 1058 knows that data was removed while it was locked. */
kenjiArai 0:d4960fcea8ff 1059 ++( pxQueue->xRxLock );
kenjiArai 0:d4960fcea8ff 1060 }
kenjiArai 0:d4960fcea8ff 1061
kenjiArai 0:d4960fcea8ff 1062 xReturn = pdPASS;
kenjiArai 0:d4960fcea8ff 1063 }
kenjiArai 0:d4960fcea8ff 1064 else
kenjiArai 0:d4960fcea8ff 1065 {
kenjiArai 0:d4960fcea8ff 1066 xReturn = pdFAIL;
kenjiArai 0:d4960fcea8ff 1067 traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );
kenjiArai 0:d4960fcea8ff 1068 }
kenjiArai 0:d4960fcea8ff 1069 }
kenjiArai 0:d4960fcea8ff 1070 portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
kenjiArai 0:d4960fcea8ff 1071
kenjiArai 0:d4960fcea8ff 1072 return xReturn;
kenjiArai 0:d4960fcea8ff 1073 }
kenjiArai 0:d4960fcea8ff 1074 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1075 #endif
kenjiArai 0:d4960fcea8ff 1076
kenjiArai 0:d4960fcea8ff 1077 unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue )
kenjiArai 0:d4960fcea8ff 1078 {
kenjiArai 0:d4960fcea8ff 1079 unsigned portBASE_TYPE uxReturn;
kenjiArai 0:d4960fcea8ff 1080
kenjiArai 0:d4960fcea8ff 1081 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1082 uxReturn = pxQueue->uxMessagesWaiting;
kenjiArai 0:d4960fcea8ff 1083 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1084
kenjiArai 0:d4960fcea8ff 1085 return uxReturn;
kenjiArai 0:d4960fcea8ff 1086 }
kenjiArai 0:d4960fcea8ff 1087 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1088
kenjiArai 0:d4960fcea8ff 1089 unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue )
kenjiArai 0:d4960fcea8ff 1090 {
kenjiArai 0:d4960fcea8ff 1091 unsigned portBASE_TYPE uxReturn;
kenjiArai 0:d4960fcea8ff 1092
kenjiArai 0:d4960fcea8ff 1093 uxReturn = pxQueue->uxMessagesWaiting;
kenjiArai 0:d4960fcea8ff 1094
kenjiArai 0:d4960fcea8ff 1095 return uxReturn;
kenjiArai 0:d4960fcea8ff 1096 }
kenjiArai 0:d4960fcea8ff 1097 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1098
kenjiArai 0:d4960fcea8ff 1099 void vQueueDelete( xQueueHandle pxQueue )
kenjiArai 0:d4960fcea8ff 1100 {
kenjiArai 0:d4960fcea8ff 1101 traceQUEUE_DELETE( pxQueue );
kenjiArai 0:d4960fcea8ff 1102 vQueueUnregisterQueue( pxQueue );
kenjiArai 0:d4960fcea8ff 1103 vPortFree( pxQueue->pcHead );
kenjiArai 0:d4960fcea8ff 1104 vPortFree( pxQueue );
kenjiArai 0:d4960fcea8ff 1105 }
kenjiArai 0:d4960fcea8ff 1106 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1107
kenjiArai 0:d4960fcea8ff 1108 // Modified by Kenji Arai / JH1PJL, October 31st,2010
kenjiArai 0:d4960fcea8ff 1109 #if 0
kenjiArai 0:d4960fcea8ff 1110 static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )
kenjiArai 0:d4960fcea8ff 1111 #else
kenjiArai 0:d4960fcea8ff 1112 void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )
kenjiArai 0:d4960fcea8ff 1113 #endif
kenjiArai 0:d4960fcea8ff 1114 {
kenjiArai 0:d4960fcea8ff 1115 if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 1116 {
kenjiArai 0:d4960fcea8ff 1117 #if ( configUSE_MUTEXES == 1 )
kenjiArai 0:d4960fcea8ff 1118 {
kenjiArai 0:d4960fcea8ff 1119 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
kenjiArai 0:d4960fcea8ff 1120 {
kenjiArai 0:d4960fcea8ff 1121 /* The mutex is no longer being held. */
kenjiArai 0:d4960fcea8ff 1122 // Modified by Kenji Arai / JH1PJL, October 31st,2010
kenjiArai 0:d4960fcea8ff 1123 //vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );
kenjiArai 0:d4960fcea8ff 1124 vTaskPriorityDisinherit( ( xTaskHandle * ) pxQueue->pxMutexHolder );
kenjiArai 0:d4960fcea8ff 1125 pxQueue->pxMutexHolder = NULL;
kenjiArai 0:d4960fcea8ff 1126 }
kenjiArai 0:d4960fcea8ff 1127 }
kenjiArai 0:d4960fcea8ff 1128 #endif
kenjiArai 0:d4960fcea8ff 1129 }
kenjiArai 0:d4960fcea8ff 1130 else if( xPosition == queueSEND_TO_BACK )
kenjiArai 0:d4960fcea8ff 1131 {
kenjiArai 0:d4960fcea8ff 1132 memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
kenjiArai 0:d4960fcea8ff 1133 pxQueue->pcWriteTo += pxQueue->uxItemSize;
kenjiArai 0:d4960fcea8ff 1134 if( pxQueue->pcWriteTo >= pxQueue->pcTail )
kenjiArai 0:d4960fcea8ff 1135 {
kenjiArai 0:d4960fcea8ff 1136 pxQueue->pcWriteTo = pxQueue->pcHead;
kenjiArai 0:d4960fcea8ff 1137 }
kenjiArai 0:d4960fcea8ff 1138 }
kenjiArai 0:d4960fcea8ff 1139 else
kenjiArai 0:d4960fcea8ff 1140 {
kenjiArai 0:d4960fcea8ff 1141 memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize );
kenjiArai 0:d4960fcea8ff 1142 pxQueue->pcReadFrom -= pxQueue->uxItemSize;
kenjiArai 0:d4960fcea8ff 1143 if( pxQueue->pcReadFrom < pxQueue->pcHead )
kenjiArai 0:d4960fcea8ff 1144 {
kenjiArai 0:d4960fcea8ff 1145 pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
kenjiArai 0:d4960fcea8ff 1146 }
kenjiArai 0:d4960fcea8ff 1147 }
kenjiArai 0:d4960fcea8ff 1148
kenjiArai 0:d4960fcea8ff 1149 ++( pxQueue->uxMessagesWaiting );
kenjiArai 0:d4960fcea8ff 1150 }
kenjiArai 0:d4960fcea8ff 1151 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1152
kenjiArai 0:d4960fcea8ff 1153 // Modified by Kenji Arai / JH1PJL, October 31st,2010
kenjiArai 0:d4960fcea8ff 1154 #if 0
kenjiArai 0:d4960fcea8ff 1155 static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
kenjiArai 0:d4960fcea8ff 1156 #else
kenjiArai 0:d4960fcea8ff 1157 void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer )
kenjiArai 0:d4960fcea8ff 1158 #endif
kenjiArai 0:d4960fcea8ff 1159 {
kenjiArai 0:d4960fcea8ff 1160 if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
kenjiArai 0:d4960fcea8ff 1161 {
kenjiArai 0:d4960fcea8ff 1162 pxQueue->pcReadFrom += pxQueue->uxItemSize;
kenjiArai 0:d4960fcea8ff 1163 if( pxQueue->pcReadFrom >= pxQueue->pcTail )
kenjiArai 0:d4960fcea8ff 1164 {
kenjiArai 0:d4960fcea8ff 1165 pxQueue->pcReadFrom = pxQueue->pcHead;
kenjiArai 0:d4960fcea8ff 1166 }
kenjiArai 0:d4960fcea8ff 1167 memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
kenjiArai 0:d4960fcea8ff 1168 }
kenjiArai 0:d4960fcea8ff 1169 }
kenjiArai 0:d4960fcea8ff 1170 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1171
kenjiArai 0:d4960fcea8ff 1172 // Modified by Kenji Arai / JH1PJL, October 31st,2010
kenjiArai 0:d4960fcea8ff 1173 #if 0
kenjiArai 0:d4960fcea8ff 1174 static void prvUnlockQueue( xQueueHandle pxQueue )
kenjiArai 0:d4960fcea8ff 1175 #else
kenjiArai 0:d4960fcea8ff 1176 void prvUnlockQueue( xQueueHandle pxQueue )
kenjiArai 0:d4960fcea8ff 1177 #endif
kenjiArai 0:d4960fcea8ff 1178 {
kenjiArai 0:d4960fcea8ff 1179 /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
kenjiArai 0:d4960fcea8ff 1180
kenjiArai 0:d4960fcea8ff 1181 /* The lock counts contains the number of extra data items placed or
kenjiArai 0:d4960fcea8ff 1182 removed from the queue while the queue was locked. When a queue is
kenjiArai 0:d4960fcea8ff 1183 locked items can be added or removed, but the event lists cannot be
kenjiArai 0:d4960fcea8ff 1184 updated. */
kenjiArai 0:d4960fcea8ff 1185 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1186 {
kenjiArai 0:d4960fcea8ff 1187 /* See if data was added to the queue while it was locked. */
kenjiArai 0:d4960fcea8ff 1188 while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )
kenjiArai 0:d4960fcea8ff 1189 {
kenjiArai 0:d4960fcea8ff 1190 /* Data was posted while the queue was locked. Are any tasks
kenjiArai 0:d4960fcea8ff 1191 blocked waiting for data to become available? */
kenjiArai 0:d4960fcea8ff 1192 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
kenjiArai 0:d4960fcea8ff 1193 {
kenjiArai 0:d4960fcea8ff 1194 /* Tasks that are removed from the event list will get added to
kenjiArai 0:d4960fcea8ff 1195 the pending ready list as the scheduler is still suspended. */
kenjiArai 0:d4960fcea8ff 1196 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 1197 {
kenjiArai 0:d4960fcea8ff 1198 /* The task waiting has a higher priority so record that a
kenjiArai 0:d4960fcea8ff 1199 context switch is required. */
kenjiArai 0:d4960fcea8ff 1200 vTaskMissedYield();
kenjiArai 0:d4960fcea8ff 1201 }
kenjiArai 0:d4960fcea8ff 1202
kenjiArai 0:d4960fcea8ff 1203 --( pxQueue->xTxLock );
kenjiArai 0:d4960fcea8ff 1204 }
kenjiArai 0:d4960fcea8ff 1205 else
kenjiArai 0:d4960fcea8ff 1206 {
kenjiArai 0:d4960fcea8ff 1207 break;
kenjiArai 0:d4960fcea8ff 1208 }
kenjiArai 0:d4960fcea8ff 1209 }
kenjiArai 0:d4960fcea8ff 1210
kenjiArai 0:d4960fcea8ff 1211 pxQueue->xTxLock = queueUNLOCKED;
kenjiArai 0:d4960fcea8ff 1212 }
kenjiArai 0:d4960fcea8ff 1213 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1214
kenjiArai 0:d4960fcea8ff 1215 /* Do the same for the Rx lock. */
kenjiArai 0:d4960fcea8ff 1216 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1217 {
kenjiArai 0:d4960fcea8ff 1218 while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
kenjiArai 0:d4960fcea8ff 1219 {
kenjiArai 0:d4960fcea8ff 1220 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
kenjiArai 0:d4960fcea8ff 1221 {
kenjiArai 0:d4960fcea8ff 1222 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 1223 {
kenjiArai 0:d4960fcea8ff 1224 vTaskMissedYield();
kenjiArai 0:d4960fcea8ff 1225 }
kenjiArai 0:d4960fcea8ff 1226
kenjiArai 0:d4960fcea8ff 1227 --( pxQueue->xRxLock );
kenjiArai 0:d4960fcea8ff 1228 }
kenjiArai 0:d4960fcea8ff 1229 else
kenjiArai 0:d4960fcea8ff 1230 {
kenjiArai 0:d4960fcea8ff 1231 break;
kenjiArai 0:d4960fcea8ff 1232 }
kenjiArai 0:d4960fcea8ff 1233 }
kenjiArai 0:d4960fcea8ff 1234
kenjiArai 0:d4960fcea8ff 1235 pxQueue->xRxLock = queueUNLOCKED;
kenjiArai 0:d4960fcea8ff 1236 }
kenjiArai 0:d4960fcea8ff 1237 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1238 }
kenjiArai 0:d4960fcea8ff 1239 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1240
kenjiArai 0:d4960fcea8ff 1241 static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue )
kenjiArai 0:d4960fcea8ff 1242 {
kenjiArai 0:d4960fcea8ff 1243 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1244
kenjiArai 0:d4960fcea8ff 1245 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1246 xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
kenjiArai 0:d4960fcea8ff 1247 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1248
kenjiArai 0:d4960fcea8ff 1249 return xReturn;
kenjiArai 0:d4960fcea8ff 1250 }
kenjiArai 0:d4960fcea8ff 1251 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1252
kenjiArai 0:d4960fcea8ff 1253 signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle pxQueue )
kenjiArai 0:d4960fcea8ff 1254 {
kenjiArai 0:d4960fcea8ff 1255 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1256
kenjiArai 0:d4960fcea8ff 1257 xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
kenjiArai 0:d4960fcea8ff 1258
kenjiArai 0:d4960fcea8ff 1259 return xReturn;
kenjiArai 0:d4960fcea8ff 1260 }
kenjiArai 0:d4960fcea8ff 1261 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1262
kenjiArai 0:d4960fcea8ff 1263 static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue )
kenjiArai 0:d4960fcea8ff 1264 {
kenjiArai 0:d4960fcea8ff 1265 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1266
kenjiArai 0:d4960fcea8ff 1267 taskENTER_CRITICAL();
kenjiArai 0:d4960fcea8ff 1268 xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
kenjiArai 0:d4960fcea8ff 1269 taskEXIT_CRITICAL();
kenjiArai 0:d4960fcea8ff 1270
kenjiArai 0:d4960fcea8ff 1271 return xReturn;
kenjiArai 0:d4960fcea8ff 1272 }
kenjiArai 0:d4960fcea8ff 1273 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1274
kenjiArai 0:d4960fcea8ff 1275 signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue )
kenjiArai 0:d4960fcea8ff 1276 {
kenjiArai 0:d4960fcea8ff 1277 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1278
kenjiArai 0:d4960fcea8ff 1279 xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
kenjiArai 0:d4960fcea8ff 1280
kenjiArai 0:d4960fcea8ff 1281 return xReturn;
kenjiArai 0:d4960fcea8ff 1282 }
kenjiArai 0:d4960fcea8ff 1283 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1284
kenjiArai 0:d4960fcea8ff 1285 #if configUSE_CO_ROUTINES == 1
kenjiArai 0:d4960fcea8ff 1286 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
kenjiArai 0:d4960fcea8ff 1287 {
kenjiArai 0:d4960fcea8ff 1288 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1289
kenjiArai 0:d4960fcea8ff 1290 /* If the queue is already full we may have to block. A critical section
kenjiArai 0:d4960fcea8ff 1291 is required to prevent an interrupt removing something from the queue
kenjiArai 0:d4960fcea8ff 1292 between the check to see if the queue is full and blocking on the queue. */
kenjiArai 0:d4960fcea8ff 1293 portDISABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1294 {
kenjiArai 0:d4960fcea8ff 1295 if( prvIsQueueFull( pxQueue ) )
kenjiArai 0:d4960fcea8ff 1296 {
kenjiArai 0:d4960fcea8ff 1297 /* The queue is full - do we want to block or just leave without
kenjiArai 0:d4960fcea8ff 1298 posting? */
kenjiArai 0:d4960fcea8ff 1299 if( xTicksToWait > ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 1300 {
kenjiArai 0:d4960fcea8ff 1301 /* As this is called from a coroutine we cannot block directly, but
kenjiArai 0:d4960fcea8ff 1302 return indicating that we need to block. */
kenjiArai 0:d4960fcea8ff 1303 vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );
kenjiArai 0:d4960fcea8ff 1304 portENABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1305 return errQUEUE_BLOCKED;
kenjiArai 0:d4960fcea8ff 1306 }
kenjiArai 0:d4960fcea8ff 1307 else
kenjiArai 0:d4960fcea8ff 1308 {
kenjiArai 0:d4960fcea8ff 1309 portENABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1310 return errQUEUE_FULL;
kenjiArai 0:d4960fcea8ff 1311 }
kenjiArai 0:d4960fcea8ff 1312 }
kenjiArai 0:d4960fcea8ff 1313 }
kenjiArai 0:d4960fcea8ff 1314 portENABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1315
kenjiArai 0:d4960fcea8ff 1316 portNOP();
kenjiArai 0:d4960fcea8ff 1317
kenjiArai 0:d4960fcea8ff 1318 portDISABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1319 {
kenjiArai 0:d4960fcea8ff 1320 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
kenjiArai 0:d4960fcea8ff 1321 {
kenjiArai 0:d4960fcea8ff 1322 /* There is room in the queue, copy the data into the queue. */
kenjiArai 0:d4960fcea8ff 1323 prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
kenjiArai 0:d4960fcea8ff 1324 xReturn = pdPASS;
kenjiArai 0:d4960fcea8ff 1325
kenjiArai 0:d4960fcea8ff 1326 /* Were any co-routines waiting for data to become available? */
kenjiArai 0:d4960fcea8ff 1327 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
kenjiArai 0:d4960fcea8ff 1328 {
kenjiArai 0:d4960fcea8ff 1329 /* In this instance the co-routine could be placed directly
kenjiArai 0:d4960fcea8ff 1330 into the ready list as we are within a critical section.
kenjiArai 0:d4960fcea8ff 1331 Instead the same pending ready list mechanism is used as if
kenjiArai 0:d4960fcea8ff 1332 the event were caused from within an interrupt. */
kenjiArai 0:d4960fcea8ff 1333 if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 1334 {
kenjiArai 0:d4960fcea8ff 1335 /* The co-routine waiting has a higher priority so record
kenjiArai 0:d4960fcea8ff 1336 that a yield might be appropriate. */
kenjiArai 0:d4960fcea8ff 1337 xReturn = errQUEUE_YIELD;
kenjiArai 0:d4960fcea8ff 1338 }
kenjiArai 0:d4960fcea8ff 1339 }
kenjiArai 0:d4960fcea8ff 1340 }
kenjiArai 0:d4960fcea8ff 1341 else
kenjiArai 0:d4960fcea8ff 1342 {
kenjiArai 0:d4960fcea8ff 1343 xReturn = errQUEUE_FULL;
kenjiArai 0:d4960fcea8ff 1344 }
kenjiArai 0:d4960fcea8ff 1345 }
kenjiArai 0:d4960fcea8ff 1346 portENABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1347
kenjiArai 0:d4960fcea8ff 1348 return xReturn;
kenjiArai 0:d4960fcea8ff 1349 }
kenjiArai 0:d4960fcea8ff 1350 #endif
kenjiArai 0:d4960fcea8ff 1351 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1352
kenjiArai 0:d4960fcea8ff 1353 #if configUSE_CO_ROUTINES == 1
kenjiArai 0:d4960fcea8ff 1354 signed portBASE_TYPE xQueueCRReceive( xQueueHandle pxQueue, void *pvBuffer, portTickType xTicksToWait )
kenjiArai 0:d4960fcea8ff 1355 {
kenjiArai 0:d4960fcea8ff 1356 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1357
kenjiArai 0:d4960fcea8ff 1358 /* If the queue is already empty we may have to block. A critical section
kenjiArai 0:d4960fcea8ff 1359 is required to prevent an interrupt adding something to the queue
kenjiArai 0:d4960fcea8ff 1360 between the check to see if the queue is empty and blocking on the queue. */
kenjiArai 0:d4960fcea8ff 1361 portDISABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1362 {
kenjiArai 0:d4960fcea8ff 1363 if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 1364 {
kenjiArai 0:d4960fcea8ff 1365 /* There are no messages in the queue, do we want to block or just
kenjiArai 0:d4960fcea8ff 1366 leave with nothing? */
kenjiArai 0:d4960fcea8ff 1367 if( xTicksToWait > ( portTickType ) 0 )
kenjiArai 0:d4960fcea8ff 1368 {
kenjiArai 0:d4960fcea8ff 1369 /* As this is a co-routine we cannot block directly, but return
kenjiArai 0:d4960fcea8ff 1370 indicating that we need to block. */
kenjiArai 0:d4960fcea8ff 1371 vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );
kenjiArai 0:d4960fcea8ff 1372 portENABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1373 return errQUEUE_BLOCKED;
kenjiArai 0:d4960fcea8ff 1374 }
kenjiArai 0:d4960fcea8ff 1375 else
kenjiArai 0:d4960fcea8ff 1376 {
kenjiArai 0:d4960fcea8ff 1377 portENABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1378 return errQUEUE_FULL;
kenjiArai 0:d4960fcea8ff 1379 }
kenjiArai 0:d4960fcea8ff 1380 }
kenjiArai 0:d4960fcea8ff 1381 }
kenjiArai 0:d4960fcea8ff 1382 portENABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1383
kenjiArai 0:d4960fcea8ff 1384 portNOP();
kenjiArai 0:d4960fcea8ff 1385
kenjiArai 0:d4960fcea8ff 1386 portDISABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1387 {
kenjiArai 0:d4960fcea8ff 1388 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 1389 {
kenjiArai 0:d4960fcea8ff 1390 /* Data is available from the queue. */
kenjiArai 0:d4960fcea8ff 1391 pxQueue->pcReadFrom += pxQueue->uxItemSize;
kenjiArai 0:d4960fcea8ff 1392 if( pxQueue->pcReadFrom >= pxQueue->pcTail )
kenjiArai 0:d4960fcea8ff 1393 {
kenjiArai 0:d4960fcea8ff 1394 pxQueue->pcReadFrom = pxQueue->pcHead;
kenjiArai 0:d4960fcea8ff 1395 }
kenjiArai 0:d4960fcea8ff 1396 --( pxQueue->uxMessagesWaiting );
kenjiArai 0:d4960fcea8ff 1397 memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
kenjiArai 0:d4960fcea8ff 1398
kenjiArai 0:d4960fcea8ff 1399 xReturn = pdPASS;
kenjiArai 0:d4960fcea8ff 1400
kenjiArai 0:d4960fcea8ff 1401 /* Were any co-routines waiting for space to become available? */
kenjiArai 0:d4960fcea8ff 1402 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
kenjiArai 0:d4960fcea8ff 1403 {
kenjiArai 0:d4960fcea8ff 1404 /* In this instance the co-routine could be placed directly
kenjiArai 0:d4960fcea8ff 1405 into the ready list as we are within a critical section.
kenjiArai 0:d4960fcea8ff 1406 Instead the same pending ready list mechanism is used as if
kenjiArai 0:d4960fcea8ff 1407 the event were caused from within an interrupt. */
kenjiArai 0:d4960fcea8ff 1408 if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 1409 {
kenjiArai 0:d4960fcea8ff 1410 xReturn = errQUEUE_YIELD;
kenjiArai 0:d4960fcea8ff 1411 }
kenjiArai 0:d4960fcea8ff 1412 }
kenjiArai 0:d4960fcea8ff 1413 }
kenjiArai 0:d4960fcea8ff 1414 else
kenjiArai 0:d4960fcea8ff 1415 {
kenjiArai 0:d4960fcea8ff 1416 xReturn = pdFAIL;
kenjiArai 0:d4960fcea8ff 1417 }
kenjiArai 0:d4960fcea8ff 1418 }
kenjiArai 0:d4960fcea8ff 1419 portENABLE_INTERRUPTS();
kenjiArai 0:d4960fcea8ff 1420
kenjiArai 0:d4960fcea8ff 1421 return xReturn;
kenjiArai 0:d4960fcea8ff 1422 }
kenjiArai 0:d4960fcea8ff 1423 #endif
kenjiArai 0:d4960fcea8ff 1424 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1425
kenjiArai 0:d4960fcea8ff 1426
kenjiArai 0:d4960fcea8ff 1427
kenjiArai 0:d4960fcea8ff 1428 #if configUSE_CO_ROUTINES == 1
kenjiArai 0:d4960fcea8ff 1429 signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle pxQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
kenjiArai 0:d4960fcea8ff 1430 {
kenjiArai 0:d4960fcea8ff 1431 /* Cannot block within an ISR so if there is no space on the queue then
kenjiArai 0:d4960fcea8ff 1432 exit without doing anything. */
kenjiArai 0:d4960fcea8ff 1433 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
kenjiArai 0:d4960fcea8ff 1434 {
kenjiArai 0:d4960fcea8ff 1435 prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
kenjiArai 0:d4960fcea8ff 1436
kenjiArai 0:d4960fcea8ff 1437 /* We only want to wake one co-routine per ISR, so check that a
kenjiArai 0:d4960fcea8ff 1438 co-routine has not already been woken. */
kenjiArai 0:d4960fcea8ff 1439 if( !xCoRoutinePreviouslyWoken )
kenjiArai 0:d4960fcea8ff 1440 {
kenjiArai 0:d4960fcea8ff 1441 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
kenjiArai 0:d4960fcea8ff 1442 {
kenjiArai 0:d4960fcea8ff 1443 if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 1444 {
kenjiArai 0:d4960fcea8ff 1445 return pdTRUE;
kenjiArai 0:d4960fcea8ff 1446 }
kenjiArai 0:d4960fcea8ff 1447 }
kenjiArai 0:d4960fcea8ff 1448 }
kenjiArai 0:d4960fcea8ff 1449 }
kenjiArai 0:d4960fcea8ff 1450
kenjiArai 0:d4960fcea8ff 1451 return xCoRoutinePreviouslyWoken;
kenjiArai 0:d4960fcea8ff 1452 }
kenjiArai 0:d4960fcea8ff 1453 #endif
kenjiArai 0:d4960fcea8ff 1454 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1455
kenjiArai 0:d4960fcea8ff 1456 #if configUSE_CO_ROUTINES == 1
kenjiArai 0:d4960fcea8ff 1457 signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle pxQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
kenjiArai 0:d4960fcea8ff 1458 {
kenjiArai 0:d4960fcea8ff 1459 signed portBASE_TYPE xReturn;
kenjiArai 0:d4960fcea8ff 1460
kenjiArai 0:d4960fcea8ff 1461 /* We cannot block from an ISR, so check there is data available. If
kenjiArai 0:d4960fcea8ff 1462 not then just leave without doing anything. */
kenjiArai 0:d4960fcea8ff 1463 if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
kenjiArai 0:d4960fcea8ff 1464 {
kenjiArai 0:d4960fcea8ff 1465 /* Copy the data from the queue. */
kenjiArai 0:d4960fcea8ff 1466 pxQueue->pcReadFrom += pxQueue->uxItemSize;
kenjiArai 0:d4960fcea8ff 1467 if( pxQueue->pcReadFrom >= pxQueue->pcTail )
kenjiArai 0:d4960fcea8ff 1468 {
kenjiArai 0:d4960fcea8ff 1469 pxQueue->pcReadFrom = pxQueue->pcHead;
kenjiArai 0:d4960fcea8ff 1470 }
kenjiArai 0:d4960fcea8ff 1471 --( pxQueue->uxMessagesWaiting );
kenjiArai 0:d4960fcea8ff 1472 memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
kenjiArai 0:d4960fcea8ff 1473
kenjiArai 0:d4960fcea8ff 1474 if( !( *pxCoRoutineWoken ) )
kenjiArai 0:d4960fcea8ff 1475 {
kenjiArai 0:d4960fcea8ff 1476 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
kenjiArai 0:d4960fcea8ff 1477 {
kenjiArai 0:d4960fcea8ff 1478 if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
kenjiArai 0:d4960fcea8ff 1479 {
kenjiArai 0:d4960fcea8ff 1480 *pxCoRoutineWoken = pdTRUE;
kenjiArai 0:d4960fcea8ff 1481 }
kenjiArai 0:d4960fcea8ff 1482 }
kenjiArai 0:d4960fcea8ff 1483 }
kenjiArai 0:d4960fcea8ff 1484
kenjiArai 0:d4960fcea8ff 1485 xReturn = pdPASS;
kenjiArai 0:d4960fcea8ff 1486 }
kenjiArai 0:d4960fcea8ff 1487 else
kenjiArai 0:d4960fcea8ff 1488 {
kenjiArai 0:d4960fcea8ff 1489 xReturn = pdFAIL;
kenjiArai 0:d4960fcea8ff 1490 }
kenjiArai 0:d4960fcea8ff 1491
kenjiArai 0:d4960fcea8ff 1492 return xReturn;
kenjiArai 0:d4960fcea8ff 1493 }
kenjiArai 0:d4960fcea8ff 1494 #endif
kenjiArai 0:d4960fcea8ff 1495 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1496
kenjiArai 0:d4960fcea8ff 1497 //#if configQUEUE_REGISTRY_SIZE > 0
kenjiArai 0:d4960fcea8ff 1498
kenjiArai 0:d4960fcea8ff 1499 void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )
kenjiArai 0:d4960fcea8ff 1500 {
kenjiArai 0:d4960fcea8ff 1501 unsigned portBASE_TYPE ux;
kenjiArai 0:d4960fcea8ff 1502
kenjiArai 0:d4960fcea8ff 1503 /* See if there is an empty space in the registry. A NULL name denotes
kenjiArai 0:d4960fcea8ff 1504 a free slot. */
kenjiArai 0:d4960fcea8ff 1505 for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )
kenjiArai 0:d4960fcea8ff 1506 {
kenjiArai 0:d4960fcea8ff 1507 if( xQueueRegistry[ ux ].pcQueueName == NULL )
kenjiArai 0:d4960fcea8ff 1508 {
kenjiArai 0:d4960fcea8ff 1509 /* Store the information on this queue. */
kenjiArai 0:d4960fcea8ff 1510 xQueueRegistry[ ux ].pcQueueName = pcQueueName;
kenjiArai 0:d4960fcea8ff 1511 xQueueRegistry[ ux ].xHandle = xQueue;
kenjiArai 0:d4960fcea8ff 1512 break;
kenjiArai 0:d4960fcea8ff 1513 }
kenjiArai 0:d4960fcea8ff 1514 }
kenjiArai 0:d4960fcea8ff 1515 }
kenjiArai 0:d4960fcea8ff 1516
kenjiArai 0:d4960fcea8ff 1517 //#endif
kenjiArai 0:d4960fcea8ff 1518 /*-----------------------------------------------------------*/
kenjiArai 0:d4960fcea8ff 1519
kenjiArai 0:d4960fcea8ff 1520 #if configQUEUE_REGISTRY_SIZE > 0
kenjiArai 0:d4960fcea8ff 1521
kenjiArai 0:d4960fcea8ff 1522 static void vQueueUnregisterQueue( xQueueHandle xQueue )
kenjiArai 0:d4960fcea8ff 1523 {
kenjiArai 0:d4960fcea8ff 1524 unsigned portBASE_TYPE ux;
kenjiArai 0:d4960fcea8ff 1525
kenjiArai 0:d4960fcea8ff 1526 /* See if the handle of the queue being unregistered in actually in the
kenjiArai 0:d4960fcea8ff 1527 registry. */
kenjiArai 0:d4960fcea8ff 1528 for( ux = 0; ux < configQUEUE_REGISTRY_SIZE; ux++ )
kenjiArai 0:d4960fcea8ff 1529 {
kenjiArai 0:d4960fcea8ff 1530 if( xQueueRegistry[ ux ].xHandle == xQueue )
kenjiArai 0:d4960fcea8ff 1531 {
kenjiArai 0:d4960fcea8ff 1532 /* Set the name to NULL to show that this slot if free again. */
kenjiArai 0:d4960fcea8ff 1533 xQueueRegistry[ ux ].pcQueueName = NULL;
kenjiArai 0:d4960fcea8ff 1534 break;
kenjiArai 0:d4960fcea8ff 1535 }
kenjiArai 0:d4960fcea8ff 1536 }
kenjiArai 0:d4960fcea8ff 1537
kenjiArai 0:d4960fcea8ff 1538 }
kenjiArai 0:d4960fcea8ff 1539
kenjiArai 0:d4960fcea8ff 1540 #endif
kenjiArai 0:d4960fcea8ff 1541