您的位置:首页 > 其它

多定时器处理3(30天自制操作系统 -- 读书笔记)

2015-05-07 20:27 375 查看
继续定时器中断处理的改进。

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,就是在正在使用的定时器中查找,谁是定时时间到的定时器,其它的就不是,那么它就要去与最近定时时间比较以更新最近定时时间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: