⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 virtualtimer.c

📁 CNC.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -