Please ensure to read the configuration and relevant port sections of the\r
online documentation.\r
\r
Please ensure to read the configuration and relevant port sections of the\r
online documentation.\r
\r
- http://www.FreeRTOS.org - Documentation, latest information, license and \r
+ http://www.FreeRTOS.org - Documentation, latest information, license and\r
- http://www.SafeRTOS.com - A version that is certified for use in safety \r
+ http://www.SafeRTOS.com - A version that is certified for use in safety\r
- http://www.OpenRTOS.com - Commercial support, development, porting, \r
+ http://www.OpenRTOS.com - Commercial support, development, porting,\r
licensing and training services.\r
*/\r
\r
licensing and training services.\r
*/\r
\r
* queue structures. It has no other purpose so is an optional component.\r
*/\r
#if configQUEUE_REGISTRY_SIZE > 0\r
* queue structures. It has no other purpose so is an optional component.\r
*/\r
#if configQUEUE_REGISTRY_SIZE > 0\r
/* The type stored within the queue registry array. This allows a name\r
/* The type stored within the queue registry array. This allows a name\r
- to be assigned to each queue making kernel aware debugging a little \r
+ to be assigned to each queue making kernel aware debugging a little\r
more user friendly. */\r
typedef struct QUEUE_REGISTRY_ITEM\r
{\r
more user friendly. */\r
typedef struct QUEUE_REGISTRY_ITEM\r
{\r
/* The queue registry is simply an array of xQueueRegistryItem structures.\r
The pcQueueName member of a structure being NULL is indicative of the\r
array position being vacant. */\r
/* The queue registry is simply an array of xQueueRegistryItem structures.\r
The pcQueueName member of a structure being NULL is indicative of the\r
array position being vacant. */\r
- xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ] = { 0 };\r
+ xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];\r
\r
/* Removes a queue from the registry by simply setting the pcQueueName\r
member to NULL. */\r
static void vQueueUnregisterQueue( xQueueHandle xQueue );\r
void vQueueAddToRegistry( xQueueHandle xQueue, signed portCHAR *pcQueueName );\r
\r
/* Removes a queue from the registry by simply setting the pcQueueName\r
member to NULL. */\r
static void vQueueUnregisterQueue( xQueueHandle xQueue );\r
void vQueueAddToRegistry( xQueueHandle xQueue, signed portCHAR *pcQueueName );\r
/*\r
* Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not\r
* prevent an ISR from adding or removing items to the queue, but does prevent\r
/*\r
* Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not\r
* prevent an ISR from adding or removing items to the queue, but does prevent\r
xQueueHandle xQueueCreateMutex( void )\r
{\r
xQUEUE *pxNewQueue;\r
xQueueHandle xQueueCreateMutex( void )\r
{\r
xQUEUE *pxNewQueue;\r
/* Allocate the new queue structure. */\r
pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );\r
if( pxNewQueue != NULL )\r
/* Allocate the new queue structure. */\r
pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );\r
if( pxNewQueue != NULL )\r
/* Information required for priority inheritance. */\r
pxNewQueue->pxMutexHolder = NULL;\r
pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;\r
/* Information required for priority inheritance. */\r
pxNewQueue->pxMutexHolder = NULL;\r
pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;\r
/* Queues used as a mutex no data is actually copied into or out\r
of the queue. */\r
pxNewQueue->pcWriteTo = NULL;\r
pxNewQueue->pcReadFrom = NULL;\r
/* Queues used as a mutex no data is actually copied into or out\r
of the queue. */\r
pxNewQueue->pcWriteTo = NULL;\r
pxNewQueue->pcReadFrom = NULL;\r
/* Each mutex has a length of 1 (like a binary semaphore) and\r
an item size of 0 as nothing is actually copied into or out\r
of the mutex. */\r
/* Each mutex has a length of 1 (like a binary semaphore) and\r
an item size of 0 as nothing is actually copied into or out\r
of the mutex. */\r
pxNewQueue->uxItemSize = 0;\r
pxNewQueue->xRxLock = queueUNLOCKED;\r
pxNewQueue->xTxLock = queueUNLOCKED;\r
pxNewQueue->uxItemSize = 0;\r
pxNewQueue->xRxLock = queueUNLOCKED;\r
pxNewQueue->xTxLock = queueUNLOCKED;\r
/* Ensure the event queues start with the correct state. */\r
vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
/* Ensure the event queues start with the correct state. */\r
vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );\r
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );\r
{\r
traceCREATE_MUTEX_FAILED();\r
}\r
{\r
traceCREATE_MUTEX_FAILED();\r
}\r
return pxNewQueue;\r
}\r
\r
return pxNewQueue;\r
}\r
\r
xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );\r
}\r
\r
xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );\r
}\r
\r
{\r
( pxMutex->uxRecursiveCallCount )++;\r
}\r
{\r
( pxMutex->uxRecursiveCallCount )++;\r
}\r
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )\r
{\r
xQueueHandle pxHandle;\r
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )\r
{\r
xQueueHandle pxHandle;\r
pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH );\r
\r
if( pxHandle != NULL )\r
pxHandle = xQueueCreate( ( unsigned portBASE_TYPE ) uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH );\r
\r
if( pxHandle != NULL )\r
{\r
traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
{\r
traceBLOCKING_ON_QUEUE_SEND( pxQueue );\r
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );\r
/* Unlocking the queue means queue events can effect the\r
event list. It is possible that interrupts occurring now\r
remove this task from the event list again - but as the\r
scheduler is suspended the task will go onto the pending\r
ready last instead of the actual ready list. */\r
prvUnlockQueue( pxQueue );\r
/* Unlocking the queue means queue events can effect the\r
event list. It is possible that interrupts occurring now\r
remove this task from the event list again - but as the\r
scheduler is suspended the task will go onto the pending\r
ready last instead of the actual ready list. */\r
prvUnlockQueue( pxQueue );\r
/* Resuming the scheduler will move tasks from the pending\r
ready list into the ready list - so it is feasible that this\r
task is already in a ready list before it yields - in which\r
/* Resuming the scheduler will move tasks from the pending\r
ready list into the ready list - so it is feasible that this\r
task is already in a ready list before it yields - in which\r
( void ) xTaskResumeAll();\r
}\r
}\r
( void ) xTaskResumeAll();\r
}\r
}\r
/* Higher priority tasks and interrupts can execute during\r
this time and could possible refill the queue - even if we\r
unblocked because space became available. */\r
/* Higher priority tasks and interrupts can execute during\r
this time and could possible refill the queue - even if we\r
unblocked because space became available. */\r
taskENTER_CRITICAL();\r
{\r
/* Is there room on the queue now? To be running we must be\r
taskENTER_CRITICAL();\r
{\r
/* Is there room on the queue now? To be running we must be\r
traceQUEUE_SEND( pxQueue );\r
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
xReturn = pdPASS;\r
traceQUEUE_SEND( pxQueue );\r
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
xReturn = pdPASS;\r
/* If there was a task waiting for data to arrive on the\r
queue then unblock it now. */\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
/* If there was a task waiting for data to arrive on the\r
queue then unblock it now. */\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
xTimeOutType xTimeOut;\r
\r
/* The source code that implements the alternative (Alt) API is\r
xTimeOutType xTimeOut;\r
\r
/* The source code that implements the alternative (Alt) API is\r
- simpler because it makes more use of critical sections. This is \r
+ simpler because it makes more use of critical sections. This is\r
the approach taken by many other RTOSes, but FreeRTOS.org has the\r
preferred fully featured API too. The fully featured API has more\r
complex code that takes longer to execute, but makes less use of\r
the approach taken by many other RTOSes, but FreeRTOS.org has the\r
preferred fully featured API too. The fully featured API has more\r
complex code that takes longer to execute, but makes less use of\r
block at least once. */\r
vTaskSetTimeOutState( &xTimeOut );\r
}\r
block at least once. */\r
vTaskSetTimeOutState( &xTimeOut );\r
}\r
if( prvIsQueueFull( pxQueue ) )\r
{\r
/* Need to call xTaskCheckForTimeout again as time could\r
if( prvIsQueueFull( pxQueue ) )\r
{\r
/* Need to call xTaskCheckForTimeout again as time could\r
}\r
portEXIT_CRITICAL();\r
}\r
}\r
portEXIT_CRITICAL();\r
}\r
/* Higher priority tasks and interrupts can execute during\r
this time and could possible refill the queue - even if we\r
unblocked because space became available. */\r
/* Higher priority tasks and interrupts can execute during\r
this time and could possible refill the queue - even if we\r
unblocked because space became available. */\r
taskENTER_CRITICAL();\r
{\r
/* Is there room on the queue now? To be running we must be\r
taskENTER_CRITICAL();\r
{\r
/* Is there room on the queue now? To be running we must be\r
traceQUEUE_SEND( pxQueue );\r
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
xReturn = pdPASS;\r
traceQUEUE_SEND( pxQueue );\r
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
xReturn = pdPASS;\r
/* If there was a task waiting for data to arrive on the\r
queue then unblock it now. */\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
/* If there was a task waiting for data to arrive on the\r
queue then unblock it now. */\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
signed portCHAR *pcOriginalReadPosition;\r
\r
/* The source code that implements the alternative (Alt) API is\r
signed portCHAR *pcOriginalReadPosition;\r
\r
/* The source code that implements the alternative (Alt) API is\r
- simpler because it makes more use of critical sections. This is \r
+ simpler because it makes more use of critical sections. This is\r
the approach taken by many other RTOSes, but FreeRTOS.org has the\r
preferred fully featured API too. The fully featured API has more\r
complex code that takes longer to execute, but makes less use of\r
the approach taken by many other RTOSes, but FreeRTOS.org has the\r
preferred fully featured API too. The fully featured API has more\r
complex code that takes longer to execute, but makes less use of\r
block at least once. */\r
vTaskSetTimeOutState( &xTimeOut );\r
}\r
block at least once. */\r
vTaskSetTimeOutState( &xTimeOut );\r
}\r
if( prvIsQueueEmpty( pxQueue ) )\r
{\r
/* Need to call xTaskCheckForTimeout again as time could\r
if( prvIsQueueEmpty( pxQueue ) )\r
{\r
/* Need to call xTaskCheckForTimeout again as time could\r
}\r
portEXIT_CRITICAL();\r
}\r
}\r
portEXIT_CRITICAL();\r
}\r
taskENTER_CRITICAL();\r
{\r
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
taskENTER_CRITICAL();\r
{\r
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
/* The task waiting has a higher priority that this task. */\r
taskYIELD();\r
}\r
/* The task waiting has a higher priority that this task. */\r
taskYIELD();\r
}\r
- \r
- xReturn = pdPASS; \r
+\r
+ xReturn = pdPASS;\r
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
{\r
traceQUEUE_SEND_FROM_ISR( pxQueue );\r
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
{\r
traceQUEUE_SEND_FROM_ISR( pxQueue );\r
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
/* If the queue is locked we do not alter the event list. This will\r
be done when the queue is unlocked later. */\r
if( pxQueue->xTxLock == queueUNLOCKED )\r
/* If the queue is locked we do not alter the event list. This will\r
be done when the queue is unlocked later. */\r
if( pxQueue->xTxLock == queueUNLOCKED )\r
knows that data was posted while it was locked. */\r
++( pxQueue->xTxLock );\r
}\r
knows that data was posted while it was locked. */\r
++( pxQueue->xTxLock );\r
}\r
xReturn = pdPASS;\r
}\r
else\r
xReturn = pdPASS;\r
}\r
else\r
( void ) xTaskResumeAll();\r
}\r
}\r
( void ) xTaskResumeAll();\r
}\r
}\r
+\r
+/* The two tasks are blocked on the queue, the low priority task is polling/running. */\r
+\r
+/* An interrupt occurs here - which unblocks the HP tasks, but they do not run. */\r
taskENTER_CRITICAL();\r
{\r
taskENTER_CRITICAL();\r
{\r
+/* Because the interrupt occurred the LP task manages to grab the data as the other two tasks are not yet running. */\r
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
/* Remember our read position in case we are just peeking. */\r
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
/* Remember our read position in case we are just peeking. */\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )\r
{\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )\r
the pending ready list as the scheduler is still suspended. */\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
{\r
the pending ready list as the scheduler is still suspended. */\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
{\r
- /* The task waiting has a higher priority that this task. */\r
+ /* The task waiting has a higher priority than this task. */\r
- \r
- xReturn = pdPASS; \r
+\r
+ xReturn = pdPASS;\r
traceQUEUE_RECEIVE_FAILED( pxQueue );\r
}\r
}\r
traceQUEUE_RECEIVE_FAILED( pxQueue );\r
}\r
}\r
} while( xReturn == queueERRONEOUS_UNBLOCK );\r
\r
return xReturn;\r
} while( xReturn == queueERRONEOUS_UNBLOCK );\r
\r
return xReturn;\r
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
traceQUEUE_RECEIVE_FROM_ISR( pxQueue );\r
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )\r
{\r
traceQUEUE_RECEIVE_FROM_ISR( pxQueue );\r
prvCopyDataFromQueue( pxQueue, pvBuffer );\r
--( pxQueue->uxMessagesWaiting );\r
prvCopyDataFromQueue( pxQueue, pvBuffer );\r
--( pxQueue->uxMessagesWaiting );\r
/* If the queue is locked we will not modify the event list. Instead\r
we update the lock count so the task that unlocks the queue will know\r
that an ISR has removed data while the queue was locked. */\r
/* If the queue is locked we will not modify the event list. Instead\r
we update the lock count so the task that unlocks the queue will know\r
that an ISR has removed data while the queue was locked. */\r
knows that data was removed while it was locked. */\r
++( pxQueue->xRxLock );\r
}\r
knows that data was removed while it was locked. */\r
++( pxQueue->xRxLock );\r
}\r
xReturn = pdPASS;\r
}\r
else\r
xReturn = pdPASS;\r
}\r
else\r
if( pxQueue->pcReadFrom < pxQueue->pcHead )\r
{\r
pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );\r
if( pxQueue->pcReadFrom < pxQueue->pcHead )\r
{\r
pxQueue->pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );\r
}\r
\r
++( pxQueue->uxMessagesWaiting );\r
}\r
\r
++( pxQueue->uxMessagesWaiting );\r
pxQueue->pcReadFrom = pxQueue->pcHead;\r
}\r
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
pxQueue->pcReadFrom = pxQueue->pcHead;\r
}\r
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->pcReadFrom, ( unsigned ) pxQueue->uxItemSize );\r
}\r
/*-----------------------------------------------------------*/\r
\r
}\r
/*-----------------------------------------------------------*/\r
\r
signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
{\r
signed portBASE_TYPE xReturn;\r
signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )\r
{\r
signed portBASE_TYPE xReturn;\r
/* If the queue is already full we may have to block. A critical section\r
is required to prevent an interrupt removing something from the queue\r
between the check to see if the queue is full and blocking on the queue. */\r
/* If the queue is already full we may have to block. A critical section\r
is required to prevent an interrupt removing something from the queue\r
between the check to see if the queue is full and blocking on the queue. */\r
{\r
/* As this is called from a coroutine we cannot block directly, but\r
return indicating that we need to block. */\r
{\r
/* As this is called from a coroutine we cannot block directly, but\r
return indicating that we need to block. */\r
- vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); \r
+ vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );\r
portENABLE_INTERRUPTS();\r
return errQUEUE_BLOCKED;\r
}\r
portENABLE_INTERRUPTS();\r
return errQUEUE_BLOCKED;\r
}\r
}\r
}\r
portENABLE_INTERRUPTS();\r
}\r
}\r
portENABLE_INTERRUPTS();\r
portNOP();\r
\r
portDISABLE_INTERRUPTS();\r
{\r
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
{\r
portNOP();\r
\r
portDISABLE_INTERRUPTS();\r
{\r
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )\r
{\r
- /* There is room in the queue, copy the data into the queue. */ \r
+ /* There is room in the queue, copy the data into the queue. */\r
prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
xReturn = pdPASS;\r
\r
prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );\r
xReturn = pdPASS;\r
\r
if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
{\r
/* There are no messages in the queue, do we want to block or just\r
if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )\r
{\r
/* There are no messages in the queue, do we want to block or just\r
- leave with nothing? */ \r
+ leave with nothing? */\r
if( xTicksToWait > ( portTickType ) 0 )\r
{\r
/* As this is a co-routine we cannot block directly, but return\r
if( xTicksToWait > ( portTickType ) 0 )\r
{\r
/* As this is a co-routine we cannot block directly, but return\r
{\r
xReturn = errQUEUE_YIELD;\r
}\r
{\r
xReturn = errQUEUE_YIELD;\r
}\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
\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 )\r
{\r
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
{\r
{\r
if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )\r
{\r
xQueueRegistry[ ux ].pcQueueName = NULL;\r
break;\r
}\r
xQueueRegistry[ ux ].pcQueueName = NULL;\r
break;\r
}\r