📄 timer.c
字号:
#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 + -