\r
/* For test purposes the priority of the sending task is changed after every\r
queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */\r
-#define queuesetPRIORITY_CHANGE_LOOPS ( ( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ) * 3 )\r
+#define queuesetPRIORITY_CHANGE_LOOPS ( ( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ) * 2 )\r
\r
/* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */\r
#define queuesetISR_TX_PERIOD ( 100UL )\r
\r
+/* A delay inserted when the Tx task changes its priority to be above the idle\r
+task priority to ensure the idle priority tasks get some CPU time before the\r
+next iteration of the queue set Tx task. */\r
+#define queuesetTX_LOOP_DELAY ( 200 / portTICK_RATE_MS )\r
+\r
/* The allowable maximum deviation between a received value and the expected\r
received value. A deviation will occur when data is received from a queue\r
inside an ISR in between a task receiving from a queue and the task checking\r
testing of limits easier (don't have to deal with wrapping values). */\r
#define queuesetIGNORED_BOUNDARY ( queuesetALLOWABLE_RX_DEVIATION * 2 )\r
\r
+typedef enum\r
+{\r
+ eEqualPriority = 0, /* Tx and Rx tasks have the same priority. */\r
+ eTxHigherPriority, /* The priority of the Tx task is above that of the Rx task. */\r
+ eTxLowerPriority /* The priority of the Tx task is below that of the Rx task. */\r
+} eRelativePriorities;\r
+\r
/*\r
* The task that periodically sends to the queue set.\r
*/\r
*/\r
static portBASE_TYPE prvCheckReceivedValueWithinExpectedRange( unsigned long ulReceived, unsigned long ulExpectedReceived );\r
\r
+/*\r
+ * Increase test coverage by occasionally change the priorities of the two tasks\r
+ * relative to each other. */\r
+static void prvChangeRelativePriorities( void );\r
+\r
/*\r
* Local pseudo random number seed and return functions. Used to avoid calls\r
* to the standard library.\r
/* Used by the pseudo random number generator. */\r
static unsigned long ulNextRand = 0;\r
\r
+/* The task handles are stored so their priorities can be changed. */\r
+xTaskHandle xQueueSetSendingTask, xQueueSetReceivingTask;\r
+\r
/*-----------------------------------------------------------*/\r
\r
void vStartQueueSetTasks( void )\r
{\r
-xTaskHandle xQueueSetSendingTask;\r
-\r
/* Create the two queues. The handle of the sending task is passed into\r
the receiving task using the task parameter. The receiving task uses the\r
handle to resume the sending task after it has created the queues. */\r
xTaskCreate( prvQueueSetSendingTask, ( signed char * ) "SetTx", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask );\r
- xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, NULL );\r
+ xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, &xQueueSetReceivingTask );\r
\r
/* It is important that the sending task does not attempt to write to a\r
queue before the queue has been created. It is therefore placed into the\r
{\r
unsigned long ulTaskTxValue = 0, ulQueueToWriteTo;\r
xQueueHandle xQueueInUse;\r
-unsigned portBASE_TYPE uxPriority = queuesetMEDIUM_PRIORITY, ulLoops = 0;\r
\r
/* Remove compiler warning about the unused parameter. */\r
( void ) pvParameters;\r
ulTaskTxValue = 0;\r
}\r
\r
- /* Occasionally change the task priority relative to the priority of\r
- the receiving task. */\r
- ulLoops++;\r
- if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS )\r
- {\r
- ulLoops = 0;\r
- uxPriority++;\r
- if( uxPriority > queuesetHIGH_PRIORITY )\r
- {\r
- uxPriority = queuesetLOW_PRIORITY;\r
- }\r
+ /* Increase test coverage by occasionally change the priorities of the\r
+ two tasks relative to each other. */\r
+ prvChangeRelativePriorities();\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
\r
- vTaskPrioritySet( NULL, uxPriority );\r
+static void prvChangeRelativePriorities( void )\r
+{\r
+static unsigned portBASE_TYPE ulLoops = 0;\r
+static eRelativePriorities ePriorities = eEqualPriority;\r
+\r
+ /* Occasionally change the task priority relative to the priority of\r
+ the receiving task. */\r
+ ulLoops++;\r
+ if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS )\r
+ {\r
+ ulLoops = 0;\r
+\r
+ switch( ePriorities )\r
+ {\r
+ case eEqualPriority:\r
+ /* Both tasks are running with medium priority. Now lower the\r
+ priority of the receiving task so the Tx task has the higher\r
+ relative priority. */\r
+ vTaskPrioritySet( xQueueSetReceivingTask, queuesetLOW_PRIORITY );\r
+ ePriorities = eTxHigherPriority;\r
+ break;\r
+\r
+ case eTxHigherPriority:\r
+ /* The Tx task is running with a higher priority than the Rx\r
+ task. Switch the priorities around so the Rx task has the\r
+ higher relative priority. */\r
+ vTaskPrioritySet( xQueueSetReceivingTask, queuesetMEDIUM_PRIORITY );\r
+ vTaskPrioritySet( xQueueSetSendingTask, queuesetLOW_PRIORITY );\r
+ ePriorities = eTxLowerPriority;\r
+ break;\r
+\r
+ case eTxLowerPriority:\r
+ /* The Tx task is running with a lower priority than the Rx\r
+ task. Make the priorities equal again. */\r
+ vTaskPrioritySet( xQueueSetSendingTask, queuesetMEDIUM_PRIORITY );\r
+ ePriorities = eEqualPriority;\r
+\r
+ /* When both tasks are using a non-idle priority the queue set\r
+ tasks will starve idle priority tasks of execution time - so\r
+ relax a bit before the next iteration to minimise the impact. */\r
+ vTaskDelay( queuesetTX_LOOP_DELAY );\r
+\r
+ break;\r
}\r
}\r
}\r
/* Demo app include files. */\r
#include "recmutex.h"\r
\r
-/* Priorities assigned to the three tasks. */\r
-#define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+/* Priorities assigned to the three tasks. recmuCONTROLLING_TASK_PRIORITY can\r
+be overridden by a definition in FreeRTOSConfig.h. */\r
+#ifndef recmuCONTROLLING_TASK_PRIORITY\r
+ #define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#endif\r
#define recmuBLOCKING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
#define recmuPOLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 )\r
\r
/* Misc. */\r
#define recmuSHORT_DELAY ( 20 / portTICK_RATE_MS )\r
#define recmuNO_DELAY ( ( portTickType ) 0 )\r
-#define recmuTHREE_TICK_DELAY ( ( portTickType ) 3 )\r
+#define recmuFIVE_TICK_DELAY ( ( portTickType ) 5 )\r
\r
/* The three tasks as described at the top of this file. */\r
static void prvRecursiveMutexControllingTask( void *pvParameters );\r
long enough to ensure the polling task will execute again before the\r
block time expires. If the block time does expire then the error\r
flag will be set here. */\r
- if( xSemaphoreTakeRecursive( xMutex, recmuTHREE_TICK_DELAY ) != pdPASS )\r
+ if( xSemaphoreTakeRecursive( xMutex, recmuFIVE_TICK_DELAY ) != pdPASS )\r
{\r
xErrorOccurred = pdTRUE;\r
}\r
}\r
\r
/* Having given it back the same number of times as it was taken, we\r
- should no longer be the mutex owner, so the next give sh ould fail. */\r
+ should no longer be the mutex owner, so the next give should fail. */\r
if( xSemaphoreGiveRecursive( xMutex ) == pdPASS )\r
{\r
xErrorOccurred = pdTRUE;\r
stall can be detected. */\r
uxControllingCycles++;\r
\r
- /* Suspend ourselves to the blocking task can execute. */\r
+ /* Suspend ourselves so the blocking task can execute. */\r
xControllingIsSuspended = pdTRUE;\r
vTaskSuspend( NULL );\r
xControllingIsSuspended = pdFALSE;\r
\r
#if( INCLUDE_uxTaskPriorityGet == 1 )\r
{\r
+ /* Check priority inherited. */\r
configASSERT( uxTaskPriorityGet( NULL ) == recmuCONTROLLING_TASK_PRIORITY );\r
}\r
#endif /* INCLUDE_uxTaskPriorityGet */\r
{\r
xErrorOccurred = pdTRUE;\r
}\r
+\r
+ #if( INCLUDE_uxTaskPriorityGet == 1 )\r
+ {\r
+ /* Check priority disinherited. */\r
+ configASSERT( uxTaskPriorityGet( NULL ) == recmuPOLLING_TASK_PRIORITY );\r
+ }\r
+ #endif /* INCLUDE_uxTaskPriorityGet */\r
}\r
}\r
\r