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

📄 timer.cpp

📁 adeos嵌入式操作系统例子,值得一看
💻 CPP
字号:
/**********************************************************************
 *
 * Filename:    timer.cpp
 * 
 * Description: A software timer class implemented over top of the
 *              hardware timer within the Intel 8018xEB processor.
 *
 * Notes:       Some of the constants in this file are specific to 
 *              Arcom's Target188EB hardware.
 *
 * 
 * Copyright (c) 1998 by Michael Barr.  This software is placed into
 * the public domain and may be used for any purpose.  However, this
 * notice must not be changed or removed and no warranty is either
 * expressed or implied by its publication or distribution.
 **********************************************************************/

#include <dos.h>                     // For enable() and disable().

#include "i8018xEB.h"
#include "timer.h"


#ifndef NULL
#define NULL  (void *) 0L
#endif


#define CYCLES_PER_TICK 6250       // Number of clock cycles per tick.
#define MS_PER_TICK     1          // Number of milliseconds per tick.


class TimerList
{
    public:

        TimerList();

        void     insert(Timer * pTimer);
        Timer *  remove(Timer * pTimer);

        void     tick(void);
 
    private:

        Timer *  pTop;

};

TimerList timerList;


/**********************************************************************
 *
 * Function:    TimerList()
 * 
 * Description: Create and initialize a linked list of timers.
 *
 * Notes:       
 *
 * Returns:     None defined.
 *
 **********************************************************************/
TimerList::TimerList(void)
{
    pTop = NULL;

}   /* TimerList() */


/**********************************************************************
 *
 * Method:      insert()
 *
 * Description: Insert a timer into an ordered linked list.
 *
 * Notes:       This routine disables interrupts.
 * 
 * Returns:     None defined.
 *
 **********************************************************************/
void
TimerList::insert(Timer * pTimer)
{
    Timer **  ppPrev = &this->pTop;


    disable();

    //
    // Initialize the new timer's tick count.
    //
    pTimer->count = pTimer->length;

    //
    // Walk down the timer list, subtracting ticks as we go.
    //
    while (*ppPrev != NULL && pTimer->count >= (*ppPrev)->count)
    {
        pTimer->count -= (*ppPrev)->count;
        ppPrev = &(*ppPrev)->pNext;
    }
    
    // 
    // Insert the new timer at this point in the timer list.
    //
    pTimer->pNext = *ppPrev;
    *ppPrev = pTimer;
  
    //
    // Adjust the tick count of the next timer (if any).
    //
    if (pTimer->pNext != NULL)
    {
        pTimer->pNext->count -= pTimer->count;
    } 

    enable();

}   /* insert() */


/**********************************************************************
 *
 * Method:      remove()
 *
 * Description: Remove a timer from the timer list.
 *
 * Notes:       This routine disables interrupts.
 * 
 * Returns:     A pointer to the removed timer, NULL if it wasn't
 *              found in the timer list.
 *
 **********************************************************************/
Timer *
TimerList::remove(Timer * pTimer)
{
    Timer **  ppPrev = &this->pTop;


    disable();

    //
    // Walk down the linked list until the dead timer is found.
    //
    while (*ppPrev != NULL && *ppPrev != pTimer)
    {
        ppPrev = &(*ppPrev)->pNext;
    }

    //
    // Remove the dead timer from the linked list.
    //
    if (*ppPrev != NULL)
    {
        *ppPrev = pTimer->pNext;
        (*ppPrev)->count += pTimer->count;
    }

    enable();

    return (*ppPrev);

}   /* remove() */


/**********************************************************************
 *
 * Method:      tick()
 *
 * Description: Update the linked list of timers for a clock tick.
 *
 * Notes:       The caller is responsible for disabling interrupts.
 * 
 * Returns:     None defined.
 *
 **********************************************************************/
void
TimerList::tick()
{
    Timer **  ppTop  = &this->pTop;


    if (*ppTop != NULL)
    {
        //
        // Decrement the tick count of the first timer in the list.
        //
        (*ppTop)->count--;

        //
        // Mark all of the expired timers done and remove them.
        //
        while (*ppTop != NULL && (*ppTop)->count == 0)
        {
            (*ppTop)->state = Done;
            *ppTop = (*ppTop)->pNext;
        }                                   
    }

}   /* tick() */


