📄 win_ss.c
字号:
SsTmrEntry *tmr; /* pointer to timer entry */
#endif
{
CmTmrArg arg;
TRC0(ssdRegTmr);
/* initialize common timers */
cmInitTimers(tmr->dep.timers, TMR_DEF_MAX);
/* start the timer */
arg.tq = osCp.dep.tmrTq;
arg.tqCp = &osCp.dep.tmrTqCp;
arg.timers = tmr->dep.timers;
arg.cb = (PTR) tmr;
arg.evnt = TMR_DEF;
arg.tNum = NOTUSED;
arg.max = TMR_DEF_MAX;
arg.wait = tmr->interval;
cmPlcCbTq(&arg);
RETVALUE(ROK);
}
/*
*
* Fun: Deregister timer
*
* Desc: This function is used to deregister a timer function.
*
* Ret: ROK - ok
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
PUBLIC S16 ssdDeregTmr
(
SsTmrEntry *tmr /* pointer to timer entry */
)
#else
PUBLIC S16 ssdDeregTmr(tmr)
SsTmrEntry *tmr; /* pointer to timer entry */
#endif
{
CmTmrArg arg;
TRC0(ssdDeregTmr);
/* stop the timer */
arg.tq = osCp.dep.tmrTq;
arg.tqCp = &osCp.dep.tmrTqCp;
arg.timers = tmr->dep.timers;
arg.cb = (PTR) tmr;
arg.evnt = TMR_DEF;
arg.wait = 0;
arg.tNum = NOTUSED;
arg.max = TMR_DEF_MAX;
arg.wait = tmr->interval;
cmRmvCbTq(&arg);
RETVALUE(ROK);
}
/*
*
* Fun: Critical error
*
* Desc: This function is called when a critical error occurs.
*
* Ret: ROK - ok
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
PUBLIC S16 ssdError
(
Seq seq, /* sequence number */
Reason reason /* reset reason */
)
#else
PUBLIC S16 ssdError(seq, reason)
Seq seq; /* sequence number */
Reason reason; /* reset reason */
#endif
{
S16 i;
DWORD tId;
DWORD exitCode;
Txt errBuf[256];
TRC0(ssdError);
/* get calling task ID */
/*
tId = taskIdSelf();
*/
tId = GetCurrentThreadId();
/* set up the message to display */
sprintf(errBuf, "\n\nFATAL ERROR - taskid = %x, errno = %d,"
"reason = %d\n\n", tId, seq, reason);
SPrint(errBuf);
/* delete all system tasks */
for ( i = 0; i < SS_MAX_STSKS; i++ )
{
if ( osCp.sTskTbl[i].used
&& (osCp.sTskTbl[i].dep.tId != tId) )
{
/*
taskDelete(osCp.sTskTbl[i].dep.tId);
*/
if ( 0 == TerminateThread(osCp.sTskTbl[i].dep.tHnd,0) )
{
RETVALUE(RFAILED);
}
}
}
/* delete self */
/*
taskDelete(tId);
*/
ExitThread(0);
GetExitCodeThread(GetCurrentThread(),&exitCode);
if ( STILL_ACTIVE == exitCode )
{
RETVALUE(RFAILED);
}
/* won't reach here */
RETVALUE(ROK);
}
/*
*
* Fun: Log error
*
* Desc: This function is called to log an error.
*
* Ret: ROK - ok
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
PUBLIC Void ssdLogError
(
Ent ent, /* Calling layer's entity id */
Inst inst, /* Calling layer's instance id */
ProcId procId, /* Calling layer's processor id */
Txt *file, /* file name where error occured */
S32 line, /* line in file where error occured */
ErrCls errCls, /* error class */
ErrCode errCode, /* layer unique error code */
ErrVal errVal, /* error value */
Txt *errDesc /* description of error */
)
#else
PUBLIC Void ssdLogError(ent, inst, procId, file, line,
errCls, errCode, errVal, errDesc)
Ent ent; /* Calling layer's entity id */
Inst inst; /* Calling layer's instance id */
ProcId procId; /* Calling layer's processor id */
Txt *file; /* file name where error occured */
S32 line; /* line in file where error occured */
ErrCls errCls; /* error class */
ErrCode errCode; /* layer unique error code */
ErrVal errVal; /* error value */
Txt *errDesc; /* description of error */
#endif
{
S16 i;
DWORD tId;
DWORD exitCode;
Txt *errClsMsg;
Txt errBuf[512];
TRC0(ssdLogError);
/* get calling task ID */
/*
tId = taskIdSelf();
*/
tId = GetCurrentThreadId();
switch ( errCls )
{
case ERRCLS_ADD_RES:
errClsMsg = "ERRCLS_ADD_RES";
break;
case ERRCLS_INT_PAR:
errClsMsg = "ERRCLS_INT_PAR";
break;
case ERRCLS_DEBUG:
errClsMsg = "ERRCLS_DEBUG";
break;
default:
errClsMsg = "INVALID ERROR CLASS!";
break;
}
sprintf(errBuf,
"\nmtss(posix): sw error: ent: %03d inst: %03d proc id: %03d \n"
"file: %s line: %03ld errcode: %05ld errcls: %s\n"
"errval: %05ld errdesc: %s\n",
ent, inst, procId, file, line, errCode, errClsMsg, errVal, errDesc);
SDisplay(0, errBuf);
#ifndef DEBUGNOEXIT
/* debug errors halt the system */
if ( errCls == ERRCLS_DEBUG )
{
/* delete all system tasks */
for ( i = 0; i < SS_MAX_STSKS; i++ )
{
if ( osCp.sTskTbl[i].used
&& (osCp.sTskTbl[i].dep.tId != tId) )
{
/*
taskDelete(osCp.sTskTbl[i].dep.tId);
*/
if ( 0 == SuspendThread(osCp.sTskTbl[i].dep.tHnd,0) )
{
/*
RETVALUE(RFAILED);
*/
}
}
}
/* delete self */
/*
taskDelete(tId);
*/
SuspendThread(GetCurrentThread());
if ( STILL_ACTIVE == exitCode )
{
/*
RETVALUE(RFAILED);
*/
}
}
#endif
RETVOID;
}
#ifdef ENB_RELAY
/*
*
* Fun: Register driver task
*
* Desc: This function is called to register the handlers for a
* driver task.
*
* Ret: ROK - ok
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
PUBLIC S16 ssdRegDrvrTsk
(
SsDrvrTskEntry *drvrTsk /* driver task entry */
)
#else
PUBLIC S16 ssdRegDrvrTsk(drvrTsk)
SsDrvrTskEntry *drvrTsk; /* driver task entry */
#endif
{
TRC0(ssdRegDrvrTsk);
RETVALUE(ROK);
}
#endif
/*
* private support functions
*/
/*
*
* Fun: Task handler
*
* Desc: This is the system task handler function. It blocks on
* the system task's demand queue. On receiving a message,
* it identifies the target TAPA task, verifies that the
* TAPA task belongs to this system task and if so, calls
* the activation function of that TAPA task with the
* received message. The task activation function or the
* timer activation function may be called.
*
* Ret: (thread function)
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
DWORD WINAPI winTskHdlr
(
Ptr tskPtr /* pointer to task entry */
)
#else
DWORD WINAPI winTskHdlr(tskPtr)
Ptr tskPtr; /* pointer to task entry */
#endif
{
S16 ret;
SsIdx i;
SsIdx idx;
SsSTskEntry *sTsk;
SsTTskEntry *tTsk;
Buffer *mBuf;
SsMsgInfo *mInfo;
Pst nPst;
PFS16 tmrActvFn;
TRC0(mtTskHdlr);
/* get out the system task entry from the parameter */
sTsk = (SsSTskEntry *) tskPtr;
/* wait for SS to come up */
ssWaitSema(&osCp.dep.ssStarted);
for ( ; ; )
{
/* get a message from the demand queue */
ret = ssDmndQGet(&sTsk->dQ, &mBuf, SS_DQ_FIRST);
if ( ret != ROK )
continue;
/* if we can't lock this system task entry, return the message */
ret = SLock(&sTsk->lock);
if ( ret != ROK )
{
#if (ERRCLASS & ERRCLS_DEBUG)
WINLOGERROR(ERRCLS_DEBUG, EMT007, (ErrVal) ret,
"Could not lock system task entry");
#endif
SPutMsg(mBuf);
continue;
}
/* find out what kind of message this is */
mInfo = (SsMsgInfo *)mBuf->b_rptr;
switch ( mInfo->eventInfo.event )
{
/* this is a termination event, we die */
case SS_EVNT_TERM:
/* release the message */
SPutMsg(mBuf);
/* Unlock the system task entry and lock the system
* task table to clean our entry up.
*/
SUnlock(&sTsk->lock);
ret = SLock(&osCp.sTskTblLock);
if ( ret != ROK )
{
#if (ERRCLASS & ERRCLS_DEBUG)
WINLOGERROR(ERRCLS_DEBUG, EMT008, (ErrVal) ret,
"Could not lock system task table");
#endif
/* what to do here? */
continue;
}
/* clean up the system task entry */
sTsk->used = FALSE;
sTsk->tskPrior = 0;
sTsk->numTTsks = 0;
SDestroyLock(&sTsk->lock);
ssDestroyDmndQ(&sTsk->dQ);
/* lock for current executing TAPA task ID */
SLock(&sTsk->dep.lock);
SDestroyLock(&sTsk->dep.lock);
/* make this entry available in the system task table */
sTsk->nxt = osCp.nxtSTskEntry;
for ( i = 0; i < SS_MAX_STSKS; i++ )
{
if ( sTsk == &osCp.sTskTbl[i] )
{
osCp.nxtSTskEntry = i;
break;
}
}
osCp.numSTsks--;
/* unlock the system task table */
SUnlock(&osCp.sTskTblLock);
/* add by shang */
ssPostSema(&osCp.dep.ssStarted);
/* add by shang over */
return NULLP;
/* this is a data message or a permanent task keep-alive message */
case SS_EVNT_DATA:
case SS_EVNT_PERMTICK:
/* message to a task. find the destination task */
idx = osCp.tTskIds[mInfo->pst.dstEnt][mInfo->pst.dstInst];
/* verify that it hasn't been deregistered */
if ( idx == SS_TSKNC )
{
SPutMsg(mBuf);
break;
}
/* verify that this system task is still running it */
tTsk = &osCp.tTskTbl[idx];
if ( tTsk->sTsk != sTsk )
{
SPutMsg(mBuf);
break;
}
/* set the current executing TAPA task ID */
ret = SLock(&sTsk->dep.lock);
if ( ret == ROK )
{
sTsk->dep.ent = mInfo->pst.dstEnt;
sTsk->dep.inst = mInfo->pst.dstInst;
SUnlock(&sTsk->dep.lock);
}
/* copy the Pst structure into a local duplicate */
for ( i = 0; i < (S16) sizeof(Pst); i++ )
*(((U8 *)(&nPst)) + i) = *(((U8 *)&mInfo->pst) + i);
/* Give the message to the task activation function. If
* its a normal data message, we pass it, if this is a
* keep-alive message for a permanent task then we pass
* NULLP in place of the message to the task activation
* function.
*/
if ( mInfo->eventInfo.event == SS_EVNT_DATA )
{
tTsk->actvTsk(&nPst, mBuf);
}
else
{
#if (ERRCLASS & ERRCLS_DEBUG)
/* this message should only come to a permanent task */
if ( tTsk->tskType != SS_TSK_PERMANENT )
{
WINLOGERROR(ERRCLS_DEBUG, EMT009, ERRZERO, "Logic failure");
break;
}
#endif
tTsk->actvTsk(&nPst, NULLP);
/* We need to re-send this message back to ourselves so
* the permanent task continues to run.
*/
if ( tTsk->used )
{
ret = ssDmndQPutLast(&sTsk->dQ, mBuf,
((tTsk->tskPrior) * SS_MAX_MSG_PRI) +
mInfo->pst.prior);
/* failure here is a real problem */
if ( ret != ROK )
{
#if (ERRCLASS & ERRCLS_DEBUG)
WINLOGERROR(ERRCLS_DEBUG, EMT010, ERRZERO,
"Could not write to demand queue");
#endif
SPutMsg(mBuf);
}
}
else
SPutMsg(mBuf);
}
/* unset the current executing TAPA task ID */
ret = SLock(&sTsk->dep.lock);
if ( ret == ROK )
{
sTsk->dep.ent = ENTNC;
sTsk->dep.inst = INSTNC;
SUnlock(&sTsk->dep.lock);
}
break;
case SS_EVNT_TIMER:
/* timer event. find the timer entry */
idx = mInfo->eventInfo.u.tmr.tmrIdx;
/* lock the timer table, coz we're going to peek in it */
ret = SLock(&osCp.tmrTblLock);
if ( ret != ROK )
{
#if (ERRCLASS & ERRCLS_DEBUG)
WINLOGERROR(ERRCLS_DEBUG, EMT011, (ErrVal) ret,
"Could not lock timer table");
#endif
SPutMsg(mBuf);
break;
}
/* Verify that this timer entry is still around and that it
* belongs to our task.
*/
if ( osCp.tmrTbl[idx].used == FALSE
|| osCp.tmrTbl[idx].ownerEnt != mInfo->pst.dstEnt
|| osCp.tmrTbl[idx].ownerInst != mInfo->pst.dstInst )
{
SUnlock(&osCp.tmrTblLock);
SPutMsg(mBuf);
break;
}
tmrActvFn = osCp.tmrTbl[idx].tmrActvFn;
/* unlock the timer table */
SUnlock(&osCp.tmrTblLock);
/* activate the timer function */
tmrActvFn();
/* return the message buffer */
SPutMsg(mBuf);
break;
default:
#if (ERRCLASS & ERRCLS_DEBUG)
WINLOGERROR(ERRCLS_DEBUG, EMT012, (ErrVal) ret,
"Illegal event");
#endif
break;
}
/* unlock the system task entry */
SUnlock(&sTsk->lock);
/* yield for other threads */
/*
taskDelay(1);
*/
/*Sleep(1);*/
}
/* should not reach here */
}
/*
*
* Fun: winTmrHdlr
*
* Desc: The timer handler thread function. Counts time
* and invokes the common timer function on each
* tick.
*
* Ret: (thread function)
*
* Notes:
*
* File: win_ss.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -