mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-05-02 11:22:03 -04:00
Add in interrupt nesting test.
This commit is contained in:
parent
d898d16c44
commit
2fc4e89b98
|
@ -49,6 +49,11 @@
|
|||
<type>1</type>
|
||||
<locationURI>FREERTOS_ROOT/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c</locationURI>
|
||||
</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>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
|
|
|
@ -132,14 +132,14 @@
|
|||
#define configUSE_QUEUE_SETS 1
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
/* Software timer definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||
#define configTIMER_QUEUE_LENGTH 5
|
||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
|
||||
#define configTIMER_QUEUE_LENGTH 5
|
||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
|
@ -165,13 +165,14 @@ Zynq MPU. */
|
|||
#define configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ( -0xf00 )
|
||||
#define configUNIQUE_INTERRUPT_PRIORITIES 32
|
||||
|
||||
/* Run time stats gathering definitions. */
|
||||
unsigned long ulGetRunTimeCounterValue( void );
|
||||
void vInitialiseRunTimeStats( void );
|
||||
|
||||
/* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS is not required because the time base
|
||||
comes from the ulHighFrequencyTimerCounts variable which is incremented in a
|
||||
high frequency timer that is already being started as part of the interrupt
|
||||
nesting test. */
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vInitialiseRunTimeStats()
|
||||
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
|
||||
extern volatile uint32_t ulHighFrequencyTimerCounts;
|
||||
#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
|
||||
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 );
|
||||
XScuTimer_Config *pxTimerConfig;
|
||||
XScuGic_Config *pxGICConfig;
|
||||
const uint8_t ucRisingEdge = 3;
|
||||
|
||||
/* This function is called with the IRQ interrupt disabled, and the IRQ
|
||||
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 );
|
||||
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. */
|
||||
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 );
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
XScuTimer_ClearInterruptStatus( &xTimer );
|
||||
|
|
|
@ -63,6 +63,24 @@
|
|||
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. */
|
||||
#include "FreeRTOS.h"
|
||||
|
||||
|
@ -71,214 +89,173 @@
|
|||
#include "IntQueue.h"
|
||||
|
||||
/* Xilinx includes. */
|
||||
#include "xstatus.h"
|
||||
#include "xil_io.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xttcps.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_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.
|
||||
* PWM_DELTA_DUTY is critical to the running time of the test. Smaller values
|
||||
* make the test run longer.
|
||||
* The single interrupt service routines that is used to service all three
|
||||
* timers.
|
||||
*/
|
||||
#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);
|
||||
|
||||
static volatile uint8_t UpdateFlag; /* Flag to update the seconds counter */
|
||||
static uint32_t TickCount; /* Ticker interrupts between seconds change */
|
||||
static XTtcPs TtcPsInst[ TIMERS_USED ]; /* Timer counter instance */
|
||||
|
||||
typedef struct {
|
||||
u32 OutputHz; /* Output frequency */
|
||||
u16 Interval; /* Interval value */
|
||||
u8 Prescaler; /* Prescaler value */
|
||||
u16 Options; /* Option settings */
|
||||
/* Timer configuration settings. */
|
||||
typedef struct
|
||||
{
|
||||
uint32_t OutputHz; /* Output frequency. */
|
||||
uint16_t Interval; /* Interval value. */
|
||||
uint8_t Prescaler; /* Prescaler value. */
|
||||
uint16_t Options; /* Option settings. */
|
||||
} TmrCntrSetup;
|
||||
|
||||
static const TmrCntrSetup SettingsTable[ TIMERS_USED ] = { { 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 } };
|
||||
static TmrCntrSetup xTimerSettings[ tmrTIMERS_USED ] =
|
||||
{
|
||||
{ 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 };
|
||||
BaseType_t InterruptIDs[ TIMERS_USED ] = { XPAR_XTTCPS_0_INTR, XPAR_XTTCPS_1_INTR };
|
||||
/* Lower priority number means higher logical priority, so
|
||||
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 )
|
||||
{
|
||||
int Status;
|
||||
TmrCntrSetup *TimerSetup;
|
||||
XTtcPs *TtcPsTick;
|
||||
BaseType_t xStatus;
|
||||
TmrCntrSetup *pxTimerSettings;
|
||||
extern XScuGic xInterruptController;
|
||||
BaseType_t xTimer;
|
||||
XTtcPs *Timer;
|
||||
XTtcPs_Config *Config;
|
||||
XTtcPs *pxTimerInstance;
|
||||
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 ] );
|
||||
Timer = &TtcPsInst[ xTimer ];
|
||||
pxTimerSettings = &( xTimerSettings[ xTimer ] );
|
||||
|
||||
/*
|
||||
* Look up the configuration based on the device identifier
|
||||
*/
|
||||
Config = XTtcPs_LookupConfig(DeviceIDs[ xTimer ]);
|
||||
configASSERT( Config );
|
||||
/* Initialise the device. */
|
||||
xStatus = XTtcPs_CfgInitialize( pxTimerInstance, pxTimerConfiguration, pxTimerConfiguration->BaseAddress );
|
||||
if( xStatus != XST_SUCCESS )
|
||||
{
|
||||
/* 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 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the device
|
||||
*/
|
||||
Status = XTtcPs_CfgInitialize(Timer, Config, Config->BaseAddress);
|
||||
configASSERT(Status == XST_SUCCESS);
|
||||
/* Set the options. */
|
||||
XTtcPs_SetOptions( pxTimerInstance, pxTimerSettings->Options );
|
||||
|
||||
/*
|
||||
* Stop the timer first
|
||||
*/
|
||||
XTtcPs_Stop( Timer );
|
||||
/* The timer frequency is preset in the pxTimerSettings structure.
|
||||
Derive the values for the other structure members. */
|
||||
XTtcPs_CalcIntervalFromFreq( pxTimerInstance, pxTimerSettings->OutputHz, &( pxTimerSettings->Interval ), &( pxTimerSettings->Prescaler ) );
|
||||
|
||||
/*
|
||||
* Set the options
|
||||
*/
|
||||
XTtcPs_SetOptions(Timer, TimerSetup->Options);
|
||||
/* Set the interval and prescale. */
|
||||
XTtcPs_SetInterval( pxTimerInstance, pxTimerSettings->Interval );
|
||||
XTtcPs_SetPrescaler( pxTimerInstance, pxTimerSettings->Prescaler );
|
||||
|
||||
/*
|
||||
* 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));
|
||||
/* The priority must be the lowest possible. */
|
||||
XScuGic_SetPriorityTriggerType( &xInterruptController, xInterruptIDs[ xTimer ], uxInterruptPriorities[ xTimer ] << portPRIORITY_SHIFT, ucRisingEdge );
|
||||
|
||||
/*
|
||||
* Set the interval and prescale
|
||||
*/
|
||||
XTtcPs_SetInterval(Timer, TimerSetup->Interval);
|
||||
XTtcPs_SetPrescaler(Timer, TimerSetup->Prescaler);
|
||||
/* Connect to the interrupt controller. */
|
||||
xStatus = XScuGic_Connect( &xInterruptController, xInterruptIDs[ xTimer ], ( Xil_InterruptHandler ) prvTimerHandler, ( void * ) pxTimerInstance );
|
||||
configASSERT( xStatus == XST_SUCCESS);
|
||||
|
||||
/* Enable the interrupt in the GIC. */
|
||||
XScuGic_Enable( &xInterruptController, xInterruptIDs[ xTimer ] );
|
||||
|
||||
/*
|
||||
* Connect to the interrupt controller
|
||||
*/
|
||||
Status = XScuGic_Connect(&xInterruptController, InterruptIDs[ xTimer ], (Xil_InterruptHandler)TickHandler, (void *)Timer);
|
||||
configASSERT( Status == XST_SUCCESS);
|
||||
/* Enable the interrupts in the timer. */
|
||||
XTtcPs_EnableInterrupts( pxTimerInstance, XTTCPS_IXR_INTERVAL_MASK );
|
||||
|
||||
/*
|
||||
* Enable the interrupt for the Timer counter
|
||||
*/
|
||||
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);
|
||||
/* Start the timer. */
|
||||
XTtcPs_Start( pxTimerInstance );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
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 )
|
||||
{
|
||||
portEND_SWITCHING_ISR( xSecondTimerHandler() );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
/* Read the interrupt status, then write it back to clear the interrupt. */
|
||||
ulInterruptStatus = XTtcPs_GetInterruptStatus( pxTimer );
|
||||
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)
|
||||
{
|
||||
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++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulTimer2Count++;
|
||||
}
|
||||
TickCount++;
|
||||
/* Check the device ID to know which IntQueue demo to call. */
|
||||
if( pxTimer->Config.DeviceId == xDeviceIDs[ 0 ] )
|
||||
{
|
||||
xYieldRequired = xFirstTimerHandler();
|
||||
}
|
||||
else if( pxTimer->Config.DeviceId == xDeviceIDs[ 1 ] )
|
||||
{
|
||||
xYieldRequired = xSecondTimerHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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
|
||||
that they are all still running, and that none have detected an error. */
|
||||
if( xAreIntQueueTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if( xAreMathsTaskStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
|
|
Loading…
Reference in a new issue