📄 timer.c
字号:
#define __TIMER_C
#include <psos.h>
#include <string.h>
#include "sys_conf.h"
#include "time.h"
#include "timer.h"
#include "netntp.h"
#ifndef DB_PRINT
#define DB_PRINT printf
#endif // DB_PRINT
#define PID_TIMER 0
#define TMCB_NUM 1000
typedef struct TMCBStruc
{
unsigned char use ;
unsigned char arrived ;
unsigned int event ;
unsigned long Count1s ;
unsigned long rest ;
void (*entry)() ;
unsigned short prev ;
unsigned short next ;
}TMCBStruc ;
typedef struct TMCBPoolStruc
{
unsigned short count ;
unsigned short head ;
unsigned short tail ;
unsigned short TMid[TMCB_NUM] ;
}TMCBPoolStruc;
static TMCBStruc TMCB[TMCB_NUM] ; /* timer control block pointer */
static TMCBPoolStruc TMCBPool; /* timer control block queue */
static unsigned long int TMCBOverflow ;
static unsigned long int TMCBExhaust ;
static unsigned short TMhead , TMtail , TMcount ;
static unsigned int SysTickCount=0;
unsigned int SysTickSecond =0;
#define ticks2ps 146
#define ticks2s 1455
unsigned int SmIdRTCTimer;
unsigned long tidRTCTimer;
void RtcSynTimer();
/********************************************************************
*FUNCTION NAME: unsigned long int InitTMCB ( void ) ; *
*DESCRIPTION: init Timer control block *
*INPUT: none *
*OUTPUT: none *
*AUTHOR/DATE: lijian/98.11.03 *
*NOTE: *
********************************************************************/
int InitTMCB ( void )
{
unsigned long int size, i ;
/* get TMCB buffer */
size = (unsigned long int)( sizeof(TMCBStruc) * TMCB_NUM ) ;
// rc = rn_getseg ( 0 , size , RN_NOWAIT , 0 , &TMCB ) ;
/* initial TMCB pool */
memset ( (unsigned char *)TMCB , 0 , size ) ;
TMhead = NULL_TMID ;
TMtail = NULL_TMID ;
TMcount = 0 ;
TMCBOverflow = 0 ;
TMCBExhaust = 0 ;
/* initial TMCB pool */
TMCBPool.count = TMCB_NUM ;
TMCBPool.head = 0 ;
TMCBPool.tail = 0 ;
for ( i = 0; i < TMCB_NUM; i ++ )
TMCBPool.TMid[i] = i ;
return 1 ;
}
/********************************************************************
*FUNCTION NAME: unsigned short SetTimer(unsigned short event,unsigned long int Count1s, void(*entry)()) *
*DESCRIPTION: set timer *
*INPUT: arg: timer arg *
* Count1s: timer length *
* entry: time out func *
*OUTPUT: timer ID *
*AUTHOR/DATE: lijian/98.11.03 *
*NOTE:
*
********************************************************************/
unsigned short _SetTimer( unsigned long int Count1ms, void (*entry)(),unsigned int arg )
{
TMCBStruc *ptr;
unsigned long sum;
unsigned short head , prev , tmid , i ;
/* get invoking process's task id */
/* if timer is exist, kill it */
Count1ms /= 100;/*TimerProc is exec once per 100ms now,added by lj 99.5.18*/
/* get a TMCB from TMCB pool */
if (TMCBPool.count > 0)
{
TMCBPool.count --;
head = TMCBPool.head;
if (++ TMCBPool.head >= TMCB_NUM)
TMCBPool.head = 0;
tmid = TMCBPool.TMid[head];
}
else
{
TMCBExhaust ++;
// poutf( FILE_LINE, PID_TIMER,ALWAYS_PRINT_ID," \nTMCB exhuast!!! " );
return NULL_TMID;
}
ptr = TMCB + tmid ;
if (ptr->use != 0)
// poutf( FILE_LINE, PID_TIMER,ALWAYS_PRINT_ID," \n<Timer exception1!!!> " );
;
/* initial TMCB */
ptr->Count1s = Count1ms ;
ptr->event = arg ;
ptr->entry = entry ;
ptr->use = 1 ;
ptr->arrived = 0 ;
/* deal relative timer following */
if (++TMcount <= 1 )
{
ptr->prev = tmid;
ptr->next = tmid;
ptr->rest = Count1ms ;
TMhead = tmid ;
TMtail = tmid ;
return tmid;
}
i = TMhead ;
sum = 0;
/* find position in queue */
for(;;)
{
sum += TMCB[i].rest;
if (sum >= Count1ms)
{
/* has find position, end seeking */
prev = TMCB[i].prev;
ptr->prev = prev;
ptr->next = i;
ptr->rest = Count1ms + TMCB[i].rest - sum ;
TMCB[prev].next = tmid;
TMCB[i].prev = tmid;
TMCB[i].rest = sum - Count1ms;
/* position is head */
if (i == TMhead)
TMhead = tmid;
break;
}
if (i == TMtail)
{
/* position is queue tail */
TMCB[TMhead].prev = tmid;
TMCB[TMtail].next = tmid;
ptr->prev = TMtail;
ptr->next = TMhead;
ptr->rest = Count1ms - sum;
TMtail = tmid;
break;
}
/* continue to seek next */
i = TMCB[i].next ;
while ( TMCB[i].rest == 0 )
{
if (i == TMtail)
{
/* position is queue tail */
TMCB[TMhead].prev = tmid;
TMCB[TMtail].next = tmid;
ptr->prev = TMtail;
ptr->next = TMhead;
ptr->rest = Count1ms - sum;
TMtail = tmid;
return tmid;
}
i = TMCB[i].next ;
}
}
return tmid;
}
/********************************************************************
*FUNCTION NAME: unsigned short StopTimer (unsigned short tmid) ; *
*DESCRIPTION: stop timer *
*INPUT: tid: timer ID *
*OUTPUT: 0--success *
* else--fail *
*AUTHOR/DATE: lijian/98.11.03 *
*NOTE: *
********************************************************************/
int _StopTimer ( unsigned short *ptmid )
{
TMCBStruc *ptr;
unsigned short tail, prev, next ;
unsigned short tmid;
if(ptmid)
tmid = *ptmid;
else
return TM_ERROR;
if((tmid >= TMCB_NUM) || (tmid == NULL_TMID))
{
*ptmid = NULL_TMID;
return TM_ERROR;
}
ptr = (TMCBStruc *)&TMCB[tmid];
/* tmid is not use */
if (ptr->use == 0)
{
*ptmid = NULL_TMID;
return TM_ERROR;
}
if (ptr->arrived == 1)
// poutf( FILE_LINE, PID_TIMER,ALWAYS_PRINT_ID,"\n<Process:%s, kill arrived timer>!!! " );
;
ptr->use = 0;
prev = ptr->prev;
next = ptr->next;
/* delete TMCB from timer queue */
if (ptr->arrived == 0)
{
if (-- TMcount == 0)
{
/* if no timer in queue, clear queue */
TMhead = NULL_TMID;
TMtail = NULL_TMID;
}
else
{
/* delete from timer queue */
TMCB[prev].next = next;
TMCB[next].prev = prev;
if (tmid != TMtail)
TMCB[next].rest += ptr->rest;
else
{
/* if tid is timer queu tail */
TMtail = prev;
}
/* the element is head of queue */
if (TMhead == tmid)
TMhead = next;
}
}
/* return TMCB to TMCB pool */
if (TMCBPool.count < TMCB_NUM)
{
tail = TMCBPool.tail;
TMCBPool.TMid[tail] = tmid;
TMCBPool.count ++;
if (++ TMCBPool.tail >= TMCB_NUM)
TMCBPool.tail = 0;
}
else
{
TMCBOverflow ++;
// poutf( FILE_LINE, PID_TIMER,ALWAYS_PRINT_ID,"\n<TMCB overflow>!!! " );
*ptmid = NULL_TMID;
return TM_ERROR;
}
*ptmid = NULL_TMID;
return TM_SUCCESS;
}
/********************************************************************
*FUNCTION NAME: void TimerProc ( void ) ; *
*DESCRIPTION: timer process *
*INPUT: none *
*OUTPUT: none *
*AUTHOR/DATE: lijian/98.11.03 *
*NOTE: *
********************************************************************/
void TimerProc ( void )
{
unsigned short tmid , next ;
unsigned char ArrivedTimerNum ;
TMCBStruc *ptr;
ArrivedTimerNum = 0 ;
/* if timer queue no element, continue next queue */
if (TMcount == 0)
return ;
/* if timer queue head has not arrive, continue next queue */
if (-- TMCB[TMhead].rest > 0)
return ;
/* deal with arrived timer */
for(;;)
{
if (TMcount == 0)
break;
ptr = (TMCBStruc *)&TMCB[TMhead];
if (ptr->rest > 0)
break;
if (ArrivedTimerNum > 200)
{
ptr->rest ++;
break;
}
tmid = TMhead ;
if (-- TMcount == 0)
{
/* queue has no element, clear queue */
TMhead = NULL_TMID;
TMtail = NULL_TMID;
}
else
{
next = ptr->next;
TMCB[TMtail].next = next;
TMCB[next].prev = TMtail;
TMhead = next;
}
/* timer arrived*/
ptr->use = 0 ;
ptr->arrived = 1;
ArrivedTimerNum ++;
(*(ptr->entry))(ptr->event);
if (++ TMCBPool.count <= TMCB_NUM)
{
TMCBPool.TMid[TMCBPool.tail] = tmid;
if (++ TMCBPool.tail >= TMCB_NUM)
TMCBPool.tail = 0;
}
else
{
TMCBPool.count = TMCB_NUM;
TMCBOverflow ++;
//poutf( FILE_LINE, PID_TIMER,ALWAYS_PRINT_ID,"\n<TMCB overflow>!!! " );
}
} /* end while */
}
void IntUserTicks(void)
{
SysTickCount ++;
}
void UsrTimerProc()
{
static unsigned int oldcount1=0,oldcount2=0;
unsigned int tickcount;
unsigned int step1, step2;
int i;
// char* strtime;
sm_create("sm_rtc",1,SM_PRIOR,&SmIdRTCTimer);
for(;;)
{
tickcount = SysTickCount;
if(tickcount > oldcount1 )
{
step1 = tickcount - oldcount1;
}
else
{
step1 = 0xFFFFFFFF - oldcount1 + tickcount;
}
if(tickcount > oldcount2 )
{
step2 = tickcount - oldcount2;
}
else
{
step2 = 0xFFFFFFFF - oldcount2 + tickcount;
}
if(step1 > ticks2ps)
{
oldcount1 = tickcount - step1%ticks2ps;
for(i=0; i <(step1 /ticks2ps);i++)
TimerProc();
}
if(step2 > ticks2s)
{
sm_p(SmIdRTCTimer,SM_WAIT,0);
SysTickSecond += step2/ticks2s;
sm_v(SmIdRTCTimer);
#if 0
if((SysTickSecond%60) == 0)
{
strtime = ctime((const time_t*)&SysTickSecond);
DB_PRINT("UsrTimerProc: SysTickSecond = %x,%s\n",SysTickSecond,strtime);
}
#endif
oldcount2 = tickcount -step2%ticks2s;
}
tm_wkafter(50);
}
}
int InitSysTimer()
{
int err;
// DB_PRINT("netping_init: start\n");
InitTMCB();
err=t_create("TICKS",100,10000,10000,0,&tidRTCTimer);
err=t_start(tidRTCTimer, T_PREEMPT | T_TSLICE | T_ASR | T_ISR, UsrTimerProc, 0);
if (err)
{
DB_PRINT("t_start failed!!!!! and err = %d. \n", err);
return (-1);
}
tm_wkafter(50);
_SetTimer( 15000, RtcSynTimer,0);
return(0);
}
int SetRtcTimer(unsigned long sec)
{
sm_p(SmIdRTCTimer,SM_WAIT,0);
SysTickSecond = sec;
sm_v(SmIdRTCTimer);
return 0;
}
unsigned long GetRtcTimer()
{
return SysTickSecond;
}
void RtcSynTimer()
{
unsigned long mydate;
char* strtime;
char strval[50];
_SetTimer( 1800000, RtcSynTimer,0);
#if 1
mydate = GetRtcTimer();
strtime = ctime((const time_t*)&mydate);
strcpy(strval,strtime);
DB_PRINT("RtcSynTimer:curtime=%x,%s\n ",mydate,strval);
/*
SetRtcTimer(28800);
mydate = GetRtcTimer();
strtime = ctime((const time_t*)&mydate);
strcpy(strval,strtime);
DB_PRINT("RtcSynTimer-1:curtime=%x,%s\n ",mydate,strval);
SetRtcTimer(28800 + 3000);
mydate = GetRtcTimer();
strtime = ctime((const time_t*)&mydate);
strcpy(strval,strtime);
DB_PRINT("RtcSynTimer-2:curtime=%x,%s\n ",mydate,strval);
*/
#endif
// 与中心服务器同步时间
/*
if(sntpcTimeGet(DST_STREAM_HOST_IP,1000,&mydate) ==0)
{
mydate +=28800;// east 8th timearea tune
SetRtcTimer(mydate);
strtime = ctime((const time_t*)&mydate);
DB_PRINT("RtcSynTimer:time=%x,%s\n ",mydate,strtime);
}
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -