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:
@ -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:
|
||||||
|
Reference in New Issue
Block a user