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

   

posted @ 2015-05-07 20:27  kanite  阅读(284)  评论(0编辑  收藏  举报