/*\r
- FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.\r
- \r
+ FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.\r
\r
- FreeRTOS supports many tools and architectures. V7.0.0 is sponsored by:\r
- Atollic AB - Atollic provides professional embedded systems development \r
- tools for C/C++ development, code analysis and test automation. \r
- See http://www.atollic.com\r
- \r
\r
***************************************************************************\r
* *\r
\r
#include "FreeRTOS.h"\r
#include "task.h"\r
-#include "croutine.h"\r
+\r
+#if ( configUSE_CO_ROUTINES == 1 )\r
+ #include "croutine.h"\r
+#endif\r
\r
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
\r
\r
/* Semaphores do not actually store or copy data, so have an items size of\r
zero. */\r
-#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( 0 )\r
-#define queueDONT_BLOCK ( ( portTickType ) 0 )\r
-#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0 )\r
+#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 )\r
+#define queueDONT_BLOCK ( ( portTickType ) 0U )\r
+#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U )\r
+\r
+/* These definitions *must* match those in queue.h. */\r
+#define queueQUEUE_TYPE_BASE ( 0U )\r
+#define queueQUEUE_TYPE_MUTEX ( 1U )\r
+#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )\r
+#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )\r
+#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )\r
\r
/*\r
* Definition of the queue used by the scheduler.\r
\r
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. */\r
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. */\r
+ \r
+ #if ( configUSE_TRACE_FACILITY == 1 )\r
+ unsigned char ucQueueNumber;\r
+ unsigned char ucQueueType;\r
+ #endif\r
\r
} xQUEUE;\r
/*-----------------------------------------------------------*/\r
* include the API header file (as it defines xQueueHandle differently). These\r
* functions are documented in the API header file.\r
*/\r
-xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize ) PRIVILEGED_FUNCTION;\r
+xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle pxQueue, void * const pvBuffer, signed portBASE_TYPE *pxTaskWoken ) PRIVILEGED_FUNCTION;\r
-xQueueHandle xQueueCreateMutex( void ) PRIVILEGED_FUNCTION;\r
+xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) PRIVILEGED_FUNCTION;\r
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION;\r
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION;\r
portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex ) PRIVILEGED_FUNCTION;\r
signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION;\r
+unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber ) PRIVILEGED_FUNCTION;\r
+unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;\r
+portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;\r
\r
/*\r
* Co-routine queue functions differ from task queue functions. Co-routines are\r
* PUBLIC QUEUE MANAGEMENT API documented in queue.h\r
*----------------------------------------------------------*/\r
\r
-xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize )\r
+portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )\r
+{\r
+portBASE_TYPE xReturn = pdPASS;\r
+\r
+ configASSERT( pxQueue );\r
+\r
+ /* If the queue being reset has already been used (has not just been\r
+ created), then only reset the queue if its event lists are empty. */\r
+ if( xNewQueue != pdTRUE )\r
+ {\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+\r
+ if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ }\r
+\r
+ if( xReturn == pdPASS )\r
+ {\r
+ pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );\r
+ pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;\r
+ pxQueue->pcWriteTo = pxQueue->pcHead;\r
+ pxQueue->pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize );\r
+ pxQueue->xRxLock = queueUNLOCKED;\r
+ pxQueue->xTxLock = queueUNLOCKED;\r
+\r
+ /* Ensure the event queues start with the correct state. */\r
+ vListInitialise( &( pxQueue->xTasksWaitingToSend ) );\r
+ vListInitialise( &( pxQueue->xTasksWaitingToReceive ) );\r
+ }\r
+\r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType )\r
{\r
xQUEUE *pxNewQueue;\r
size_t xQueueSizeInBytes;\r
xQueueHandle xReturn = NULL;\r
\r
+ /* Remove compiler warnings about unused parameters should \r
+ configUSE_TRACE_FACILITY not be set to 1. */\r
+ ( void ) ucQueueType;\r
+\r
/* Allocate the new queue structure. */\r
if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )\r
{\r
{\r
/* Initialise the queue members as described above where the\r
queue type is defined. */\r
- pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize );\r
- pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;\r
- pxNewQueue->pcWriteTo = pxNewQueue->pcHead;\r
- pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - ( unsigned portBASE_TYPE ) 1U ) * uxItemSize );\r
pxNewQueue->uxLength = uxQueueLength;\r
pxNewQueue->uxItemSize = uxItemSize;\r
- pxNewQueue->xRxLock = queueUNLOCKED;\r
- pxNewQueue->xTxLock = queueUNLOCKED;\r
-\r
- /* Likewise ensure the event queues start with the correct state. */\r
- vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
- vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
+ xQueueGenericReset( pxNewQueue, pdTRUE );\r
+ #if ( configUSE_TRACE_FACILITY == 1 )\r
+ {\r
+ pxNewQueue->ucQueueType = ucQueueType;\r
+ }\r
+ #endif /* configUSE_TRACE_FACILITY */\r
\r
traceQUEUE_CREATE( pxNewQueue );\r
xReturn = pxNewQueue;\r
}\r
else\r
{\r
- traceQUEUE_CREATE_FAILED();\r
+ traceQUEUE_CREATE_FAILED( ucQueueType );\r
vPortFree( pxNewQueue );\r
}\r
}\r
\r
#if ( configUSE_MUTEXES == 1 )\r
\r
- xQueueHandle xQueueCreateMutex( void )\r
+ xQueueHandle xQueueCreateMutex( unsigned char ucQueueType )\r
{\r
xQUEUE *pxNewQueue;\r
\r
+ /* Prevent compiler warnings about unused parameters if\r
+ configUSE_TRACE_FACILITY does not equal 1. */\r
+ ( void ) ucQueueType;\r
+ \r
/* Allocate the new queue structure. */\r
pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );\r
if( pxNewQueue != NULL )\r
pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U;\r
pxNewQueue->xRxLock = queueUNLOCKED;\r
pxNewQueue->xTxLock = queueUNLOCKED;\r
+ \r
+ #if ( configUSE_TRACE_FACILITY == 1 )\r
+ {\r
+ pxNewQueue->ucQueueType = ucQueueType;\r
+ }\r
+ #endif\r
\r
/* Ensure the event queues start with the correct state. */\r
vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
\r
+ traceCREATE_MUTEX( pxNewQueue );\r
+\r
/* Start with the semaphore in the expected state. */\r
xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK );\r
-\r
- traceCREATE_MUTEX( pxNewQueue );\r
}\r
else\r
{\r
{\r
xQueueHandle pxHandle;\r
\r
- pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH );\r
+ pxHandle = xQueueGenericCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE );\r
\r
if( pxHandle != NULL )\r
{\r
/* Update the timeout state to see if it has expired yet. */\r
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
{\r
- if( prvIsQueueFull( pxQueue ) )\r
+ if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
{\r
traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
task is already in a ready list before it yields - in which\r
case the yield will not cause a context switch unless there\r
is also a higher priority task in the pending ready list. */\r
- if( !xTaskResumeAll() )\r
+ if( xTaskResumeAll() == pdFALSE )\r
{\r
portYIELD_WITHIN_API();\r
}\r
{\r
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
{\r
- if( prvIsQueueFull( pxQueue ) )\r
+ if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
{\r
traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
{\r
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
{\r
- if( prvIsQueueEmpty( pxQueue ) )\r
+ if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
{\r
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
\r
/* Update the timeout state to see if it has expired yet. */\r
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )\r
{\r
- if( prvIsQueueEmpty( pxQueue ) )\r
+ if( prvIsQueueEmpty( pxQueue ) != pdFALSE )\r
{\r
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );\r
\r
\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );\r
prvUnlockQueue( pxQueue );\r
- if( !xTaskResumeAll() )\r
+ if( xTaskResumeAll() == pdFALSE )\r
{\r
portYIELD_WITHIN_API();\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue )\r
+ {\r
+ return pxQueue->ucQueueNumber;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber )\r
+ {\r
+ pxQueue->ucQueueNumber = ucQueueNumber;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if ( configUSE_TRACE_FACILITY == 1 )\r
+\r
+ unsigned char ucQueueGetQueueType( xQueueHandle pxQueue )\r
+ {\r
+ return pxQueue->ucQueueType;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )\r
{\r
if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )\r
between the check to see if the queue is full and blocking on the queue. */\r
portDISABLE_INTERRUPTS();\r
{\r
- if( prvIsQueueFull( pxQueue ) )\r
+ if( prvIsQueueFull( pxQueue ) != pdFALSE )\r
{\r
/* The queue is full - do we want to block or just leave without\r
posting? */\r
\r
/* We only want to wake one co-routine per ISR, so check that a\r
co-routine has not already been woken. */\r
- if( !xCoRoutinePreviouslyWoken )\r
+ if( xCoRoutinePreviouslyWoken == pdFALSE )\r
{\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
--( pxQueue->uxMessagesWaiting );\r
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
\r
- if( !( *pxCoRoutineWoken ) )\r
+ if( ( *pxCoRoutineWoken ) == pdFALSE )\r
{\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
\r
/* See if there is an empty space in the registry. A NULL name denotes\r
a free slot. */\r
- for( ux = ( unsigned portBASE_TYPE ) 0U; ux < configQUEUE_REGISTRY_SIZE; ux++ )\r
+ for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )\r
{\r
if( xQueueRegistry[ ux ].pcQueueName == NULL )\r
{\r
\r
/* See if the handle of the queue being unregistered in actually in the\r
registry. */\r
- for( ux = ( unsigned portBASE_TYPE ) 0U; ux < configQUEUE_REGISTRY_SIZE; ux++ )\r
+ for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )\r
{\r
if( xQueueRegistry[ ux ].xHandle == xQueue )\r
{\r