#define configTICK_RATE_HZ ( ( portTickType ) 1000 )\r
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )\r
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 )\r
-#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 7 * 1024 ) )\r
+#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 45 * 1024 ) )\r
#define configMAX_TASK_NAME_LEN ( 10 )\r
#define configUSE_TRACE_FACILITY 0\r
#define configUSE_16_BIT_TICKS 0\r
#define configQUEUE_REGISTRY_SIZE 0\r
#define configGENERATE_RUN_TIME_STATS 0\r
#define configCHECK_FOR_STACK_OVERFLOW 2\r
-#define configUSE_RECURSIVE_MUTEXES 0\r
+#define configUSE_RECURSIVE_MUTEXES 1\r
#define configUSE_MALLOC_FAILED_HOOK 1\r
#define configUSE_APPLICATION_TASK_TAG 0\r
#define configUSE_COUNTING_SEMAPHORES 0\r
/* Software timer definitions. */\r
#define configUSE_TIMERS 1\r
#define configTIMER_TASK_PRIORITY ( 3 )\r
-#define configTIMER_QUEUE_LENGTH 5\r
+#define configTIMER_QUEUE_LENGTH 10\r
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )\r
\r
/* Set the following definitions to 1 to include the API function, or zero\r
#define INCLUDE_vTaskDelayUntil 1\r
#define INCLUDE_vTaskDelay 1\r
\r
+/* Override some of the priorities set in the common demo tasks. This is\r
+required to ensure false positive timing errors are not reported. */\r
+#define bktPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )\r
+#define bktSECONDARY_PRIORITY ( configMAX_PRIORITIES - 4 )\r
+\r
/* Use the system definition, if there is one */\r
#ifdef __NVIC_PRIO_BITS\r
#define configPRIO_BITS __NVIC_PRIO_BITS\r
\r
/* Common demo includes. */\r
#include "partest.h"\r
-\r
+#include "flash.h"\r
+#include "BlockQ.h"\r
+#include "death.h"\r
+#include "blocktim.h"\r
+#include "semtest.h"\r
+#include "GenQTest.h"\r
+#include "QPeek.h"\r
+#include "recmutex.h"\r
+#include "TimerDemo.h"\r
\r
/* Priorities at which the tasks are created. */\r
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
/* The number of items the queue can hold. This is 1 as the receive task\r
will remove items as they are added, meaning the send task should always find\r
the queue empty. */\r
-#define mainQUEUE_LENGTH ( 1 )\r
+#define mainQUEUE_LENGTH ( 1 )\r
+\r
+#define mainCHECK_LED 0x07UL\r
+#define mainTIMER_CONTROLLED_LED 0x06UL\r
+#define mainTASK_CONTROLLED_LED 0x05UL\r
+\r
+#define mainTIMER_TEST_PERIOD ( 50 )\r
+\r
+#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )\r
+#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )\r
+#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
+#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
+#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
\r
-#define mainTASK_CONTROLLED_LED 0x01UL\r
-#define mainTIMER_CONTROLLED_LED 0x02UL\r
/*-----------------------------------------------------------*/\r
\r
/*\r
*/\r
static void vLEDTimerCallback( xTimerHandle xTimer );\r
\r
+static void vCheckTimerCallback( xTimerHandle xTimer );\r
+\r
+/*\r
+ * This is not a 'standard' partest function, so the prototype is not in\r
+ * partest.h.
+ */\r
+void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue );\r
+\r
/*-----------------------------------------------------------*/\r
\r
/* The queue used by both tasks. */\r
function. */\r
static xTimerHandle xLEDTimer = NULL;\r
\r
+static xTimerHandle xCheckTimer = NULL;\r
+\r
+/* The status message that is displayed at the bottom of the "task stats" web\r
+page, which is served by the uIP task. This will report any errors picked up\r
+by the reg test task. */\r
+static const char *pcStatusMessage = NULL;\r
\r
\r
/*-----------------------------------------------------------*/\r
vLEDTimerCallback /* The callback function that switches the LED off. */\r
);\r
\r
+ xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer", /* A text name, purely to help debugging. */\r
+ ( 3000 / portTICK_RATE_MS ), /* The timer period, in this case 3000ms (3s). */\r
+ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */\r
+ ( void * ) 0, /* The ID is not used, so can be set to anything. */\r
+ vCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */\r
+ );\r
+\r
+ vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
+ vCreateBlockTimeTasks();\r
+ vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
+ vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY );\r
+ vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );\r
+ vStartQueuePeekTasks();\r
+ vStartRecursiveMutexTasks();\r
+ vStartTimerDemoTask( mainTIMER_TEST_PERIOD );\r
+\r
/* Start the tasks and timer running. */\r
vTaskStartScheduler();\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void vCheckTimerCallback( xTimerHandle xTimer )\r
+{\r
+ /* Check the standard demo tasks are running without error. */\r
+ if( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
+ {\r
+ /* Increase the rate at which this task cycles, which will increase the\r
+ rate at which mainCHECK_LED flashes to give visual feedback that an error\r
+ has occurred. */\r
+ pcStatusMessage = "Error: GenQueue";\r
+// xPrintf( pcStatusMessage );\r
+ }\r
+\r
+ if( xAreQueuePeekTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "Error: QueuePeek\r\n";\r
+// xPrintf( pcStatusMessage );\r
+ }\r
+\r
+ if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "Error: BlockQueue\r\n";\r
+// xPrintf( pcStatusMessage );\r
+ }\r
+\r
+ if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "Error: BlockTime\r\n";\r
+// xPrintf( pcStatusMessage );\r
+ }\r
+\r
+ if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "Error: SemTest\r\n";\r
+// xPrintf( pcStatusMessage );\r
+ }\r
+\r
+ if( xIsCreateTaskStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "Error: Death\r\n";\r
+// xPrintf( pcStatusMessage );\r
+ }\r
+\r
+ if( xAreRecursiveMutexTasksStillRunning() != pdTRUE )\r
+ {\r
+ pcStatusMessage = "Error: RecMutex\r\n";\r
+// xPrintf( pcStatusMessage );\r
+ }\r
+\r
+ if( xAreTimerDemoTasksStillRunning( ( 3000 / portTICK_RATE_MS ) ) != pdTRUE )\r
+ {\r
+ pcStatusMessage = "Error: TimerDemo";\r
+ }\r
+\r
+ /* Toggle the check LED to give an indication of the system status. If\r
+ the LED toggles every 5 seconds then everything is ok. A faster toggle\r
+ indicates an error. */\r
+ vParTestToggleLED( mainCHECK_LED );\r
+\r
+ if( pcStatusMessage != NULL )\r
+ {\r
+ /* The block time is set to zero as a timer callback must *never*\r
+ attempt to block. */\r
+ xTimerChangePeriod( xCheckTimer, ( 500 / portTICK_RATE_MS ), 0 );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
static void vLEDTimerCallback( xTimerHandle xTimer )\r
{\r
/* The timer has expired - so no button pushes have occurred in the last\r
a critical section because it is accessed from multiple tasks, and the\r
button interrupt - in this trivial case, for simplicity, the critical\r
section is omitted. */\r
- ulGPIOState |= mainTIMER_CONTROLLED_LED;\r
- MSS_GPIO_set_outputs( ulGPIOState );\r
+ vParTestSetLED( mainTIMER_CONTROLLED_LED, pdFALSE );\r
}\r
/*-----------------------------------------------------------*/\r
\r
/* The button was pushed, so ensure the LED is on before resetting the\r
LED timer. The LED timer will turn the LED off if the button is not\r
pushed within 5000ms. */\r
- ulGPIOState &= ~mainTIMER_CONTROLLED_LED;\r
- MSS_GPIO_set_outputs( ulGPIOState );\r
+ vParTestSetLEDFromISR( mainTIMER_CONTROLLED_LED, pdTRUE );\r
\r
/* This interrupt safe FreeRTOS function can be called from this interrupt\r
because the interrupt priority is below the\r
portTickType xNextWakeTime;\r
const unsigned long ulValueToSend = 100UL;\r
\r
+ /* The suicide tasks must be created last as they need to know how many\r
+ tasks were running prior to their creation in order to ascertain whether\r
+ or not the correct/expected number of tasks are running at any given time. */\r
+ vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );\r
+\r
+ xTimerStart( xCheckTimer, portMAX_DELAY );\r
+\r
/* Initialise xNextWakeTime - this only needs to be done once. */\r
xNextWakeTime = xTaskGetTickCount();\r
\r
because it is accessed from multiple tasks, and the button interrupt \r
- in this trivial case, for simplicity, the critical section is \r
omitted. */\r
- if( ( ulGPIOState & mainTASK_CONTROLLED_LED ) != 0 )\r
- {\r
- ulGPIOState &= ~mainTASK_CONTROLLED_LED;\r
- }\r
- else\r
- {\r
- ulGPIOState |= mainTASK_CONTROLLED_LED;\r
- }\r
- MSS_GPIO_set_outputs( ulGPIOState );\r
+ vParTestToggleLED( mainTASK_CONTROLLED_LED );\r
}\r
}\r
}\r