]> git.sur5r.net Git - freertos/commitdiff
Add in interrupt nesting test.
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 30 Jan 2014 14:45:48 +0000 (14:45 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Thu, 30 Jan 2014 14:45:48 +0000 (14:45 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2187 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/.project
FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOSConfig.h
FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/FreeRTOS_tick_config.c
FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/IntQueueTimer.c
FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main_full.c

index 1d9dcfbc6d4c48e8b2058b19cb3aa9699d307aaf..4431c9a6659123141b64da3c42759d09b8d5f04c 100644 (file)
                        <type>1</type>\r
                        <locationURI>FREERTOS_ROOT/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c</locationURI>\r
                </link>\r
+               <link>\r
+                       <name>src/Standard_Demo_Tasks/IntQueue.c</name>\r
+                       <type>1</type>\r
+                       <locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal/IntQueue.c</locationURI>\r
+               </link>\r
        </linkedResources>\r
        <filteredResources>\r
                <filter>\r
index e2d387664c07fa449347d0123041506bd50758ad..9130dc805b183cf93effd328bbaa4ce5a4234685 100644 (file)
 #define configUSE_QUEUE_SETS                                   1\r
 \r
 /* Co-routine definitions. */\r
-#define configUSE_CO_ROUTINES                  0\r
-#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )\r
+#define configUSE_CO_ROUTINES                                  0\r
+#define configMAX_CO_ROUTINE_PRIORITIES                ( 2 )\r
 \r
 /* Software timer definitions. */\r
-#define configUSE_TIMERS                               1\r
-#define configTIMER_TASK_PRIORITY              ( configMAX_PRIORITIES - 1 )\r
-#define configTIMER_QUEUE_LENGTH               5\r
-#define configTIMER_TASK_STACK_DEPTH   ( configMINIMAL_STACK_SIZE * 2 )\r
+#define configUSE_TIMERS                                               1\r
+#define configTIMER_TASK_PRIORITY                              ( configMAX_PRIORITIES - 1 )\r
+#define configTIMER_QUEUE_LENGTH                               5\r
+#define configTIMER_TASK_STACK_DEPTH                   ( configMINIMAL_STACK_SIZE * 2 )\r
 \r
 /* Set the following definitions to 1 to include the API function, or zero\r
 to exclude the API function. */\r
@@ -165,13 +165,14 @@ Zynq MPU. */
 #define configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ( -0xf00 )\r
 #define configUNIQUE_INTERRUPT_PRIORITIES                              32\r
 \r
-/* Run time stats gathering definitions. */\r
-unsigned long ulGetRunTimeCounterValue( void );\r
-void vInitialiseRunTimeStats( void );\r
-\r
+/* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS is not required because the time base\r
+comes from the ulHighFrequencyTimerCounts variable which is incremented in a\r
+high frequency timer that is already being started as part of the interrupt\r
+nesting test. */\r
 #define configGENERATE_RUN_TIME_STATS  1\r
-#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vInitialiseRunTimeStats()\r
-#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()\r
+extern volatile uint32_t ulHighFrequencyTimerCounts;\r
+#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()\r
+#define portGET_RUN_TIME_COUNTER_VALUE() ulHighFrequencyTimerCounts\r
 \r
 /* The size of the global output buffer that is available for use when there\r
 are multiple command interpreters running at once (for example, one on a UART\r
index 601311059d3e3db6dbdf2f0fb55f340ce12f402a..0134d31d7c9d6883456aed594ea380a92051ee45 100644 (file)
@@ -88,6 +88,7 @@ BaseType_t xStatus;
 extern void FreeRTOS_Tick_Handler( void );\r
 XScuTimer_Config *pxTimerConfig;\r
 XScuGic_Config *pxGICConfig;\r
+const uint8_t ucRisingEdge = 3;\r
 \r
        /* This function is called with the IRQ interrupt disabled, and the IRQ\r
        interrupt should be left disabled.  It is enabled automatically when the\r
@@ -99,8 +100,11 @@ XScuGic_Config *pxGICConfig;
        xStatus = XScuGic_CfgInitialize( &xInterruptController, pxGICConfig, pxGICConfig->CpuBaseAddress );\r
        configASSERT( xStatus == XST_SUCCESS );\r
 \r
+       /* The priority must be the lowest possible. */\r
+       XScuGic_SetPriorityTriggerType( &xInterruptController, XPAR_SCUTIMER_INTR, portLOWEST_USABLE_INTERRUPT_PRIORITY << portPRIORITY_SHIFT, ucRisingEdge );\r
+\r
        /* Install the FreeRTOS tick handler. */\r
-       xStatus = XScuGic_Connect(&xInterruptController, XPAR_SCUTIMER_INTR, (Xil_ExceptionHandler) FreeRTOS_Tick_Handler, (void *)&xTimer);\r
+       xStatus = XScuGic_Connect( &xInterruptController, XPAR_SCUTIMER_INTR, (Xil_ExceptionHandler) FreeRTOS_Tick_Handler, ( void * ) &xTimer );\r
        configASSERT( xStatus == XST_SUCCESS );\r
 \r
        /* Initialise the timer. */\r
@@ -127,21 +131,6 @@ XScuGic_Config *pxGICConfig;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-/*\r
- * Crude implementation of a run time counter used to measure how much time\r
- * each task spends in the Running state.\r
- */\r
-unsigned long ulGetRunTimeCounterValue( void )\r
-{\r
-       return 0;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vInitialiseRunTimeStats( void )\r
-{\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
 void vClearTickInterrupt( void )\r
 {\r
        XScuTimer_ClearInterruptStatus( &xTimer );\r
index c0bd4c077878912f9a3f89f09c5fe482e7f1423e..1a24a4cba900284bf6b0494c478521c1321b8c6a 100644 (file)
     1 tab == 4 spaces!\r
 */\r
 \r
+/*\r
+ * This file initialises three timers as follows:\r
+ *\r
+ * Timer 0 and Timer 1 provide the interrupts that are used with the IntQ\r
+ * standard demo tasks, which test interrupt nesting and using queues from\r
+ * interrupts.  Both these interrupts operate below the maximum syscall\r
+ * interrupt priority.\r
+ *\r
+ * Timer 2 is a much higher frequency timer that tests the nesting of interrupts\r
+ * that execute above the maximum syscall interrupt priority.\r
+ *\r
+ * All the timers can nest with the tick interrupt - creating a maximum\r
+ * interrupt nesting depth of 4.\r
+ *\r
+ * For convenience, the high frequency timer is also used to provide the time\r
+ * base for the run time stats.\r
+ */\r
+\r
 /* Scheduler includes. */\r
 #include "FreeRTOS.h"\r
 \r
 #include "IntQueue.h"\r
 \r
 /* Xilinx includes. */\r
-#include "xstatus.h"\r
-#include "xil_io.h"\r
-#include "xil_exception.h"\r
 #include "xttcps.h"\r
 #include "xscugic.h"\r
 \r
+/* The frequencies at which the first two timers expire are slightly offset to\r
+ensure they don't remain synchronised.  The frequency of the interrupt that\r
+operates above the max syscall interrupt priority is 10 times faster so really\r
+hammers the interrupt entry and exit code. */\r
+#define tmrTIMERS_USED 3\r
 #define tmrTIMER_0_FREQUENCY   ( 2000UL )\r
 #define tmrTIMER_1_FREQUENCY   ( 2001UL )\r
+#define tmrTIMER_2_FREQUENCY   ( 20000UL )\r
 \r
-#define TTC_TICK_DEVICE_ID     XPAR_XTTCPS_0_DEVICE_ID\r
-#define TTC_TICK_INTR_ID       XPAR_XTTCPS_0_INTR\r
-#define INTC_DEVICE_ID         XPAR_SCUGIC_SINGLE_DEVICE_ID\r
+/*-----------------------------------------------------------*/\r
 \r
 /*\r
- * Constants to set the basic operating parameters.\r
- * PWM_DELTA_DUTY is critical to the running time of the test. Smaller values\r
- * make the test run longer.\r
+ * The single interrupt service routines that is used to service all three\r
+ * timers.\r
  */\r
-#define        TICK_TIMER_FREQ_HZ      100  /* Tick timer counter's output frequency */\r
+static void prvTimerHandler( void *CallBackRef );\r
 \r
-#define TICKS_PER_CHANGE_PERIOD        TICK_TIMER_FREQ_HZ /* Tick signals per update */\r
+/*-----------------------------------------------------------*/\r
 \r
-#define TIMERS_USED    2\r
+/* Hardware constants. */\r
+static const BaseType_t xDeviceIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_0_DEVICE_ID, XPAR_XTTCPS_1_DEVICE_ID, XPAR_XTTCPS_2_DEVICE_ID };\r
+static const BaseType_t xInterruptIDs[ tmrTIMERS_USED ] = { XPAR_XTTCPS_0_INTR, XPAR_XTTCPS_1_INTR, XPAR_XTTCPS_2_INTR };\r
 \r
-static void TickHandler(void *CallBackRef);\r
+/* Timer configuration settings. */\r
+typedef struct\r
+{\r
+       uint32_t OutputHz;      /* Output frequency. */\r
+       uint16_t Interval;      /* Interval value. */\r
+       uint8_t Prescaler;      /* Prescaler value. */\r
+       uint16_t Options;       /* Option settings. */\r
+} TmrCntrSetup;\r
 \r
-static volatile uint8_t UpdateFlag;    /* Flag to update the seconds counter */\r
-static uint32_t TickCount;             /* Ticker interrupts between seconds change */\r
-static XTtcPs TtcPsInst[ TIMERS_USED ];  /* Timer counter instance */\r
+static TmrCntrSetup xTimerSettings[ tmrTIMERS_USED ] =\r
+{\r
+       { tmrTIMER_0_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE },\r
+       { tmrTIMER_1_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE },\r
+       { tmrTIMER_2_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE }\r
+};\r
+\r
+/* Lower priority number means higher logical priority, so\r
+configMAX_API_CALL_INTERRUPT_PRIORITY - 1 is above the maximum system call\r
+interrupt priority. */\r
+static const UBaseType_t uxInterruptPriorities[ tmrTIMERS_USED ] =\r
+{\r
+       configMAX_API_CALL_INTERRUPT_PRIORITY + 1,\r
+       configMAX_API_CALL_INTERRUPT_PRIORITY,\r
+       configMAX_API_CALL_INTERRUPT_PRIORITY - 1\r
+}\r
+static XTtcPs xTimerInstances[ tmrTIMERS_USED ];\r
 \r
-typedef struct {\r
-       u32 OutputHz;   /* Output frequency */\r
-       u16 Interval;   /* Interval value */\r
-       u8 Prescaler;   /* Prescaler value */\r
-       u16 Options;    /* Option settings */\r
-} TmrCntrSetup;\r
+/* Used to provide a means of ensuring the intended interrupt nesting depth is\r
+actually being reached. */\r
+extern uint32_t ulPortInterruptNesting;\r
+static uint32_t ulMaxRecordedNesting = 0;\r
 \r
-static const TmrCntrSetup SettingsTable[ TIMERS_USED ] = {     { tmrTIMER_0_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE },\r
-                                                                                                                       { tmrTIMER_1_FREQUENCY, 0, 0, XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE } };\r
+/* For convenience the high frequency timer increments a variable that is then\r
+used as the time base for the run time stats. */\r
+volatile uint32_t ulHighFrequencyTimerCounts = 0;\r
 \r
-BaseType_t DeviceIDs[ TIMERS_USED ] = { XPAR_XTTCPS_0_DEVICE_ID, XPAR_XTTCPS_1_DEVICE_ID };\r
-BaseType_t InterruptIDs[ TIMERS_USED ] = { XPAR_XTTCPS_0_INTR, XPAR_XTTCPS_1_INTR };\r
+/*-----------------------------------------------------------*/\r
 \r
 void vInitialiseTimerForIntQueueTest( void )\r
 {\r
-int Status;\r
-TmrCntrSetup *TimerSetup;\r
-XTtcPs *TtcPsTick;\r
+BaseType_t xStatus;\r
+TmrCntrSetup *pxTimerSettings;\r
 extern XScuGic xInterruptController;\r
 BaseType_t xTimer;\r
-XTtcPs *Timer;\r
-XTtcPs_Config *Config;\r
+XTtcPs *pxTimerInstance;\r
+XTtcPs_Config *pxTimerConfiguration;\r
+const uint8_t ucRisingEdge = 3;\r
 \r
-       for( xTimer = 0; xTimer < TIMERS_USED; xTimer++ )\r
+       for( xTimer = 0; xTimer < tmrTIMERS_USED; xTimer++ )\r
        {\r
+               /* Look up the timer's configuration. */\r
+               pxTimerInstance = &( xTimerInstances[ xTimer ] );\r
+               pxTimerConfiguration = XTtcPs_LookupConfig( xDeviceIDs[ xTimer ] );\r
+               configASSERT( pxTimerConfiguration );\r
+\r
+               pxTimerSettings = &( xTimerSettings[ xTimer ] );\r
+\r
+               /* Initialise the device. */\r
+               xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress );\r
+               if( xStatus != XST_SUCCESS )\r
+               {\r
+                       /* Not sure how to do this before XTtcPs_CfgInitialize is called\r
+                       as pxTimerInstance is set within XTtcPs_CfgInitialize(). */\r
+                       XTtcPs_Stop( pxTimerInstance );\r
+                       xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress );\r
+                       configASSERT( xStatus == XST_SUCCESS );\r
+               }\r
+\r
+               /* Set the options. */\r
+               XTtcPs_SetOptions( pxTimerInstance, pxTimerSettings->Options );\r
+\r
+               /* The timer frequency is preset in the pxTimerSettings structure.\r
+               Derive the values for the other structure members. */\r
+               XTtcPs_CalcIntervalFromFreq( pxTimerInstance, pxTimerSettings->OutputHz, &( pxTimerSettings->Interval ), &( pxTimerSettings->Prescaler ) );\r
+\r
+               /* Set the interval and prescale. */\r
+               XTtcPs_SetInterval( pxTimerInstance, pxTimerSettings->Interval );\r
+               XTtcPs_SetPrescaler( pxTimerInstance, pxTimerSettings->Prescaler );\r
+\r
+               /* The priority must be the lowest possible. */\r
+               XScuGic_SetPriorityTriggerType( &xInterruptController, xInterruptIDs[ xTimer ], uxInterruptPriorities[ xTimer ] << portPRIORITY_SHIFT, ucRisingEdge );\r
 \r
-               TimerSetup = &( SettingsTable[ xTimer ] );\r
-               Timer = &TtcPsInst[ xTimer ];\r
-\r
-               /*\r
-                * Look up the configuration based on the device identifier\r
-                */\r
-               Config = XTtcPs_LookupConfig(DeviceIDs[ xTimer ]);\r
-               configASSERT( Config );\r
-\r
-               /*\r
-                * Initialize the device\r
-                */\r
-               Status = XTtcPs_CfgInitialize(Timer, Config, Config->BaseAddress);\r
-               configASSERT(Status == XST_SUCCESS);\r
-\r
-               /*\r
-                * Stop the timer first\r
-                */\r
-               XTtcPs_Stop( Timer );\r
-\r
-               /*\r
-                * Set the options\r
-                */\r
-               XTtcPs_SetOptions(Timer, TimerSetup->Options);\r
-\r
-               /*\r
-                * Timer frequency is preset in the TimerSetup structure,\r
-                * however, the value is not reflected in its other fields, such as\r
-                * IntervalValue and PrescalerValue. The following call will map the\r
-                * frequency to the interval and prescaler values.\r
-                */\r
-               XTtcPs_CalcIntervalFromFreq(Timer, TimerSetup->OutputHz,\r
-                       &(TimerSetup->Interval), &(TimerSetup->Prescaler));\r
-\r
-               /*\r
-                * Set the interval and prescale\r
-                */\r
-               XTtcPs_SetInterval(Timer, TimerSetup->Interval);\r
-               XTtcPs_SetPrescaler(Timer, TimerSetup->Prescaler);\r
-\r
-\r
-               /*\r
-                * Connect to the interrupt controller\r
-                */\r
-               Status = XScuGic_Connect(&xInterruptController, InterruptIDs[ xTimer ], (Xil_InterruptHandler)TickHandler, (void *)Timer);\r
-               configASSERT( Status == XST_SUCCESS);\r
-\r
-               /*\r
-                * Enable the interrupt for the Timer counter\r
-                */\r
-               XScuGic_Enable(&xInterruptController, InterruptIDs[ xTimer ]);\r
-\r
-               /*\r
-                * Enable the interrupts for the tick timer/counter\r
-                * We only care about the interval timeout.\r
-                */\r
-               XTtcPs_EnableInterrupts(Timer, XTTCPS_IXR_INTERVAL_MASK);\r
-\r
-               /*\r
-                * Start the tick timer/counter\r
-                */\r
-               XTtcPs_Start(Timer);\r
+               /* Connect to the interrupt controller. */\r
+               xStatus = XScuGic_Connect( &xInterruptController, xInterruptIDs[ xTimer ], ( Xil_InterruptHandler ) prvTimerHandler, ( void * ) pxTimerInstance );\r
+               configASSERT( xStatus == XST_SUCCESS);\r
+\r
+               /* Enable the interrupt in the GIC. */\r
+               XScuGic_Enable( &xInterruptController, xInterruptIDs[ xTimer ] );\r
+\r
+               /* Enable the interrupts in the timer. */\r
+               XTtcPs_EnableInterrupts( pxTimerInstance, XTTCPS_IXR_INTERVAL_MASK );\r
+\r
+               /* Start the timer. */\r
+               XTtcPs_Start( pxTimerInstance );\r
        }\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vT2InterruptHandler( void )\r
+static void prvTimerHandler( void *pvCallBackRef )\r
 {\r
-       portEND_SWITCHING_ISR( xFirstTimerHandler() );\r
-}\r
-/*-----------------------------------------------------------*/\r
+uint32_t ulInterruptStatus;\r
+XTtcPs *pxTimer = ( XTtcPs * ) pvCallBackRef;\r
+BaseType_t xYieldRequired;\r
 \r
-void vT3InterruptHandler( void )\r
-{\r
-       portEND_SWITCHING_ISR( xSecondTimerHandler() );\r
-}\r
-/*-----------------------------------------------------------*/\r
+       /* Read the interrupt status, then write it back to clear the interrupt. */\r
+       ulInterruptStatus = XTtcPs_GetInterruptStatus( pxTimer );\r
+       XTtcPs_ClearInterruptStatus( pxTimer, ulInterruptStatus );\r
 \r
-volatile uint32_t ulTimer1Count = 0, ulTimer2Count = 0;\r
+       /* Only one interrupt event type is expected. */\r
+       configASSERT( ( XTTCPS_IXR_INTERVAL_MASK & ulInterruptStatus ) != 0 );\r
 \r
-static void TickHandler(void *CallBackRef)\r
-{\r
-uint32_t StatusEvent;\r
-XTtcPs *pxTtcPs = (XTtcPs *)CallBackRef;\r
-       /*\r
-        * Read the interrupt status, then write it back to clear the interrupt.\r
-        */\r
-       StatusEvent = XTtcPs_GetInterruptStatus(pxTtcPs);\r
-       XTtcPs_ClearInterruptStatus(pxTtcPs, StatusEvent);\r
-\r
-       if (0 != (XTTCPS_IXR_INTERVAL_MASK & StatusEvent)) {\r
-               if( pxTtcPs->Config.DeviceId == DeviceIDs[ 0 ] )\r
-               {\r
-                       ulTimer1Count++;\r
-               }\r
-               else\r
+       /* Check the device ID to know which IntQueue demo to call. */\r
+       if( pxTimer->Config.DeviceId == xDeviceIDs[ 0 ] )\r
+       {\r
+               xYieldRequired = xFirstTimerHandler();\r
+       }\r
+       else if( pxTimer->Config.DeviceId == xDeviceIDs[ 1 ] )\r
+       {\r
+               xYieldRequired = xSecondTimerHandler();\r
+       }\r
+       else\r
+       {\r
+               /* The high frequency timer is also used to generate the time base for\r
+               the run time state. */\r
+               ulHighFrequencyTimerCounts++;\r
+\r
+               /* Latch the highest interrupt nesting count detected. */\r
+               if( ulPortInterruptNesting > ulMaxRecordedNesting )\r
                {\r
-                       ulTimer2Count++;\r
+                       ulMaxRecordedNesting = ulPortInterruptNesting;\r
                }\r
-               TickCount++;\r
+\r
+               xYieldRequired = pdFALSE;\r
        }\r
-}\r
 \r
-#if 0\r
-int SetupTimer(int DeviceID)\r
-{\r
-       int Status;\r
-       XTtcPs_Config *Config;\r
-       XTtcPs *Timer;\r
-       TmrCntrSetup *TimerSetup;\r
-\r
-       TimerSetup = &SettingsTable;\r
-\r
-       Timer = &TtcPsInst;\r
-       /*\r
-        * Stop the timer first\r
-        */\r
-       XTtcPs_Stop( &TtcPsInst );\r
-\r
-       /*\r
-        * Look up the configuration based on the device identifier\r
-        */\r
-       Config = XTtcPs_LookupConfig(DeviceIDs[ DeviceID ]);\r
-       configASSERT( Config );\r
-\r
-       /*\r
-        * Initialize the device\r
-        */\r
-       Status = XTtcPs_CfgInitialize(Timer, Config, Config->BaseAddress);\r
-       configASSERT(Status == XST_SUCCESS);\r
-\r
-       /*\r
-        * Set the options\r
-        */\r
-       XTtcPs_SetOptions(Timer, TimerSetup->Options);\r
-\r
-       /*\r
-        * Timer frequency is preset in the TimerSetup structure,\r
-        * however, the value is not reflected in its other fields, such as\r
-        * IntervalValue and PrescalerValue. The following call will map the\r
-        * frequency to the interval and prescaler values.\r
-        */\r
-       XTtcPs_CalcIntervalFromFreq(Timer, TimerSetup->OutputHz,\r
-               &(TimerSetup->Interval), &(TimerSetup->Prescaler));\r
-\r
-       /*\r
-        * Set the interval and prescale\r
-        */\r
-       XTtcPs_SetInterval(Timer, TimerSetup->Interval);\r
-       XTtcPs_SetPrescaler(Timer, TimerSetup->Prescaler);\r
-\r
-       return XST_SUCCESS;\r
+       /* If xYieldRequired is not pdFALSE then calling either xFirstTimerHandler()\r
+       or xSecondTimerHandler() resulted in a task leaving the blocked state and\r
+       the task that left the blocked state had a priority higher than the currently\r
+       running task (the task this interrupt interrupted) - so a context switch\r
+       should be performed so the interrupt returns directly to the higher priority\r
+       task.  xYieldRequired is tested inside the following macro. */\r
+       portYIELD_FROM_ISR( xYieldRequired );\r
 }\r
-#endif\r
 \r
index 3019fc0c8755aa7347b37a6ff9af91b854adda15..f6f632573b607b4b3ff974b015c9fdd05647cef1 100644 (file)
@@ -324,6 +324,11 @@ unsigned long ulErrorFound = pdFALSE;
 \r
                /* Check all the demo tasks (other than the flash tasks) to ensure\r
                that they are all still running, and that none have detected an error. */\r
+               if( xAreIntQueueTasksStillRunning() != pdTRUE )\r
+               {\r
+                       ulErrorFound = pdTRUE;\r
+               }\r
+\r
                if( xAreMathsTaskStillRunning() != pdTRUE )\r
                {\r
                        ulErrorFound = pdTRUE;\r