📄 usertimer.c
字号:
/********************************************************
*
* File: BscTimer.c
*
* Description:
* This file contains routines about Timer Manager Module.
*
* Author: Weiming Zhang
*
* Created Date: Feb 2,2002
* Completed Date: Feb 23,2002
*
********************************************************/
#include "Includes.h"
#include "UserTimer.h"
IUT iut[MAXIUT]; /* allocate memory for MAXIUT iuts */
IUT *FreeIutHead; /* pointing to the FIRST availabel IUTs */
IUT *FreeIutTail; /* pointing to the LAST available IUTs */
IUT *ChainHead;
extern OS_EVENT *rom peventTimer;
extern OS_MEM *pMemSml;
//extern OS_EVENT *rom MsgQueue[OS_LOWEST_PRIO+1]; /* Message queue pointer */
extern void Func_Clear_Msg(INT8U rom * pMsg);
extern void OSTrap(INT8U);
extern void TimerISR(void);
//TIMERPRO xdata timerpro[MAXPRO];
//extern unsigned char SendMsg(unsigned char len,unsigned char srcid,unsigned char destid,unsigned char msgid,unsigned char *info);
void TimerMgtInit()
{
char i;
/* Initialize the available IUTs */
FreeIutHead=&iut[0];
FreeIutTail=&iut[MAXIUT-1];
for(i=0;i<MAXIUT-1;i++)
iut[i].next=&iut[i+1];
iut[MAXIUT-1].next=NULL;
/* Initialize the available TIMERPROs array */
// for(i=0;i<=MAXPRO-1;i++){
// timerpro[i].source=0;
// timerpro[i].type=0;
// timerpro[i].interval=0;
// }
/* Initialize the head of IUT-chain */
ChainHead=NULL;
return;
}
//void TickPostSem()
//{
// if(ChainHead!=NULL)
// OSQPost(MsgQueue[TASK_TIMER_PRIO],(rom INT8U *)TIMER_SEM);
//}
/*
void TimerSendMsg(INT8U prio,INT16U timer_id)
{
INT8U err;
TIMER_MESSAGE *addr1;
addr1=(TIMER_MESSAGE *)OSMemGet(pMemSml,&err);
if(err!=OS_NO_ERR){
OSTrap(TASK_TIMER_PRIO+80);
}
addr1->Len=8;
addr1->Src=TASK_TIMER_PRIO;
addr1->Des=prio;
addr1->MID=Timer_TimeOut;
addr1->TID=timer_id;
addr1->Val=0xEEEE;
OSQPost(MsgQueue[prio],(rom INT8U *)addr1);
}
*/
/* Calculate the Timer interval and position of IUT */
void IutInsert(IUT * piut)
{
unsigned short val;
IUT *p1;
IUT *p2; /* p1 is front-pointer,p2 is rear-pointer */
val=piut->interval;
p1=ChainHead; /* p1 points to the front IUT */
p2=p1->next; /* p2 points to the back IUT */
if(p1!=NULL){
if(val<p1->interval){
piut->interval=val; /* "piut" should be the first IUT (This line is useless.) */
piut->next=p1;
ChainHead=piut;
p1->interval-=val; /* modify the next IUT's interval */
}
else{
val-=p1->interval;
while(p2!=NULL&&val>=p2->interval){ /* shift backward */
p1=p2;
p2=p2->next;
val-=p1->interval;
}
piut->interval=val; /* Insert "piut" into the chain */
piut->next=p2;
p1->next=piut;
if(p2!=NULL) p2->interval-=val; /* not the end of chain */
}
}
else{ /* "piut" is the first IUT of that chain */
piut->interval=val;
piut->next=NULL;
ChainHead=piut;
}
}
void StartTimer(OS_EVENT *psrc,unsigned short typ,unsigned short val)
{
IUT *pfront;
IUT *p; /* p to the desired IUT, pfront's IUT is in front of p's IUT */
unsigned char iutfound;
unsigned char i;
// if(src==0 || typ==0 || val==0) return;
// if(typ&0x8000){ /* for SPECIAL timer */
// for(i=0;i<MAXPRO;i++){ /* Clear the original reload infomation */
// if(timerpro[i].source==src && timerpro[i].type==typ){
// timerpro[i].source=0;
// timerpro[i].type=0; /* This line is useless! */
// }
// }
// for(i=0;i<MAXPRO;i++){ /* Load the new information of SPECIAL timer */
// if(timerpro[i].source==0){ /* Get a free TIMERPRO */
// timerpro[i].source=src;
// timerpro[i].type=typ;
// timerpro[i].interval=val;
// break; /* Load successful! So break, i<MAXPRO. */
// }
// }
// if(i>=MAXPRO){ /* No room for this timer, i++ --> i=MAXPRO. */
// /* What happens when there is not enough room for TIMERPRO-unit? Send timeout message directly? */
// return;
// }
// }
iutfound=0;
OS_ENTER_CRITICAL();
pfront=ChainHead;
p=ChainHead;
/* If the desired IUT cannot be found in the chain, get a free-IUT */
while(p!=NULL){
if((p->Origin==psrc)&&(p->type==typ)){
if(p->next!=NULL)
p->next->interval+=p->interval; /* Modify next-IUT's interval */
if(p==ChainHead) /* Pick the desired IUT out */
ChainHead=p->next; /* p is to the First IUT */
else
pfront->next=p->next; /* p is not to the First IUT */
if(typ&0x8000) /* for SPECIAL timer */
p->initcnt=val;
else /* for NORMAL timer */
p->initcnt=0;
p->interval=val; /* modify the interval */
IutInsert(p);
iutfound=1; /* found the IUT in the working chain */
break;
}
else{
pfront=p; /* shift backward and go on looking for ... */
p=p->next;
}
}
OS_EXIT_CRITICAL();
if(iutfound!=1){ /* If IUT cannot be found in the chain,then catch a NEW IUT from the free-iut-chain. */
OS_ENTER_CRITICAL();
if(FreeIutHead->next!=NULL){ /* Be sure that there is at least one IUT in the free-chain. */
p=FreeIutHead;
FreeIutHead=FreeIutHead->next;
if(typ&0x8000) /* for SPECIAL timer */
p->initcnt=val;
else /* for NORMAL timer */
p->initcnt=0;
p->interval=val;
p->type=typ;
p->Origin=psrc;
p->next=NULL;
IutInsert(p); /* Insert the IUT into the working-chain. */
}
OS_EXIT_CRITICAL();
// else{
// /* What happens when there is not enough free-IUT? Send timeout message directly? */
// return;
// }
}
}
void StopTimer(OS_EVENT *psrc,unsigned short typ)
{
IUT *pfront;
IUT *p; /* p pointing to the desired IUT */
unsigned char i;
// if(typ&0x8000){ /* Stop the SPECIAL timer */
// for(i=0;i<MAXPRO;i++){
// if(timerpro[i].source==src && timerpro[i].type==typ){
// timerpro[i].source=0; /* Clear the reload value */
// timerpro[i].type=0;
// timerpro[i].interval=0;
// break; /* break from "for" */
// }
// }
// }
OS_ENTER_CRITICAL();
pfront=ChainHead;
p=ChainHead;
/* If the desired IUT cannot be found in the working chain, nothing ought to do */
while(p!=NULL){
if((p->Origin==psrc)&&(p->type==typ)){
if(p->next!=NULL)
p->next->interval+=p->interval; /* Modify next-IUT's interval */
if(p==ChainHead) /* Pick the desired IUT out */
ChainHead=p->next; /* p is to the First IUT */
else
pfront->next=p->next; /* p is not to the First IUT */
p->next=NULL; /* Free the IUT */
FreeIutTail->next=p;
FreeIutTail=p;
break;
}
else{
pfront=p; /* shift backwards */
p=p->next;
}
}
OS_EXIT_CRITICAL();
}
void TimerISR(void)
{
IUT *p;
// unsigned char i;
// unsigned short timer_id;
INT8U err;
TIMER_MESSAGE *addr1;
if(ChainHead!=NULL){
ChainHead->interval-=1; /* count down for 1 */
while(ChainHead!=NULL && ChainHead->interval==0){
addr1=(TIMER_MESSAGE *)OSMemGet(pMemSml,&err);
if(err!=OS_NO_ERR){
OSTrap(TASK_TIMER_PRIO+160);
}
((MSG_HEAD *)addr1)->Msg_ID=MSG_TIMER_EXPIRE;
((MSG_HEAD *)addr1)->Origin=peventTimer; //should be changed to peventTimer
((MSG_HEAD *)addr1)->Attached=FALSE;
((MSG_HEAD *)addr1)->pmemME=pMemSml;
((MSG_HEAD *)addr1)->LenOfBody=2;
((TIMER_MESSAGE *)addr1)->TID=ChainHead->type;
OSQPost(ChainHead->Origin,(rom INT8U *)addr1);
// timer_id=ChainHead->type;
// TimerSendMsg(ChainHead->source,timer_id); /* Here is a CONSTANT(6) */
/* send timer expiry message ChainHead->type from TimerProc_module to ChainHead->source */
p=ChainHead;
ChainHead=ChainHead->next;
if(p->type & 0x8000){
p->interval=p->initcnt; /* reload the timer inteval */
IutInsert(p);
// for(i=0;i<MAXPRO;i++){
// if(timerpro[i].source==p->source && timerpro[i].type==p->type){
// p->interval=timerpro[i].interval; /* reload the timer inteval */
// IutInsert(p);
// break; /* break from "for" */
// }
// }
// if(i>=MAXPRO){
// /* What happens when the TIMERPRO cannot be found? */
// FreeIutTail->next=p; /* free the IUT */
// FreeIutTail=p;
// FreeIutTail->next=NULL; /* Should be at the end */
// }
}
else{
FreeIutTail->next=p;
FreeIutTail=p;
FreeIutTail->next=NULL; /* Should be at the end */
}
}
}
}
void TimerManager(OS_EVENT *peventTimer)
{
void rom * pMsg;
INT8U err;
pMsg=OSQPend(peventTimer,0,&err);
if(err==OS_NO_ERR){
if((INT24U)pMsg >= PTR_MAX){
OSTrap(TASK_TIMER_PRIO+64);
}
else{
if(((MSG_HEAD *)pMsg)->Attached)
OSTrap(TASK_TIMER_PRIO+96);
if(((MSG_HEAD *)pMsg)->LenOfBody!=2 && ((MSG_HEAD *)pMsg)->LenOfBody!=4)
OSTrap(TASK_TIMER_PRIO+96);
switch (((MSG_HEAD *)pMsg)->Msg_ID){
case MSG_TIMER_START:
StartTimer(((MSG_HEAD *)pMsg)->Origin,((TIMER_MESSAGE *)pMsg)->TID,((TIMER_MESSAGE *)pMsg)->Val);
break;
case MSG_TIMER_STOP:
StopTimer(((MSG_HEAD *)pMsg)->Origin,((TIMER_MESSAGE *)pMsg)->TID);
break;
default:
OSTrap(TASK_TIMER_PRIO+96);
break;
}
Func_Clear_Msg(pMsg);
//err=OSMemPut(((MSG_HEAD *)pMsg)->pmemME, pMsg);
//if(err!=OS_NO_ERR){
// OSTrap(TASK_TIMER_PRIO+128);
//}
}
}
else{
OSTrap(TASK_TIMER_PRIO);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -