#include <stdlib.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
Go to the source code of this file.
Data Structures | |
struct | QueueDefinition |
Defines | |
#define | MPU_WRAPPERS_INCLUDED_FROM_API_FILE |
#define | prvLockQueue(pxQueue) |
#define | pxMutexHolder pcTail |
#define | queueDONT_BLOCK ( ( portTickType ) 0 ) |
#define | queueERRONEOUS_UNBLOCK ( -1 ) |
#define | queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 ) |
#define | queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0 ) |
#define | queueQUEUE_IS_MUTEX NULL |
#define | queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 ) |
#define | queueSEND_TO_BACK ( 0 ) |
#define | queueSEND_TO_FRONT ( 1 ) |
#define | queueUNLOCKED ( ( signed portBASE_TYPE ) -1 ) |
#define | uxQueueType pcHead |
#define | uxRecursiveCallCount pcReadFrom |
Typedefs | |
typedef struct QueueDefinition | xQUEUE |
typedef xQUEUE * | xQueueHandle |
Functions | |
static void | prvCopyDataFromQueue (xQUEUE *const pxQueue, const void *pvBuffer) |
static void | prvCopyDataToQueue (xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition) |
static signed portBASE_TYPE | prvIsQueueEmpty (const xQueueHandle pxQueue) |
static signed portBASE_TYPE | prvIsQueueFull (const xQueueHandle pxQueue) |
static void | prvUnlockQueue (xQueueHandle pxQueue) |
unsigned portBASE_TYPE | uxQueueMessagesWaiting (const xQueueHandle pxQueue) PRIVILEGED_FUNCTION |
unsigned portBASE_TYPE | uxQueueMessagesWaitingFromISR (const xQueueHandle pxQueue) |
void | vQueueDelete (xQueueHandle xQueue) PRIVILEGED_FUNCTION |
xQueueHandle | xQueueCreate (unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize) PRIVILEGED_FUNCTION |
xQueueHandle | xQueueCreateMutex (void) |
signed portBASE_TYPE | xQueueGenericReceive (xQueueHandle pxQueue, void *const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking) PRIVILEGED_FUNCTION |
signed portBASE_TYPE | xQueueGenericSend (xQueueHandle xQueue, const void *const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition) PRIVILEGED_FUNCTION |
signed portBASE_TYPE | xQueueGenericSendFromISR (xQueueHandle pxQueue, const void *const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition) PRIVILEGED_FUNCTION |
signed portBASE_TYPE | xQueueIsQueueEmptyFromISR (const xQueueHandle pxQueue) |
signed portBASE_TYPE | xQueueIsQueueFullFromISR (const xQueueHandle pxQueue) |
signed portBASE_TYPE | xQueueReceiveFromISR (xQueueHandle pxQueue, void *const pvBuffer, signed portBASE_TYPE *pxTaskWoken) PRIVILEGED_FUNCTION |
#define prvLockQueue | ( | pxQueue | ) |
Value:
{ \ taskENTER_CRITICAL(); \ { \ if( pxQueue->xRxLock == queueUNLOCKED ) \ { \ pxQueue->xRxLock = queueLOCKED_UNMODIFIED; \ } \ if( pxQueue->xTxLock == queueUNLOCKED ) \ { \ pxQueue->xTxLock = queueLOCKED_UNMODIFIED; \ } \ } \ taskEXIT_CRITICAL(); \ }
Referenced by xQueueGenericReceive(), and xQueueGenericSend().
#define queueDONT_BLOCK ( ( portTickType ) 0 ) |
#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 ) |
#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0 ) |
#define queueQUEUE_IS_MUTEX NULL |
Definition at line 86 of file queue.c.
Referenced by prvCopyDataFromQueue(), prvCopyDataToQueue(), and xQueueGenericReceive().
#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 ) |
Definition at line 73 of file queue.c.
Referenced by prvUnlockQueue(), xQueueGenericSendFromISR(), and xQueueReceiveFromISR().
typedef struct QueueDefinition xQUEUE |
typedef xQUEUE* xQueueHandle |
static void prvCopyDataFromQueue | ( | xQUEUE *const | pxQueue, | |
const void * | pvBuffer | |||
) | [static] |
Definition at line 1088 of file queue.c.
References QueueDefinition::pcHead, QueueDefinition::pcReadFrom, QueueDefinition::pcTail, queueQUEUE_IS_MUTEX, and QueueDefinition::uxItemSize.
Referenced by xQueueGenericReceive(), and xQueueReceiveFromISR().
01088 { 01089 if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX ) 01090 { 01091 pxQueue->pcReadFrom += pxQueue->uxItemSize; 01092 if( pxQueue->pcReadFrom >= pxQueue->pcTail ) 01093 { 01094 pxQueue->pcReadFrom = pxQueue->pcHead; 01095 } 01096 memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); 01097 } 01098 } 01099 /*-----------------------------------------------------------*/
static void prvCopyDataToQueue | ( | xQUEUE * | pxQueue, | |
const void * | pvItemToQueue, | |||
portBASE_TYPE | xPosition | |||
) | [static] |
Definition at line 1050 of file queue.c.
References QueueDefinition::pcHead, QueueDefinition::pcReadFrom, QueueDefinition::pcTail, QueueDefinition::pcWriteTo, queueQUEUE_IS_MUTEX, queueSEND_TO_BACK, QueueDefinition::uxItemSize, QueueDefinition::uxMessagesWaiting, and vTaskPriorityDisinherit().
Referenced by xQueueGenericSend(), and xQueueGenericSendFromISR().
01050 { 01051 if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 ) 01052 { 01053 #if ( configUSE_MUTEXES == 1 ) 01054 { 01055 if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) 01056 { 01057 /* The mutex is no longer being held. */ 01058 vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder ); 01059 pxQueue->pxMutexHolder = NULL; 01060 } 01061 } 01062 #endif 01063 } 01064 else if( xPosition == queueSEND_TO_BACK ) 01065 { 01066 memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); 01067 pxQueue->pcWriteTo += pxQueue->uxItemSize; 01068 if( pxQueue->pcWriteTo >= pxQueue->pcTail ) 01069 { 01070 pxQueue->pcWriteTo = pxQueue->pcHead; 01071 } 01072 } 01073 else 01074 { 01075 memcpy( ( void * ) pxQueue->pcReadFrom, pvItemToQueue, ( unsigned ) pxQueue->uxItemSize ); 01076 pxQueue->pcReadFrom -= pxQueue->uxItemSize; 01077 if( pxQueue->pcReadFrom < pxQueue->pcHead ) 01078 { 01079 pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize ); 01080 } 01081 } 01082 01083 ++( pxQueue->uxMessagesWaiting ); 01084 } 01085 /*-----------------------------------------------------------*/
static signed portBASE_TYPE prvIsQueueEmpty | ( | const xQueueHandle | pxQueue | ) | [static] |
Definition at line 1166 of file queue.c.
References taskENTER_CRITICAL, and taskEXIT_CRITICAL.
Referenced by xQueueGenericReceive().
01166 { 01167 signed portBASE_TYPE xReturn; 01168 01169 taskENTER_CRITICAL(); 01170 xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ); 01171 taskEXIT_CRITICAL(); 01172 01173 return xReturn; 01174 } 01175 /*-----------------------------------------------------------*/
static signed portBASE_TYPE prvIsQueueFull | ( | const xQueueHandle | pxQueue | ) | [static] |
Definition at line 1188 of file queue.c.
References taskENTER_CRITICAL, and taskEXIT_CRITICAL.
Referenced by xQueueGenericSend().
01188 { 01189 signed portBASE_TYPE xReturn; 01190 01191 taskENTER_CRITICAL(); 01192 xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength ); 01193 taskEXIT_CRITICAL(); 01194 01195 return xReturn; 01196 } 01197 /*-----------------------------------------------------------*/
static void prvUnlockQueue | ( | xQueueHandle | pxQueue | ) | [static] |
Definition at line 1102 of file queue.c.
References listLIST_IS_EMPTY, pdFALSE, queueLOCKED_UNMODIFIED, queueUNLOCKED, taskENTER_CRITICAL, taskEXIT_CRITICAL, vTaskMissedYield(), and xTaskRemoveFromEventList().
Referenced by xQueueGenericReceive(), and xQueueGenericSend().
01102 { 01103 /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ 01104 01105 /* The lock counts contains the number of extra data items placed or 01106 removed from the queue while the queue was locked. When a queue is 01107 locked items can be added or removed, but the event lists cannot be 01108 updated. */ 01109 taskENTER_CRITICAL(); 01110 { 01111 /* See if data was added to the queue while it was locked. */ 01112 while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED ) 01113 { 01114 /* Data was posted while the queue was locked. Are any tasks 01115 blocked waiting for data to become available? */ 01116 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ) 01117 { 01118 /* Tasks that are removed from the event list will get added to 01119 the pending ready list as the scheduler is still suspended. */ 01120 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) 01121 { 01122 /* The task waiting has a higher priority so record that a 01123 context switch is required. */ 01124 vTaskMissedYield(); 01125 } 01126 01127 --( pxQueue->xTxLock ); 01128 } 01129 else 01130 { 01131 break; 01132 } 01133 } 01134 01135 pxQueue->xTxLock = queueUNLOCKED; 01136 } 01137 taskEXIT_CRITICAL(); 01138 01139 /* Do the same for the Rx lock. */ 01140 taskENTER_CRITICAL(); 01141 { 01142 while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) 01143 { 01144 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ) 01145 { 01146 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) 01147 { 01148 vTaskMissedYield(); 01149 } 01150 01151 --( pxQueue->xRxLock ); 01152 } 01153 else 01154 { 01155 break; 01156 } 01157 } 01158 01159 pxQueue->xRxLock = queueUNLOCKED; 01160 } 01161 taskEXIT_CRITICAL(); 01162 } 01163 /*-----------------------------------------------------------*/
unsigned portBASE_TYPE uxQueueMessagesWaiting | ( | const xQueueHandle | pxQueue | ) |
unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR | ( | const xQueueHandle | pxQueue | ) |
Definition at line 1031 of file queue.c.
01031 { 01032 unsigned portBASE_TYPE uxReturn; 01033 01034 uxReturn = pxQueue->uxMessagesWaiting; 01035 01036 return uxReturn; 01037 } 01038 /*-----------------------------------------------------------*/
void vQueueDelete | ( | xQueueHandle | xQueue | ) |
xQueueHandle xQueueCreate | ( | unsigned portBASE_TYPE | uxQueueLength, | |
unsigned portBASE_TYPE | uxItemSize | |||
) |
xQueueHandle xQueueCreateMutex | ( | void | ) |
Definition at line 138 of file queue.c.
00169 { 00170 signed char *pcQueueName; 00171 xQueueHandle xHandle; 00172 } xQueueRegistryItem; 00173 00174 /* The queue registry is simply an array of xQueueRegistryItem structures. 00175 The pcQueueName member of a structure being NULL is indicative of the 00176 array position being vacant. */ 00177 xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; 00178 00179 /* Removes a queue from the registry by simply setting the pcQueueName 00180 member to NULL. */ 00181 static void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; 00182 void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) PRIVILEGED_FUNCTION; 00183 #endif 00184 00185 /* 00186 * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not 00187 * prevent an ISR from adding or removing items to the queue, but does prevent 00188 * an ISR from removing tasks from the queue event lists. If an ISR finds a 00189 * queue is locked it will instead increment the appropriate queue lock count 00190 * to indicate that a task may require unblocking. When the queue in unlocked 00191 * these lock counts are inspected, and the appropriate action taken. 00192 */ 00193 static void prvUnlockQueue( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; 00194 00195 /* 00196 * Uses a critical section to determine if there is any data in a queue. 00197 * 00198 * @return pdTRUE if the queue contains no items, otherwise pdFALSE. 00199 */ 00200 static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; 00201 00202 /* 00203 * Uses a critical section to determine if there is any space in a queue. 00204 * 00205 * @return pdTRUE if there is no space, otherwise pdFALSE; 00206 */ 00207 static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION; 00208 00209 /* 00210 * Copies an item into the queue, either at the front of the queue or the 00211 * back of the queue. 00212 */ 00213 static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION; 00214 00215 /* 00216 * Copies an item out of a queue. 00217 */ 00218 static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void *pvBuffer ) PRIVILEGED_FUNCTION; 00219 /*-----------------------------------------------------------*/ 00220 00221 /* 00222 * Macro to mark a queue as locked. Locking a queue prevents an ISR from 00223 * accessing the queue event lists. 00224 */ 00225 #define prvLockQueue( pxQueue ) \ 00226 { \ 00227 taskENTER_CRITICAL(); \ 00228 { \ 00229 if( pxQueue->xRxLock == queueUNLOCKED ) \ 00230 { \ 00231 pxQueue->xRxLock = queueLOCKED_UNMODIFIED; \ 00232 } \ 00233 if( pxQueue->xTxLock == queueUNLOCKED ) \ 00234 { \ 00235 pxQueue->xTxLock = queueLOCKED_UNMODIFIED; \ 00236 } \ 00237 } \ 00238 taskEXIT_CRITICAL(); \ 00239 } 00240 /*-----------------------------------------------------------*/ 00241 00242 00243 /*----------------------------------------------------------- 00244 * PUBLIC QUEUE MANAGEMENT API documented in queue.h 00245 *----------------------------------------------------------*/ 00246 00247 xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) 00248 { 00249 xQUEUE *pxNewQueue; 00250 size_t xQueueSizeInBytes; 00251 00252 /* Allocate the new queue structure. */ 00253 if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) 00254 { 00255 pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) ); 00256 if( pxNewQueue != NULL ) 00257 { 00258 /* Create the list of pointers to queue items. The queue is one byte 00259 longer than asked for to make wrap checking easier/faster. */ 00260 xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; 00261 00262 pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes ); 00263 if( pxNewQueue->pcHead != NULL ) 00264 { 00265 /* Initialise the queue members as described above where the 00266 queue type is defined. */ 00267 pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize ); 00268 pxNewQueue->uxMessagesWaiting = 0; 00269 pxNewQueue->pcWriteTo = pxNewQueue->pcHead; 00270 pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize ); 00271 pxNewQueue->uxLength = uxQueueLength; 00272 pxNewQueue->uxItemSize = uxItemSize; 00273 pxNewQueue->xRxLock = queueUNLOCKED; 00274 pxNewQueue->xTxLock = queueUNLOCKED; 00275 00276 /* Likewise ensure the event queues start with the correct state. */ 00277 vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); 00278 vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); 00279 00280 traceQUEUE_CREATE( pxNewQueue ); 00281 return pxNewQueue; 00282 } 00283 else 00284 { 00285 traceQUEUE_CREATE_FAILED(); 00286 vPortFree( pxNewQueue ); 00287 } 00288 } 00289 } 00290 00291 /* Will only reach here if we could not allocate enough memory or no memory 00292 was required. */ 00293 return NULL; 00294 }
signed portBASE_TYPE xQueueGenericReceive | ( | xQueueHandle | pxQueue, | |
void *const | pvBuffer, | |||
portTickType | xTicksToWait, | |||
portBASE_TYPE | xJustPeeking | |||
) |
signed portBASE_TYPE xQueueGenericSend | ( | xQueueHandle | xQueue, | |
const void *const | pvItemToQueue, | |||
portTickType | xTicksToWait, | |||
portBASE_TYPE | xCopyPosition | |||
) |
signed portBASE_TYPE xQueueGenericSendFromISR | ( | xQueueHandle | pxQueue, | |
const void *const | pvItemToQueue, | |||
signed portBASE_TYPE * | pxHigherPriorityTaskWoken, | |||
portBASE_TYPE | xCopyPosition | |||
) |
signed portBASE_TYPE xQueueIsQueueEmptyFromISR | ( | const xQueueHandle | pxQueue | ) |
Definition at line 1178 of file queue.c.
01178 { 01179 signed portBASE_TYPE xReturn; 01180 01181 xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ); 01182 01183 return xReturn; 01184 } 01185 /*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueIsQueueFullFromISR | ( | const xQueueHandle | pxQueue | ) |
Definition at line 1200 of file queue.c.
01200 { 01201 signed portBASE_TYPE xReturn; 01202 01203 xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength ); 01204 01205 return xReturn; 01206 } 01207 /*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueReceiveFromISR | ( | xQueueHandle | pxQueue, | |
void *const | pvBuffer, | |||
signed portBASE_TYPE * | pxTaskWoken | |||
) |