revise logging and state trace

r3790 | dcl | 2012-11-13 13:38:25 +1100 (Tue, 13 Nov 2012) | 1 line
This commit is contained in:
Douglas Clowes
2012-11-13 13:38:25 +11:00
parent fa18677fca
commit fd064f3df9

View File

@ -62,7 +62,10 @@ typedef struct EvtEvent_s EvtEvent, *pEvtEvent;
typedef void (*StateFunc)(pDMC2280Driv self, pEvtEvent event); typedef void (*StateFunc)(pDMC2280Driv self, pEvtEvent event);
typedef struct EvtState_s { } EvtState; typedef struct EvtState_s {
StateFunc oldState;
StateFunc newState;
} EvtState;
typedef struct EvtTimer_s { typedef struct EvtTimer_s {
int timerValue; int timerValue;
@ -223,6 +226,8 @@ struct __MoDriv {
int variables; int variables;
#if defined(STATE_TRACE) && (STATE_TRACE > 0) #if defined(STATE_TRACE) && (STATE_TRACE > 0)
int state_trace_idx; int state_trace_idx;
int state_trace_old;
char state_trace_done[STATE_TRACE];
char state_trace_text[STATE_TRACE][CMDLEN]; char state_trace_text[STATE_TRACE][CMDLEN];
struct timeval state_trace_time[STATE_TRACE]; struct timeval state_trace_time[STATE_TRACE];
#endif #endif
@ -772,11 +777,21 @@ static int SendCallback(pAsyncTxn pCmd) {
case '?': case '?':
strncpy(self->lastCmd, pCmd->out_buf, CMDLEN); strncpy(self->lastCmd, pCmd->out_buf, CMDLEN);
strncpy(self->dmc2280Error, &resp[1], CMDLEN); strncpy(self->dmc2280Error, &resp[1], CMDLEN);
SICSLogWrite("SendCallback: BADCMD", eError);
SICSLogWrite(cmnd, eError); SICSLogWrite(cmnd, eError);
SICSLogWrite(resp, eError); SICSLogWrite(resp, eError);
self->errorCode = BADCMD; self->errorCode = BADCMD;
break; break;
default: default:
if ((cmnd[0] == 'M' && cmnd[1] == 'G') || (cmnd[0] == 'L' && cmnd[1] == 'V')) {
/* MG and LV commands can produce this result */
if (self->debug) {
SICSLogWrite(cmnd, eStatus);
SICSLogWrite(resp, eStatus);
}
break;
}
SICSLogWrite("SendCallback: BADUNKNOWN", eError);
SICSLogWrite(cmnd, eError); SICSLogWrite(cmnd, eError);
SICSLogWrite(resp, eError); SICSLogWrite(resp, eError);
self->errorCode = BADUNKNOWN; self->errorCode = BADUNKNOWN;
@ -837,13 +852,14 @@ static int DMC_SendReceive(pDMC2280Driv self, char *cmd, char* reply) {
} }
switch (reply[0]) { switch (reply[0]) {
case ':': case ':': /* prompt */
if (self->debug) { if (self->debug) {
SICSLogWrite(cmd, eStatus); SICSLogWrite(cmd, eStatus);
SICSLogWrite(reply, eStatus); SICSLogWrite(reply, eStatus);
} }
return SUCCESS; return SUCCESS;
case ' ': case ' ': /* leading blank */
case '-': /* leading minus sign */
if (self->debug) { if (self->debug) {
SICSLogWrite(cmd, eStatus); SICSLogWrite(cmd, eStatus);
SICSLogWrite(reply, eStatus); SICSLogWrite(reply, eStatus);
@ -852,13 +868,23 @@ static int DMC_SendReceive(pDMC2280Driv self, char *cmd, char* reply) {
case '?': case '?':
strncpy(self->lastCmd, cmd, CMDLEN); strncpy(self->lastCmd, cmd, CMDLEN);
strncpy(self->dmc2280Error, &reply[1], CMDLEN); strncpy(self->dmc2280Error, &reply[1], CMDLEN);
SICSLogWrite("DMC_SendReceive: BADCMD", eError);
SICSLogWrite(cmd, eError); SICSLogWrite(cmd, eError);
SICSLogWrite(reply, eError); SICSLogWrite(reply, eError);
self->errorCode = BADCMD; self->errorCode = BADCMD;
return FAILURE; return FAILURE;
default: default:
if ((cmd[0] == 'M' && cmd[1] == 'G') || (cmd[0] == 'L' && cmd[1] == 'V')) {
/* MG and LV commands can produce this result */
if (self->debug) {
SICSLogWrite(cmd, eStatus);
SICSLogWrite(reply, eStatus);
}
return SUCCESS;
}
strncpy(self->lastCmd, cmd, CMDLEN); strncpy(self->lastCmd, cmd, CMDLEN);
strncpy(self->dmc2280Error, &reply[0], CMDLEN); strncpy(self->dmc2280Error, &reply[0], CMDLEN);
SICSLogWrite("DMC_SendReceive: BADUNKNOWN", eError);
SICSLogWrite(cmd, eError); SICSLogWrite(cmd, eError);
SICSLogWrite(reply, eError); SICSLogWrite(reply, eError);
self->errorCode = BADUNKNOWN; self->errorCode = BADUNKNOWN;
@ -1503,20 +1529,32 @@ static int rspPoll(pDMC2280Driv self, const char* text) {
static void state_trace_prn(pDMC2280Driv self) { static void state_trace_prn(pDMC2280Driv self) {
#if defined(STATE_TRACE) && (STATE_TRACE > 0) #if defined(STATE_TRACE) && (STATE_TRACE > 0)
int idx = self->state_trace_idx; int idx = self->state_trace_idx;
SICSLogWrite("state_trace_prn trace listing start", eStatus); int lines_printed = 0;
struct timeval tv;
gettimeofday(&tv, NULL);
do { do {
char* line; char* line;
struct timeval *tp; struct timeval *tp;
tp = &self->state_trace_time[self->state_trace_idx]; tp = &self->state_trace_time[idx];
line = &self->state_trace_text[self->state_trace_idx++][0]; if (self->state_trace_done[idx])
if (self->state_trace_idx >= STATE_TRACE) line = NULL;
self->state_trace_idx = 0; else
if (*line) line = &self->state_trace_text[idx][0];
if (line && *line) {
if (lines_printed == 0)
/* print the opening message only if there are lines to print */
SICSLogTimePrintf(eStatus, &tv, "Motor: %s, state_trace_prn trace history listing start", self->name);
SICSLogWriteTime(line, eStatus, tp); SICSLogWriteTime(line, eStatus, tp);
lines_printed++;
}
self->state_trace_done[idx] = 1;
if (++idx >= STATE_TRACE)
idx = 0;
} while (idx != self->state_trace_idx); } while (idx != self->state_trace_idx);
SICSLogWrite("state_trace_prn trace listing end", eStatus); /* print a close message, even if there are zero lines */
SICSLogTimePrintf(eStatus, &tv, "Motor: %s, state_trace_prn trace history listing end (%d entries)", self->name, lines_printed);
#else #else
SICSLogWrite("state_trace_prn not implemented", eStatus); SICSLogPrintf(eStatus, "Motor: %s, state_trace_prn not implemented", self->name);
#endif #endif
} }
@ -1548,17 +1586,38 @@ static char* state_name(StateFunc func) {
static void str_n_cat(char* s1, int len, const char* s2) { static void str_n_cat(char* s1, int len, const char* s2) {
int i = strlen(s1); int i = strlen(s1);
const char* p = s2; const char* p = s2;
while (i < len - 3 && *p) { while (i < len - 1 && *p) {
if (*p == '\r') { if (*p == '\r') {
if (i >= len -3)
break;
s1[i++] = '\\'; s1[i++] = '\\';
s1[i++] = 'r'; s1[i++] = 'r';
++p; ++p;
} }
else if (*p == '\n') { else if (*p == '\n') {
if (i >= len -3)
break;
s1[i++] = '\\'; s1[i++] = '\\';
s1[i++] = 'n'; s1[i++] = 'n';
++p; ++p;
} }
else if (*p == '\t') {
if (i >= len -3)
break;
s1[i++] = '\\';
s1[i++] = 't';
++p;
}
else if (*p < ' ' || *p > '~') {
const char hex[] = "0123456789ABCDEF";
if (i >= len -5)
break;
s1[i++] = '<';
s1[i++] = hex[(*p >> 4) & 0xF];
s1[i++] = hex[(*p) & 0xF];
s1[i++] = '>';
++p;
}
else else
s1[i++] = *p++; s1[i++] = *p++;
} }
@ -1568,7 +1627,9 @@ static void str_n_cat(char* s1, int len, const char* s2) {
static char* event_name(pEvtEvent event, char* text, int length) { static char* event_name(pEvtEvent event, char* text, int length) {
switch (event->event_type) { switch (event->event_type) {
case eStateEvent: case eStateEvent:
snprintf(text, length, "eStateEvent"); snprintf(text, length, "eStateEvent (%s => %s)",
state_name(event->event.sta.oldState),
state_name(event->event.sta.newState));
return text; return text;
case eTimerEvent: case eTimerEvent:
snprintf(text, length, "eTimerEvent (%d mSec)", event->event.tmr.timerValue); snprintf(text, length, "eTimerEvent (%d mSec)", event->event.tmr.timerValue);
@ -1605,120 +1666,109 @@ static char* event_name(pEvtEvent event, char* text, int length) {
} }
} }
static void report_event(pDMC2280Driv self, pEvtEvent event) { static void state_trace_ins(pDMC2280Driv self, const char *fmt, ...) {
#if defined(STATE_TRACE) && (STATE_TRACE > 0) va_list ap;
if (true) {
char* line;
gettimeofday(&self->state_trace_time[self->state_trace_idx], NULL);
line = &self->state_trace_text[self->state_trace_idx++][0];
if (self->state_trace_idx >= STATE_TRACE)
self->state_trace_idx = 0;
#else
if (self->debug || self->trace) {
char line[CMDLEN]; char line[CMDLEN];
char *lp = line;
#if defined(STATE_TRACE) && (STATE_TRACE > 0)
gettimeofday(&self->state_trace_time[self->state_trace_idx], NULL);
lp = &self->state_trace_text[self->state_trace_idx][0];
self->state_trace_done[self->state_trace_idx] = 0;
if (true)
#else
if (self->debug || self->trace)
#endif #endif
char text[CMDLEN]; {
snprintf(line, CMDLEN, "Motor=%s, State=%s(%d), event=%s", char format[CMDLEN];
snprintf(format, CMDLEN, "Motor=%s, State=%s(%d), %s",
self->name, self->name,
state_name(self->myState), state_name(self->myState),
self->subState, self->subState,
event_name(event, text, CMDLEN)); fmt);
va_start(ap, fmt);
vsnprintf(lp, CMDLEN, format, ap);
va_end(ap);
if (self->debug) if (self->debug)
SICSLogWrite(line, eStatus); SICSLogWrite(lp, eStatus);
if (self->trace) if (self->trace)
SCWrite(self->trace, line, eStatus); SCWrite(self->trace, lp, eStatus);
} }
#if defined(STATE_TRACE) && (STATE_TRACE > 0)
if (++self->state_trace_idx >= STATE_TRACE)
self->state_trace_idx = 0;
#endif
}
static void report_event(pDMC2280Driv self, pEvtEvent event) {
#if defined(STATE_TRACE) && (STATE_TRACE > 0)
if (true)
#else
if (self->debug || self->trace)
#endif
{
char text[CMDLEN];
state_trace_ins(self, "Event=%s",
event_name(event, text, CMDLEN));
}
}
static void unhandled_event(pDMC2280Driv self, pEvtEvent event) {
char text[CMDLEN];
state_trace_ins(self, "Unhandled Event=%s",
event_name(event, text, CMDLEN));
}
static void handle_event(pDMC2280Driv self, pEvtEvent event) {
#if defined(STATE_TRACE) && (STATE_TRACE > 0)
if (true)
#else
if (self->debug || self->trace)
#endif
{
report_event(self, event);
}
self->myState(self, event);
} }
static void change_state(pDMC2280Driv self, StateFunc func) { static void change_state(pDMC2280Driv self, StateFunc func) {
#if defined(STATE_TRACE) && (STATE_TRACE > 0) #if defined(STATE_TRACE) && (STATE_TRACE > 0)
if (true) { if (true)
char* line;
gettimeofday(&self->state_trace_time[self->state_trace_idx], NULL);
line = &self->state_trace_text[self->state_trace_idx++][0];
if (self->state_trace_idx >= STATE_TRACE)
self->state_trace_idx = 0;
#else #else
if (self->debug || self->trace) { if (self->debug || self->trace)
char line[CMDLEN];
#endif #endif
snprintf(line, CMDLEN, "Motor=%s, OldState=%s(%d), NewState=%s", {
self->name, state_trace_ins(self, "NewState=%s",
state_name(self->myState),
self->subState,
state_name(func)); state_name(func));
if (self->debug)
SICSLogWrite(line, eStatus);
if (self->trace)
SCWrite(self->trace, line, eStatus);
} }
self->myPrevState = self->myState; self->myPrevState = self->myState;
self->myState = func; self->myState = func;
self->subState = 0; self->subState = 0;
EvtEvent evt; EvtEvent evt;
evt.event_type = eStateEvent; evt.event_type = eStateEvent;
evt.event.sta.oldState = self->myPrevState;
evt.event.sta.newState = self->myState;
self->myState(self, &evt); self->myState(self, &evt);
} }
static void unhandled_event(pDMC2280Driv self, pEvtEvent event) {
#if defined(STATE_TRACE) && (STATE_TRACE > 0)
char* line;
gettimeofday(&self->state_trace_time[self->state_trace_idx], NULL);
line = &self->state_trace_text[self->state_trace_idx++][0];
if (self->state_trace_idx >= STATE_TRACE)
self->state_trace_idx = 0;
#else
char line[CMDLEN];
#endif
char text[CMDLEN];
snprintf(line, CMDLEN, "Motor=%s, State=%s(%d), unhandled event=%s",
self->name,
state_name(self->myState),
self->subState,
event_name(event, text, CMDLEN));
SICSLogWrite(line, eError);
}
static void handle_event(pDMC2280Driv self, pEvtEvent event) {
StateFunc oldState;
#if defined(STATE_TRACE) && (STATE_TRACE > 0)
#else
if (self->debug || self->trace)
#endif
report_event(self, event);
oldState = self->myState;
self->myState(self, event);
}
static int state_snd_callback(pAsyncTxn pCmd) { static int state_snd_callback(pAsyncTxn pCmd) {
pDMC2280Driv self = (pDMC2280Driv) pCmd->cntx; pDMC2280Driv self = (pDMC2280Driv) pCmd->cntx;
SendCallback(pCmd); SendCallback(pCmd);
#if defined(STATE_TRACE) && (STATE_TRACE > 0) #if defined(STATE_TRACE) && (STATE_TRACE > 0)
char* line; if (true)
char text[CMDLEN];
gettimeofday(&self->state_trace_time[self->state_trace_idx], NULL);
line = &self->state_trace_text[self->state_trace_idx++][0];
if (self->state_trace_idx >= STATE_TRACE)
self->state_trace_idx = 0;
#else #else
char line[CMDLEN]; if (self->debug || self->trace)
char text[CMDLEN];
#endif #endif
{
char text[CMDLEN];
text[0] = '\0'; text[0] = '\0';
str_n_cat(text, CMDLEN, pCmd->out_buf); str_n_cat(text, CMDLEN, pCmd->out_buf);
str_n_cat(text, CMDLEN, "|"); str_n_cat(text, CMDLEN, "|");
str_n_cat(text, CMDLEN, pCmd->inp_buf); str_n_cat(text, CMDLEN, pCmd->inp_buf);
snprintf(line, CMDLEN, "Motor=%s, State=%s(%d), send complete=%s", state_trace_ins(self, "Send Complete=%s",
self->name,
state_name(self->myState),
self->subState,
text); text);
if (self->debug)
SICSLogWrite(line, eStatus);
if (self->trace)
SCWrite(self->trace, line, eStatus);
return 0; return 0;
} }
}
static int state_msg_callback(pAsyncTxn pCmd) { static int state_msg_callback(pAsyncTxn pCmd) {
pDMC2280Driv self = (pDMC2280Driv) pCmd->cntx; pDMC2280Driv self = (pDMC2280Driv) pCmd->cntx;
@ -2760,6 +2810,7 @@ static void DMCState_MotorStop(pDMC2280Driv self, pEvtEvent event) {
static void DMCState_Error(pDMC2280Driv self, pEvtEvent event) { static void DMCState_Error(pDMC2280Driv self, pEvtEvent event) {
switch (event->event_type) { switch (event->event_type) {
case eStateEvent: case eStateEvent:
if (self->myPrevState != self->myState)
state_trace_prn(self); state_trace_prn(self);
return; return;
case eTimerEvent: case eTimerEvent: