📄 virtualtimer.c
字号:
TimerEnable(TIMER2_BASE, TIMER_A);
}
//*****************************************************************************
//
//! The real timer interrupt handler for the virtual timers.
//!
//! This function handles the real timer interrupt. It will call the virtual
//! timer handler for the virtual timer that has just expired and schedule a
//! new real timer interrupt for the time of the next virtual timer expiration.
//!
//! \return None.
//
//*****************************************************************************
void
Timer2IntHandler(void)
{
tVirtualTimer *pTimer;
//
// Clear the timer interrupt.
//
TimerIntClear(TIMER2_BASE, TIMER_TIMA_TIMEOUT);
//
// Indicate that the interrupt handler is active.
//
HWREGBITW(&g_ulVirtualTimerFlags, VT_FLAG_INT_ACTIVE) = 1;
//
// Get a pointer to the structure for the virtual timer that just expired.
//
pTimer = g_psVirtualTimers[g_ulVirtualTimer];
//
// Remove this virtual timer from the list.
//
g_psVirtualTimers[g_ulVirtualTimer] = 0;
//
// Call the handler for this virtual timer.
//
pTimer->pfnHandler();
//
// Schedule the next real timer interrupt.
//
VirtualTimerSchedule();
//
// Indicate that the interrupt handler is no longer active.
//
HWREGBITW(&g_ulVirtualTimerFlags, VT_FLAG_INT_ACTIVE) = 0;
}
//*****************************************************************************
//
//! Add a new virtual timer.
//!
//! \param pTimer is a pointer to the virtual timer structure for the timer to
//! be added. The memory containing this structure must persist until the
//! timer has expired; it is not copied into an internal virtual timer
//! structure.
//!
//! This function adds a new virtual timer to the list of virtual timers
//!
//! \return Returns one if the virtual timer was added successfully and zero
//! otherwise.
//
//*****************************************************************************
unsigned long
VirtualTimerAdd(tVirtualTimer *pTimer)
{
unsigned long ulIdx, ulLoop, ulA, ulB;
//
// Loop over the virtual timer list to find an unused entry.
//
for(ulIdx = 0; ulIdx < NUM_TIMERS; ulIdx++)
{
if(g_psVirtualTimers[ulIdx] == 0)
{
break;
}
}
//
// Return an error if an unused entry could not be found.
//
if(ulIdx == NUM_TIMERS)
{
return(0);
}
//
// Save a pointer to the virtual timer structure.
//
g_psVirtualTimers[ulIdx] = pTimer;
//
// See if this timer was added from within the interrupt handler.
//
if(HWREGBITW(&g_ulVirtualTimerFlags, VT_FLAG_INT_ACTIVE) == 0)
{
//
// This timer was not added from within the interrupt handler, so the
// virtual timer list needs to be checked to see if the new timer is
// the one with the earliest expiration time. Loop through the virtual
// timers.
//
for(ulLoop = 0; ulLoop < NUM_TIMERS; ulLoop++)
{
//
// Skip this entry if it is unused or is the entry for the newly
// added timer.
//
if((g_psVirtualTimers[ulLoop] == 0) || (ulLoop == ulIdx))
{
continue;
}
//
// Get the timeouts for this virtual timer and the new virtual
// timer.
//
ulA = pTimer->ulTimeOut;
ulB = g_psVirtualTimers[ulLoop]->ulTimeOut;
//
// If this virtual timer expires before the new virtual timer, then
// stop looking.
//
if(((ulB < ulA) && ((ulA - ulB) < 0x10000000)) ||
((ulB > ulA) && ((ulB - ulA) > 0xf0000000)))
{
break;
}
}
//
// See if a virtual timer was found with an earlier expiration time.
//
if(ulLoop == NUM_TIMERS)
{
//
// Save the index of the new virtual timer since it is the next to
// expire.
//
g_ulVirtualTimer = ulIdx;
//
// Get the present time.
//
ulA = 0xffffffff - TimerValueGet(TIMER1_BASE, TIMER_A);
//
// Set the real timer to expire when the virtual timer is set to
// expire.
//
TimerDisable(TIMER2_BASE, TIMER_A);
TimerLoadSet(TIMER2_BASE, TIMER_A, pTimer->ulTimeOut - ulA - 1);
TimerEnable(TIMER2_BASE, TIMER_A);
}
}
//
// Success.
//
return(1);
}
//*****************************************************************************
//
//! Gets the current virtual time.
//!
//! This function returns the current virtual time. This can be used to
//! determine the timeout for a new virtual timer; for example, using
//! "VirtualTimeGet() + SysCtlClockGet()" as the timeout will cause a virtual
//! timer to expire in one second (in reality it would be a bit less than that
//! since it will actually expire one second from the VirtualTimeGet() call).
//!
//! \return The current virtual time.
//
//*****************************************************************************
unsigned long
VirtualTimeGet(void)
{
//
// Return the current virtual time.
//
return(0xffffffff - TimerValueGet(TIMER1_BASE, TIMER_A));
}
//*****************************************************************************
//
//! Initializes the virtual timer driver.
//!
//! This function prepares the virtual timers for operation. It must be called
//! before any other virtual timer function.
//!
//! \return None.
//
//*****************************************************************************
void
VirtualTimerInit(void)
{
unsigned long ulIdx;
//
// Loop over the virtual time list, clearing out each entry.
//
for(ulIdx = 0; ulIdx < NUM_TIMERS; ulIdx++)
{
g_psVirtualTimers[ulIdx] = 0;
}
//
// Configure timer 1 to be the free-running time base.
//
TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER);
TimerLoadSet(TIMER1_BASE, TIMER_A, 0xffffffff);
TimerControlStall(TIMER1_BASE, TIMER_A, true);
TimerEnable(TIMER1_BASE, TIMER_A);
//
// Configure timer 2 to be a one-shot timer to provide interrupts as
// required to support the virtual timers.
//
TimerConfigure(TIMER2_BASE, TIMER_CFG_32_BIT_OS);
TimerControlStall(TIMER2_BASE, TIMER_A, true);
IntEnable(INT_TIMER2A);
TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -