zoukankan      html  css  js  c++  java
  • 多定时器处理3(30天自制操作系统 -- 读书笔记)

         继续定时器中断处理的改进。

         1、定时器中断程序Timer_Interrupt是这样的。

    //定时器中断函数
    void Timer_Interrupt(void)
    {
        int i=0;
        timerctl.count ++;
        for(i=0;i<MAX_TIMER;i++)        //扫描所有的定时器
        {
            if(timerctl.timer[i].flag == TIMER_FLAG_USING)
            {
                timerctl.count--;
                if(timerctl.count == 0) //减得时间到了
                {
                    fifo8_put(timerctl.timer[i].fifo,timerctl.timer[i].data);  //向关联fifo中写入数据
                    timerctl.timer[i].flag = TIMER_FLAG_ALLOC;      //改变标志位
                }
            }
        }
        
        return ;
    }

         程序的弊端在于每次中断里,程序都要循环MAX_TIMER次,查找TMER_FLAG_USING中的定时器中,是否有定时器定时时间到。
         改进思想,用nexttimeout变量记录任意时刻的下一个定时时间到。特例:在最开始的时候,没有设置定时器,那么下个定时时间到的值就是大无穷。

         看代码,更改timerctl数据描述结构:

    struct TIMER
    {
        unsigned int timeout,flag,nexttimeout;     //设定的定时时间,定时器的状态,下个定时时间到
        struct FIFO8 *fifo;            //定时器关联的fifo
        unsigned char data;            //当定时时间到时,向fifo中写入的数值
    }

        更改初始化代码:

    void TIMERCTL_Initial(void)
    {
        char i=0;
        timer.count = 0;               //基数清零
        timerctl.nexttimeout = 0xffffffff;        //到下个定时时间到几乎为不可能,也就是还没有设置定时器  这里!!!!
        for(i=0;i<MAX_TIMER;i++)
        {
            timerctl.timer[i].flag = TIMER_FLAG_NOUSE;   /*标记为未使用*/        
        }
    }

        更改定时器设定函数:

    //设定timer定时器的定时时间为timeout
    void timer_settime(struct TIMER* timer,unsigned int timeout)
    {
        timer.timeout = timeout + timrctl.count;        
        timer.flag = TIMER_FLAG_USING;  //这条语句相当于启动了定时器
    
       //这后面的这句代码
       if(timerctl.nexttimeout > timer.timeout)   //现在新添加了一个定时器,新添加的定时器定时时间更短,比原先所有设定的定时器都要先到
       {
                timerctl.nexttimeout = timer.timeout;  //调整nexttimeout值
       }
        
        return ;
    }

        再更改定时器中断函数:

    //定时器中断函数
    void Timer_Interrupt(void)
    {
        int i=0;
        timerctl.count ++;
        if(timerctl.count > timectl.nexttimeout)    
             return ;   //最近的定时时间都没到
    
        timerctl.nexttimeout = 0xffffffff;
        for(i=0;i<MAX_TIMER;i++)        //扫描所有的定时器
        {
            if(timerctl.timer[i].flag == TIMER_FLAG_USING)
            {
                if(timerctl.timer[i].timeout <= timerctl.count) 
                {
                    fifo8_put(timerctl.timer[i].fifo,timerctl.timer[i].data);  //向关联fifo中写入数据
                    timerctl.timer[i].flag = TIMER_FLAG_ALLOC;      //改变标志位
                }
                else
                {
                     if(timerctl.timer[i].count < timerctl.nexttimeout)
                     {
                           timerctl.nexttimeout = timerctl.timer[i].count;  //更新最小值
                     }
                }
            }
        }
        
        return ;
    }

       以上代码思路很简单,如果现在的计时时间还不到最近的定时时间,那么就退出。如果计数时间超过了最近的定时时间,那么一定就有一个定时器定时时间到了,那么找到这个定时器,接下来呢,就是更新最近的定时时间。上面代码从for(i=0;i<MAX_TIMER;i++) 限定TIMER_FLAG_USING,就是在正在使用的定时器中查找,谁是定时时间到的定时器,其它的就不是,那么它就要去与最近定时时间比较以更新最近定时时间。

       

  • 相关阅读:
    hlgoj 1766 Cubing
    Reverse Linked List
    String to Integer
    Bitwise AND of Numbers Range
    Best Time to Buy and Sell Stock III
    First Missing Positive
    Permutation Sequence
    Next Permutation
    Gray Code
    Number of Islands
  • 原文地址:https://www.cnblogs.com/kanite/p/4485951.html
Copyright © 2011-2022 走看看