/**********************************************************************
 * 
 * Method:      Interrupt()
 *
 * Description: An interrupt handler for the timer hardware.
 *
 * Notes:       This method is declared static, so that we cannot 
 *              inadvertently modify any of the software timers.
 *
 * Returns:     None defined.
 *
 **********************************************************************/
void interrupt
Timer::Interrupt()
{
    //
    // Decrement the active timer's count.
    //
    timerList.tick();

    //
    // Acknowledge the timer interrupt.
    //
    gProcessor.pPCB->intControl.eoi = EOI_NONSPECIFIC;

    //
    // Clear the Maximum Count bit (to start the next cycle). 
    //
    gProcessor.pPCB->timer[2].control &= ~TIMER_MAXCOUNT;

}   /* Interrupt() */


/**********************************************************************
 * 
 * Method:      Timer()
 *
 * Description: Constructor for the Timer class.
 *
 * Notes:    
 *
 * Returns:     None defined.
 *
 **********************************************************************/
Timer::Timer(void)
{
    static int bInitialized = 0;


    //
    // Initialize the new software timer.
    //
    state  = Idle;
    type   = OneShot;
    length = 0;
    count  = 0;
    pNext  = NULL;

    //
    // Initialize the timer hardware, if not previously done.
    //
    if (!bInitialized)
    {
        //
        // Install the interrupt handler and enable timer interrupts.
        //
        gProcessor.installHandler(TIMER2_INT, Timer::Interrupt);
        gProcessor.pPCB->intControl.timerControl &= 
                                 ~(TIMER_MASK | TIMER_PRIORITY);

        // 
        // Initialize the hardware device (use Timer #2).
        // 
        gProcessor.pPCB->timer[2].count = 0;
        gProcessor.pPCB->timer[2].maxCountA = CYCLES_PER_TICK;
        gProcessor.pPCB->timer[2].control = TIMER_ENABLE 
                                          | TIMER_INTERRUPT
                                          | TIMER_PERIODIC;

        //
        // Mark the timer hardware initialized.
        //
        bInitialized = 1;
    }

}   /* Timer() */


/**********************************************************************
 * 
 * Method:      ~Timer()
 *
 * Description: Destructor for the Timer class.
 *
 * Notes:       This routine ensures that the timer isn't left dangling
 *              in the timer list.
 *
 * Returns:     None defined.
 *
 **********************************************************************/
Timer::~Timer(void)
{
    //
    // Cancel the timer.
    //
    this->cancel();

}   /* ~Timer() */


/**********************************************************************
 * 
 * Method:      start()
 *
 * Description: Start a software timer, based on the tick from the
 *              underlying hardware timer.
 *
 * Notes:    
 *
 * Returns:     0 on success, -1 if the timer is already in use.
 *
 **********************************************************************/
int
Timer::start(unsigned int nMilliseconds, TimerType timerType)
{
    if (state != Idle)
    {
        return (-1);
    }

    //
    // Initialize the software timer.
    //
    type   = timerType;
    length = nMilliseconds / MS_PER_TICK;
    state  = Active;

    //
    // Add this timer to the active timer list.
    //
    timerList.insert(this);

    return (0);

}   /* start() */


/**********************************************************************
 * 
 * Method:      waitfor()
 *
 * Description: Wait for the software timer to finish.
 *
 * Notes:    
 *
 * Returns:     0 on success, -1 if the timer is not running.
 *
 **********************************************************************/
int
Timer::waitfor()
{
    if (state != Active)
    {
        return (-1);
    }

    //
    // Wait for the timer to expire.
    //
    while (state != Done);

    //
    // Restart or idle the timer, depending on its type.
    //
    if (type == Periodic)
    {
        state = Active;
        timerList.insert(this);
    }
    else
    {
        state = Idle;
    }

    return (0);

}   /* waitfor() */


/**********************************************************************
 * 
 * Method:      cancel()
 *
 * Description: Stop a running timer.
 *
 * Notes:
 *
 * Returns:     None defined.
 *
 **********************************************************************/
void
Timer::cancel(void)
{
    // 
    // Remove the timer from the timer list.
    //
    if (state == Active)
    {
        timerList.remove(this);
    }

    //
    // Reset the timer's state.
    //
    state = Idle; 

}   /* cancel() */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -