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

📄 timer.c

📁 一种操作系统源码核
💻 C
📖 第 1 页 / 共 2 页
字号:

#if !defined(__EBOS_H)
#include "ebos.h"
#endif

/*
*********************************************************************************************************
*                                          Timer module implement file
*********************************************************************************************************
*/
/*
*********************************************************************************************************
											任务定时器初始化函数

*********************************************************************************************************
*/
static  TIMER_TCB *Suspend_Timers_List; //第二类激活定时器列表头指针
static  TIMER_TABLE *Task_Timer_Head;   //第一类定时器列表头指针 
static  UNSIGNED  TotalTimers;  //创建的应用定时器数
static  INT32U  System_Clock;//系统时钟

static  TASK_HCB TIMER_HISR;   //定时器高级中断线程
static  UNSIGNED Timer_Stk[200];//定时器高级中断线程堆栈
static APP_TIMER *TimerTable[MAX_TIMER_NUM];////应用定时器向量表
static void interrupt (*TickISR_OldHandle)(void);//旧的定时器处理向量
static void SetTimerRate(INT8U Freq);//设置定时器滴答速度
APP_TIMER  *TimerFreeList;//可用应用定时器列表
/*
*********************************************************************************************************
				任务挂起定时器初始化函数.

*********************************************************************************************************
*/
void InitTaskTimer(TIMER_TCB *timer, void *information)
{
	timer->information=information;
	timer->next_timer=NULL;
	timer->previous_timer=NULL;
	timer->timer_type=TASKTIMER;

}


/*
*********************************************************************************************************
			任务挂起定时器启动函数,并插入活动定时器链表.
 
*********************************************************************************************************
*/
void StartTimer(TIMER_TCB *timer,UNSIGNED time)
{
    	TIMER_TCB *timer_tcb,*ptq;
    	UCHAR  i=0;
    	timer->next_timer=NULL;
    	timer->remaining_time=time;
    	timer->previous_timer=timer;
    	EnLock();
    	if (Suspend_Timers_List==NULL) {
	 	Suspend_Timers_List=timer;
	 	UnLock();
	 	return;
    	}
    	for(timer_tcb=Suspend_Timers_List;timer_tcb;timer_tcb=timer_tcb->next_timer){
         	if(timer->remaining_time<timer_tcb->remaining_time)
             		break;
         	timer->remaining_time-= timer_tcb->remaining_time;
	 	i++;
    	};
    	timer->next_timer=timer_tcb;
    	timer->previous_timer=timer_tcb->previous_timer;
    	(timer_tcb->previous_timer)->next_timer=timer;
    	timer_tcb->previous_timer=timer;
    	if(!i)
        	Suspend_Timers_List=timer;
    	if(timer_tcb)
        	timer_tcb->remaining_time-=timer->remaining_time;
    	UnLock();
}

/*
*********************************************************************************************************
                                 停止一个定时器,并从活动定时器表中删除

*********************************************************************************************************
*/

void StopTimer(TIMER_TCB *timer)
{
	TIMER_TCB *prev,*next;
  	if(timer==NULL)
     		return;
  	EnLock();
	if(timer->next_timer){
     		prev=timer->previous_timer;
		next=timer->next_timer;
     		next->remaining_time+= timer->remaining_time;
     		prev->next_timer=next;
     		next->previous_timer=prev;
     		if(Suspend_Timers_List==timer)
     			Suspend_Timers_List=next;
     
  	}
  	else
     		Suspend_Timers_List=NULL;
  	UnLock();


}

/*
*********************************************************************************************************
                                 定时器时间到的HISR处理函数,如果应用定时器到期调用TIMER_Timer_Expiration
				 如果时间片应用定时器到,调用Time_Slice

*********************************************************************************************************
*/

void TimerHISRHandle(void)
{
     	TASK_TCB *current;
     	UNSIGNED type,id;
     	EnLock(); //不允许中断
     	while(Task_Timer_Head){
        	current=(TASK_TCB *)(Task_Timer_Head->information);
        	type=Task_Timer_Head->timer_type;
        	DelList(&(void *)Task_Timer_Head,&(Task_Timer_Head->linknode));
        	UnLock();
        	if(type==TIMESLICE)
           		TaskTimeSlice(current);
		else
	   		TaskTimerOut(current);
        	EnLock(); //不允许中断
     	}
     	if (Suspend_Timers_List->remaining_time==0){
		UnLock();
		if (Suspend_Timers_List->timer_type==TASKTIMER)
	   		TaskSuspendTimeout((TASK_TCB *)(Suspend_Timers_List->information));
		else {
	   		id= ((APP_TIMER *)Suspend_Timers_List)->expiration_id;
	   		((APP_TIMER *)Suspend_Timers_List)->expiration_routine(id);
		}
		EnLock();
     	}
     	((TASK_HCB *)KERNAL.Active_HISR_Heads[2])->activation_count--;
     	if(((TASK_HCB *)KERNAL.Active_HISR_Heads[2])->activation_count==0) 
	   	DelTaskList(&(TASK_TCB *)KERNAL.Active_HISR_Heads[2],(TASK_TCB *)&(TIMER_HISR));
     	UnLock();
     
     	Schedule();
 }




/*
*********************************************************************************************************
                               定时器模块初始化函数,初始化定时器模块数据结构,并定义task_slice_timer,task_lim_timer两个定时器

*********************************************************************************************************
*/

void TimerInitialize(void)
{

  	Suspend_Timers_List=NULL;
  	Task_Timer_Head=NULL;
  	TimerInstall();//---------------->Attention:TickIsr is setup here<------
  	CreateHISR(&TIMER_HISR,TimerHISRHandle,&Timer_Stk[200],200,2);
}
/*
*********************************************************************************************************
		 该函数处理实际的硬件的定时器中断,更新定时器计数值,如果某个定时器计数到,则调用
                定时器的HISR

*********************************************************************************************************
*/
void Update_times()
{
     	TIMER_TABLE  timer;
     	UNSIGNED state;
     	if(++System_Clock==4294967294L)
		System_Clock=0;
     	if ((((TASK_TCB *)KERNAL.current_thread)->timer_active)==TRUE){
        	if(((TASK_TCB *)KERNAL.current_thread)->time_slice){
	    	((TASK_TCB *)KERNAL.current_thread)->time_slice--;
        	}
       		else{
	    		timer.timer_type=TIMESLICE;
	    		timer.information=(TASK_TCB *)KERNAL.current_thread;
	    		AddList(&(void *)Task_Timer_Head,&(timer.linknode),0);
	    		ActivateHISR((&TIMER_HISR)->id) ;
       		}
       		if(((TASK_TCB *)KERNAL.current_thread)->task_timeout>0) {
	    		((TASK_TCB *)KERNAL.current_thread)->task_timeout--;
      		}
		else if (((TASK_TCB *)KERNAL.current_thread)->task_timeout==0) {
	    		timer.timer_type=TIMELIMIT;
	    		timer.information=(TASK_TCB *)KERNAL.current_thread;
	    		AddTaskList(&(TASK_TCB *)Task_Timer_Head,(TASK_TCB *)&(timer.linknode),0);
	    		ActivateHISR((&TIMER_HISR)->id);
		}
   	}
   	if(Suspend_Timers_List){
       		if (Suspend_Timers_List->remaining_time){
	    		Suspend_Timers_List->remaining_time--;
       		}
       		else {
	    		ActivateHISR((&TIMER_HISR)->id);
		}
    	}
}
void interrupt SysTimerTick(void)
{
 	asm  MOV    AL, 20H                   //    ; Move EOI code into AL.
 	asm   MOV    DX, 20H                   //    ; Address of 8259 PIC in DX.
 	asm   OUT    DX, AL                   //     ; Send EOI to PIC if not processing DOS timer.
 	EnLock();
 	if(KERNAL.current_thread){
     		FP_SEG(((TASK_TCB *)KERNAL.current_thread)->stack_pointer)=_SS;
     		FP_OFF(((TASK_TCB *)KERNAL.current_thread)->stack_pointer)=_SP;
  	}

 	Update_times();
 	UnLock();
 }
void SetTimerRate(INT8U Freq)
{
   	USHORT  v;
   	if (Freq == 18)                            /* See if we need to restore the DOS frequency        */
		v = 0;
   	v=(INT16U)(((INT32U)2386360L / Freq + 1) >> 1) ;
   	outportb(0x43, 0x36);
   	outportb(0x40, v & 0xff);
   	outportb(0x40, (v >> 8)& 0xFF);

}
void TimerInstall()
{
   	TickISR_OldHandle=getvect(INTTICK);
   	EnLock();
   	setvect(INTTICK,SysTimerTick);
   	SetTimerRate(TICKS_PER_SEC);
   	UnLock();
}
void TimerUninstall()
{
  	EnLock();
  	SetTimerRate(18);
  	setvect(INTTICK,TickISR_OldHandle);
  	UnLock();
}

⌨️ 快捷键说明

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