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