prvQueueOverwriteTask() has not found any errors. */\r
static unsigned long ulLoopCounter = 0;\r
\r
+/* Set to pdFALSE if an error is discovered by the\r
+vQueueOverwritePeriodicISRDemo() function. */\r
+static portBASE_TYPE xISRTestStatus = pdPASS;\r
+\r
+/* The queue that is accessed from the ISR. The queue accessed by the task is\r
+created inside the task itself. */\r
+static xQueueHandle xISRQueue = NULL;\r
+\r
/*-----------------------------------------------------------*/\r
\r
void vStartQueueOverwriteTask( unsigned portBASE_TYPE uxPriority )\r
{\r
- /* Create the test task. */\r
+const unsigned portBASE_TYPE uxQueueLength = 1;\r
+\r
+ /* Create the queue used by the ISR. xQueueOverwriteFromISR() should only\r
+ be used on queues that have a length of 1. */\r
+ xISRQueue = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( unsigned long ) );\r
+\r
+ /* Create the test task. The queue used by the test task is created inside\r
+ the task itself. */\r
xTaskCreate( prvQueueOverwriteTask, ( signed char * ) "QOver", configMINIMAL_STACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );\r
}\r
/*-----------------------------------------------------------*/\r
\r
static void prvQueueOverwriteTask( void *pvParameters )\r
{\r
-xQueueHandle xQueue;\r
+xQueueHandle xTaskQueue;\r
const unsigned portBASE_TYPE uxQueueLength = 1;\r
unsigned long ulValue, ulStatus = pdPASS, x;\r
\r
\r
/* Create the queue. xQueueOverwrite() should only be used on queues that\r
have a length of 1. */\r
- xQueue = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( unsigned long ) );\r
- configASSERT( xQueue );\r
+ xTaskQueue = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( unsigned long ) );\r
+ configASSERT( xTaskQueue );\r
\r
for( ;; )\r
{\r
/* The queue is empty. Writing to the queue then reading from the queue\r
should return the item written. */\r
ulValue = 10;\r
- xQueueOverwrite( xQueue, &ulValue );\r
+ xQueueOverwrite( xTaskQueue, &ulValue );\r
\r
ulValue = 0;\r
- xQueueReceive( xQueue, &ulValue, qoDONT_BLOCK );\r
+ xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );\r
\r
if( ulValue != 10 )\r
{\r
for( x = 0; x < qoLOOPS; x++ )\r
{\r
/* Write to the queue. */\r
- xQueueOverwrite( xQueue, &x );\r
+ xQueueOverwrite( xTaskQueue, &x );\r
\r
/* Check the value in the queue is that written, even though the\r
queue was not necessarily empty. */\r
- xQueuePeek( xQueue, &ulValue, qoDONT_BLOCK );\r
+ xQueuePeek( xTaskQueue, &ulValue, qoDONT_BLOCK );\r
if( ulValue != x )\r
{\r
ulStatus = pdFAIL;\r
}\r
\r
/* There should always be one item in the queue. */\r
- if( uxQueueMessagesWaiting( xQueue ) != uxQueueLength )\r
+ if( uxQueueMessagesWaiting( xTaskQueue ) != uxQueueLength )\r
{\r
ulStatus = pdFAIL;\r
}\r
}\r
\r
/* Empty the queue again. */\r
- xQueueReceive( xQueue, &ulValue, qoDONT_BLOCK );\r
+ xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK );\r
\r
- if( uxQueueMessagesWaiting( xQueue ) != 0 )\r
+ if( uxQueueMessagesWaiting( xTaskQueue ) != 0 )\r
{\r
ulStatus = pdFAIL;\r
}\r
{\r
portBASE_TYPE xReturn;\r
\r
- if( ulLoopCounter > 0 )\r
+ if( xISRTestStatus != pdPASS )\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ else if( ulLoopCounter > 0 )\r
{\r
xReturn = pdPASS;\r
}\r
\r
return xReturn;\r
}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vQueueOverwritePeriodicISRDemo( void )\r
+{\r
+static unsigned long ulCallCount = 0;\r
+const unsigned long ulTx1 = 10UL, ulTx2 = 20UL, ulNumberOfSwitchCases = 3UL;\r
+unsigned long ulRx;\r
+\r
+ /* This function should be called from an interrupt, such as the tick hook\r
+ function vApplicationTickHook(). */\r
+\r
+ configASSERT( xISRQueue );\r
+\r
+ switch( ulCallCount )\r
+ {\r
+ case 0:\r
+ /* The queue is empty. Write ulTx1 to the queue. In this demo the\r
+ last parameter is not used because there are no tasks blocked on\r
+ this queue. */\r
+ xQueueOverwriteFromISR( xISRQueue, &ulTx1, NULL );\r
+ break;\r
+\r
+ case 1:\r
+ /* The queue already holds ulTx1. Overwrite the value in the queue\r
+ with ulTx2. */\r
+ xQueueOverwriteFromISR( xISRQueue, &ulTx2, NULL );\r
+ break;\r
+\r
+ case 2:\r
+ /* Read from the queue to empty the queue again. The value read\r
+ should be ulTx2. */\r
+ xQueueReceiveFromISR( xISRQueue, &ulRx, NULL );\r
+\r
+ if( ulRx != ulTx2 )\r
+ {\r
+ xISRTestStatus = pdFAIL;\r
+ }\r
+ break;\r
+ }\r
+\r
+ /* Run the next case in the switch statement above next time this function\r
+ is called. */\r
+ ulCallCount++;\r
+\r
+ if( ulCallCount >= ulNumberOfSwitchCases )\r
+ {\r
+ /* Go back to the start. */\r
+ ulCallCount = 0;\r
+ }\r
+}\r
\r
*/\r
#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )\r
\r
+/**\r
+ * queue. h\r
+ * <pre>\r
+ portBASE_TYPE xQueueOverwriteFromISR(\r
+ xQueueHandle xQueue,\r
+ const void * pvItemToQueue,\r
+ portBASE_TYPE *pxHigherPriorityTaskWoken\r
+ );\r
+ * </pre>\r
+ *\r
+ * A version of xQueueOverwrite() that can be used from an interrupt service\r
+ * routine (ISR).\r
+ *\r
+ * Only for use with queues that can hold a single item - so the queue is either\r
+ * empty or full.\r
+ *\r
+ * Post an item on a queue. If the queue is already full then overwrite the\r
+ * value held in the queue. The item is queued by copy, not by reference.\r
+ *\r
+ * @param xQueue The handle to the queue on which the item is to be posted.\r
+ *\r
+ * @param pvItemToQueue A pointer to the item that is to be placed on the\r
+ * queue. The size of the items the queue will hold was defined when the\r
+ * queue was created, so this many bytes will be copied from pvItemToQueue\r
+ * into the queue storage area.\r
+ *\r
+ * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set\r
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task\r
+ * to unblock, and the unblocked task has a priority higher than the currently\r
+ * running task. If xQueueSendFromISR() sets this value to pdTRUE then\r
+ * a context switch should be requested before the interrupt is exited.\r
+ *\r
+ * @return xQueueOverwriteFromISR() is a macro that calls \r
+ * xQueueGenericSendFromISR(), and therefore has the same return values as \r
+ * xQueueSendToFrontFromISR(). However, as xQueueOverwriteFromISR() will write \r
+ * to the queue even when the queue is full pdPASS will be returned in all cases \r
+ * (errQUEUE_FULL will never be returned).\r
+ *\r
+ * Example usage:\r
+ <pre>\r
+\r
+ xQueueHandle xQueue;\r
+ \r
+ void vFunction( void *pvParameters )\r
+ {\r
+ // Create a queue to hold one unsigned long value. It is strongly\r
+ // recommended *not* to use xQueueOverwrite() on queues that can\r
+ // contain more than one value, and doing so will trigger an assertion\r
+ // if configASSERT() is defined.\r
+ xQueue = xQueueCreate( 1, sizeof( unsigned long ) );\r
+}\r
+\r
+void vAnInterruptHandler( void )\r
+{\r
+// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.\r
+portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
+unsigned long ulVarToSend, ulValReceived;\r
+\r
+ // Write the value 10 to the queue using xQueueOverwriteFromISR().\r
+ ulVarToSend = 10;\r
+ xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );\r
+\r
+ // The queue is full, but calling xQueueOverwriteFromISR() again will still\r
+ // pass because the value held in the queue will be overwritten with the\r
+ // new value.\r
+ ulVarToSend = 100;\r
+ xQueueOverwrite( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );\r
+\r
+ // Reading from the queue will now return 100.\r
+\r
+ // ...\r
+}\r
+ </pre>\r
+ * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR\r
+ * \ingroup QueueManagement\r
+ */\r
+#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE )\r
+\r
/**\r
* queue. h\r
* <pre>\r