Refactor the timer clearing; force timer clear on set; improve the tracing of timer operations.

r3616 | dcl | 2012-06-26 14:36:32 +1000 (Tue, 26 Jun 2012) | 1 line
This commit is contained in:
Douglas Clowes
2012-06-26 14:36:32 +10:00
parent 5dd1ff27a4
commit eeac77f9ce

View File

@@ -35,7 +35,7 @@
#define UNITSLEN 256
#define TEXTPARLEN 1024
#define CMDLEN 1024
#define STATE_TRACE (100)
#define STATE_TRACE (200)
/** \brief Used to ensure that the getDMCSetting function is called
* with valid values.
@@ -51,7 +51,9 @@ enum eventtype {
eTimerEvent,
eMessageEvent,
eCommandEvent,
eTimeoutEvent
eTimeoutEvent,
eTimerSet, /* pseudo-event for state trace only */
eTimerClear /* pseudo-event for state trace only */
};
typedef struct EvtEvent_s EvtEvent, *pEvtEvent;
@@ -73,6 +75,14 @@ typedef struct EvtCommand_s {
typedef struct EvtTimeout_s { } EvtTimeout;
typedef struct TimerClear_s { /* pseudo-event for state trace only */
int timerValue;
} TimerClear;
typedef struct TimerSet_s { /* pseudo-event for state trace only */
int timerValue;
} TimerSet;
struct EvtEvent_s {
enum eventtype event_type;
union {
@@ -81,6 +91,8 @@ struct EvtEvent_s {
EvtMessage msg;
EvtCommand cmd;
EvtTimeout tmo;
TimerSet tms;
TimerClear tmc;
} event;
};
@@ -283,6 +295,9 @@ static int state_msg_callback(pAsyncTxn pCmd);
static int state_tmr_callback(void* ctx, int mode);
static int state_cmd_execute(pDMC2280Driv self, enum commandtype cmd);
static void report_event(pDMC2280Driv self, pEvtEvent event);
static void state_trace_prn(pDMC2280Driv self);
static char* state_name(StateFunc func);
static int DMC2280Halt(void *pData);
static int DMC2280SetPar(void *pData, SConnection *pCon,
char *name, float newValue);
@@ -845,7 +860,42 @@ static int DMC_SendReceive(pDMC2280Driv self, char *cmd, char* reply) {
return OKOK;
}
/*
* Clear the timer if it is set
*/
static void DMC_ClearTimer(pDMC2280Driv self) {
/* only if the timer is really set */
if (self->state_timer) {
/* log this event in the trace buffer */
EvtEvent event;
event.event_type = eTimerClear;
event.event.tmc.timerValue = self->timerValue;
report_event(self, &event);
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
}
}
static void DMC_SetTimer(pDMC2280Driv self, int msecs) {
EvtEvent event;
/* if the timer is already set, log the logic error and clear it */
if (self->state_timer != 0) {
char line[133];
snprintf(line, 132, "Motor %s, state %s(%d): setting new timer (%d mSec) when old (%d mSec) active, clearing",
self->name,
state_name(self->myState),
self->subState,
msecs,
self->timerValue);
SICSLogWrite(line, eError);
DMC_ClearTimer(self);
state_trace_prn(self);
}
/* log this event in the trace buffer */
event.event_type = eTimerSet;
event.event.tms.timerValue = msecs;
report_event(self, &event);
self->timerValue = msecs;
NetWatchRegisterTimer(&self->state_timer, msecs, state_tmr_callback, self);
}
@@ -1467,6 +1517,12 @@ static char* event_name(pEvtEvent event, char* text, int length) {
case eTimerEvent:
snprintf(text, length, "eTimerEvent (%d mSec)", event->event.tmr.timerValue);
return text;
case eTimerSet:
snprintf(text, length, "eTimerSet (%d mSec)", event->event.tms.timerValue);
return text;
case eTimerClear:
snprintf(text, length, "eTimerClear (%d mSec)", event->event.tmc.timerValue);
return text;
case eMessageEvent:
snprintf(text, length, "eMessageEvent:");
str_n_cat(text, length, event->event.msg.cmd->out_buf);
@@ -1741,9 +1797,7 @@ static void DMCState_Unknown(pDMC2280Driv self, pEvtEvent event) {
static void DMCState_Idle(pDMC2280Driv self, pEvtEvent event) {
switch (event->event_type) {
case eStateEvent:
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
DMC_ClearTimer(self);
if (self->driver_status == HWBusy)
self->driver_status = HWIdle;
if (self->variables & VAR_RUN) {
@@ -1828,10 +1882,7 @@ static void DMCState_MotorStart(pDMC2280Driv self, pEvtEvent event) {
switch (event->event_type) {
case eStateEvent:
self->run_flag = 0;
if (self->state_timer) {
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
}
DMC_ClearTimer(self);
/* If Motion Control is off, report HWFault */
if (DMC2280MotionControl != 1) {
state_cmd_execute(self, CMD_HALT);
@@ -2433,9 +2484,7 @@ static void DMCState_Moving(pDMC2280Driv self, pEvtEvent event) {
static void DMCState_MotorHalt(pDMC2280Driv self, pEvtEvent event) {
switch (event->event_type) {
case eStateEvent:
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
DMC_ClearTimer(self);
cmdHalt(self);
/* Note fall through */
case eTimerEvent:
@@ -2517,18 +2566,14 @@ static void DMCState_OffTimer(pDMC2280Driv self, pEvtEvent event) {
switch (event->event.cmd.cmd_type) {
case CMD_RUN:
/* handle run command, convert to motor on timer expired */
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
DMC_ClearTimer(self);
if (self->driver_status == HWIdle)
self->driver_status = HWBusy;
change_state(self, DMCState_MotorOn);
return;
case CMD_HALT:
/* handle halt command, convert to motor off timer expired */
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
DMC_ClearTimer(self);
change_state(self, DMCState_MotorStop);
return;
}
@@ -2897,9 +2942,7 @@ static int DMC2280Fix(void *pData, int iCode,/*@unused@*/ float fValue){
return MOTREDO;
case STATEERROR:
/* recover state error */
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
DMC_ClearTimer(self);
change_state(self, DMCState_Unknown);
return MOTFAIL;
default:
@@ -2923,8 +2966,8 @@ static int DMC2280Halt(void *pData){
self = (pDMC2280Driv)pData;
assert(self != NULL);
state_trace_prn(self);
state_cmd_execute(self, CMD_HALT);
state_trace_prn(self);
return 1;
}
@@ -3527,15 +3570,14 @@ static void DMC_Notify(void* context, int event) {
snprintf(line, 132, "Disconnect on Motor '%s'", self->name);
SICSLogWrite(line, eStatus);
/* TODO: disconnect */
change_state(self, DMCState_Error);
break;
case AQU_RECONNECT:
snprintf(line, 132, "Reconnect on Motor '%s'", self->name);
SICSLogWrite(line, eStatus);
/* TODO: reconnect */
/* Reset the state machine */
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
DMC_ClearTimer(self);
change_state(self, DMCState_Unknown);
break;
}
@@ -4060,9 +4102,7 @@ int DMC2280Action(SConnection *pCon, SicsInterp *pSics, void *pData,
}
else if(strcasecmp("reset", argv[1]) == 0) {
/* Reset the state machine */
if (self->state_timer)
NetWatchRemoveTimer(self->state_timer);
self->state_timer = 0;
DMC_ClearTimer(self);
self->driver_status = HWIdle;
change_state(self, DMCState_Unknown);
while (self->myState == DMCState_Unknown) {