• 多定时器处理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,就是在正在使用的定时器中查找,谁是定时时间到的定时器,其它的就不是,那么它就要去与最近定时时间比较以更新最近定时时间。

       

  • 相关阅读:
    数字基本数据类型范围比较
    java中float和double的区别
    ASP.NET中javascript与c#互相访问
    Javascript技术之详尽解析event对象
    Java基础-Java中的Calendar和Date类
    逻辑运算符
    JS获取当前时间
    几秒后刷新页面
    【LiteOS】LiteOS任务篇源码分析删除任务函数
    POJ 2385 Apple Catching (DP)
  • 原文地址:https://www.cnblogs.com/kanite/p/4485951.html
Copyright © 2020-2023  润新知