FRONTPANEL: sim_frontpanel API release 7

- Add explicit support for referencing register array elements.
- Reworked the parsing of the grouped output sets for explicitly queried
   registers and the auto repeat output sets.
- Fix race conditions in the various RUN, START, BOOT, and CONT commands.
- Fix incorrect RUN/HALT state after STEP commands
- Tolerate input TCP traffic that has been legitimately coalesced into
   different
This commit is contained in:
Mark Pizzolato 2017-12-09 01:25:34 -08:00
parent 0e4ee6ecce
commit b4c3fa1656
3 changed files with 208 additions and 164 deletions

View file

@ -62,6 +62,7 @@ unsigned int PCQ[32];
int PSL_bits[32]; int PSL_bits[32];
int PC_bits[32]; int PC_bits[32];
int PC_indirect_bits[32]; int PC_indirect_bits[32];
int PCQ_3_bits[32];
int update_display = 1; int update_display = 1;
@ -422,7 +423,7 @@ if (sim_panel_set_sampling_parameters_ex (panel, 500, 10, 100)) {
goto Done; goto Done;
} }
if (sim_panel_add_register_indirect_bits (panel, "PC", NULL, 32, PC_indirect_bits)) { if (sim_panel_add_register_indirect_bits (panel, "PC", NULL, 32, PC_indirect_bits)) {
printf ("Error adding register 'PSL' bits: %s\n", sim_panel_get_error()); printf ("Error adding register 'PC' indirect bits: %s\n", sim_panel_get_error());
goto Done; goto Done;
} }
if (sim_panel_add_register_bits (panel, "PSL", NULL, 32, PSL_bits)) { if (sim_panel_add_register_bits (panel, "PSL", NULL, 32, PSL_bits)) {
@ -433,6 +434,10 @@ if (sim_panel_add_register_bits (panel, "PC", NULL, 32, PC_bits)) {
printf ("Error adding register 'PSL' bits: %s\n", sim_panel_get_error()); printf ("Error adding register 'PSL' bits: %s\n", sim_panel_get_error());
goto Done; goto Done;
} }
if (sim_panel_add_register_bits (panel, "PCQ[3]", NULL, 32, PCQ_3_bits)) {
printf ("Error adding register 'PCQ[3]' bits: %s\n", sim_panel_get_error());
goto Done;
}
if (1) { if (1) {
unsigned int noop_noop_noop_halt = 0x00010101, addr400 = 0x00000400, pc_value; unsigned int noop_noop_noop_halt = 0x00010101, addr400 = 0x00000400, pc_value;
int mstime = 0; int mstime = 0;
@ -464,7 +469,24 @@ if (1) {
goto Done; goto Done;
} }
if (pc_value != addr400 + 4) { if (pc_value != addr400 + 4) {
printf ("Unexpected error getting PC value: %08X, expected: %08X\n", pc_value, addr400 + 4); printf ("Unexpected PC value after HALT: %08X, expected: %08X\n", pc_value, addr400 + 4);
goto Done;
}
if (sim_panel_gen_deposit (panel, "PC", sizeof(addr400), &addr400)) {
printf ("Error setting PC to %08X: %s\n", addr400, sim_panel_get_error());
goto Done;
}
if (sim_panel_exec_step (panel)) {
printf ("Error executing a single step: %s\n", sim_panel_get_error());
goto Done;
}
pc_value = 0;
if (sim_panel_gen_examine (panel, "PC", sizeof(pc_value), &pc_value)) {
printf ("Unexpected error getting PC value: %s\n", sim_panel_get_error());
goto Done;
}
if (pc_value != addr400 + 1) {
printf ("Unexpected PC value after STEP: %08X, expected: %08X\n", pc_value, addr400 + 1);
goto Done; goto Done;
} }
} }

View file

@ -217,8 +217,10 @@ static const char *register_collect_mid1 = " samples every ";
static const char *register_collect_mid2 = " cycles dither "; static const char *register_collect_mid2 = " cycles dither ";
static const char *register_collect_mid3 = " percent "; static const char *register_collect_mid3 = " percent ";
static const char *register_get_postfix = "sampleout"; static const char *register_get_postfix = "sampleout";
static const char *register_get_echo = "# REGISTERS-DONE"; static const char *register_get_start = "# REGISTERS-START";
static const char *register_repeat_echo = "# REGISTERS-REPEAT-DONE"; static const char *register_get_end = "# REGISTERS-DONE";
static const char *register_repeat_start = "# REGISTERS-REPEAT-START\r";
static const char *register_repeat_end = "# REGISTERS-REPEAT-DONE";
static const char *register_dev_echo = "# REGISTERS-FOR-DEVICE:"; static const char *register_dev_echo = "# REGISTERS-FOR-DEVICE:";
static const char *register_ind_echo = "# REGISTER-INDIRECT:"; static const char *register_ind_echo = "# REGISTER-INDIRECT:";
static const char *command_status = "ECHO Status:%STATUS%-%TSTATUS%"; static const char *command_status = "ECHO Status:%STATUS%-%TSTATUS%";
@ -451,7 +453,9 @@ size_t i, j, buf_data, buf_needed = 0, reg_count = 0, bit_reg_count = 0;
const char *dev; const char *dev;
pthread_mutex_lock (&panel->io_lock); pthread_mutex_lock (&panel->io_lock);
buf_needed = 2 + strlen (register_get_prefix); /* SHOW TIME */ buf_needed = 3 +
strlen (register_get_start) + /* # REGISTERS-START */
strlen (register_get_prefix); /* SHOW TIME */
for (i=0; i<panel->reg_count; i++) { for (i=0; i<panel->reg_count; i++) {
if (panel->regs[i].bits) if (panel->regs[i].bits)
++bit_reg_count; ++bit_reg_count;
@ -466,7 +470,7 @@ for (i=0; i<panel->reg_count; i++) {
} }
if (bit_reg_count) if (bit_reg_count)
buf_needed += 2 + strlen (register_get_postfix); buf_needed += 2 + strlen (register_get_postfix);
buf_needed += 10 + strlen (register_get_echo); /* # REGISTERS-DONE */ buf_needed += 10 + strlen (register_get_end); /* # REGISTERS-DONE */
if (buf_needed > *buf_size) { if (buf_needed > *buf_size) {
free (*buf); free (*buf);
*buf = (char *)_panel_malloc (buf_needed); *buf = (char *)_panel_malloc (buf_needed);
@ -479,7 +483,7 @@ if (buf_needed > *buf_size) {
} }
buf_data = 0; buf_data = 0;
if (reg_count) { if (reg_count) {
sprintf (*buf + buf_data, "%s\r", register_get_prefix); sprintf (*buf + buf_data, "%s\r%s\r", register_get_start, register_get_prefix);
buf_data += strlen (*buf + buf_data); buf_data += strlen (*buf + buf_data);
} }
dev = ""; dev = "";
@ -540,7 +544,7 @@ if (bit_reg_count) {
strcpy (*buf + buf_data, "\r"); strcpy (*buf + buf_data, "\r");
buf_data += strlen (*buf + buf_data); buf_data += strlen (*buf + buf_data);
} }
strcpy (*buf + buf_data, register_get_echo); strcpy (*buf + buf_data, register_get_end);
buf_data += strlen (*buf + buf_data); buf_data += strlen (*buf + buf_data);
strcpy (*buf + buf_data, "\r"); strcpy (*buf + buf_data, "\r");
buf_data += strlen (*buf + buf_data); buf_data += strlen (*buf + buf_data);
@ -1435,7 +1439,7 @@ if (_panel_sendf (panel, &cmd_stat, NULL, "SHOW TIME\r"))
panel->simulation_time_base += panel->simulation_time; panel->simulation_time_base += panel->simulation_time;
if (_panel_sendf (panel, NULL, NULL, "BOOT %s\r", device)) if (_panel_sendf (panel, NULL, NULL, "BOOT %s\r", device))
return -1; return -1;
panel->State = Run; msleep (100); /* Allow Run/Hslt state to settle */
return 0; return 0;
} }
@ -1464,7 +1468,7 @@ if (_panel_sendf (panel, &cmd_stat, NULL, "SHOW TIME\r"))
panel->simulation_time_base += panel->simulation_time; panel->simulation_time_base += panel->simulation_time;
if (_panel_sendf (panel, NULL, NULL, "RUN -Q\r", 5)) if (_panel_sendf (panel, NULL, NULL, "RUN -Q\r", 5))
return -1; return -1;
panel->State = Run; msleep (100); /* Allow Run/Hslt state to settle */
return 0; return 0;
} }
@ -1485,7 +1489,7 @@ if (panel->State == Run) {
} }
if (_panel_sendf (panel, NULL, NULL, "CONT\r", 5)) if (_panel_sendf (panel, NULL, NULL, "CONT\r", 5))
return -1; return -1;
panel->State = Run; msleep (100); /* Allow Run/Hslt state to settle */
return 0; return 0;
} }
@ -1507,7 +1511,6 @@ if (panel->State == Run) {
if (5 != _panel_send (panel, "STEP\r", 5)) if (5 != _panel_send (panel, "STEP\r", 5))
return -1; return -1;
panel->State = Run;
return 0; return 0;
} }
@ -1951,11 +1954,12 @@ static void *
_panel_reader(void *arg) _panel_reader(void *arg)
{ {
PANEL *p = (PANEL*)arg; PANEL *p = (PANEL*)arg;
REG *r; REG *r = NULL;
int sched_policy; int sched_policy;
struct sched_param sched_priority; struct sched_param sched_priority;
char buf[4096]; char buf[4096];
int buf_data = 0; int buf_data = 0;
int processing_register_output = 0;
/* /*
Boost Priority for this response processing thread to quickly digest Boost Priority for this response processing thread to quickly digest
@ -2020,183 +2024,194 @@ while ((p->sock != INVALID_SOCKET) &&
s = buf; s = buf;
while ((eol = strchr (s, '\n'))) { while ((eol = strchr (s, '\n'))) {
/* Line to process */ /* Line to process */
r = NULL;
*eol++ = '\0'; *eol++ = '\0';
while ((*s) && (s[strlen(s)-1] == '\r')) while ((*s) && (s[strlen(s)-1] == '\r'))
s[strlen(s)-1] = '\0'; s[strlen(s)-1] = '\0';
e = strchr (s, ':'); if (processing_register_output) {
if (e) { e = strchr (s, ':');
size_t i; if (e) {
char smp_dev[32], smp_reg[32], smp_ind[32]; size_t i;
unsigned int bit; char smp_dev[32], smp_reg[32], smp_ind[32];
unsigned int bit;
*e++ = '\0'; *e++ = '\0';
if (!strcmp("Time", s)) { if (!strcmp("Time", s)) {
p->simulation_time = strtoull (e, NULL, 10); p->simulation_time = strtoull (e, NULL, 10);
s = eol;
while (isspace(0xFF & (*s)))
++s;
continue; /* process next line */
}
if ((*s == '}') &&
(3 == sscanf (s, "}%s %s %s", smp_dev, smp_reg, smp_ind))) { /* Register bit Sample Data? */
r = NULL;
for (i=0; i<p->reg_count; i++) {
if (p->regs[i].bits == NULL)
continue;
if ((!strcmp (smp_reg, p->regs[i].name)) &&
((!p->device_name) || (!strcmp (smp_dev, p->device_name)))) {
r = &p->regs[i];
break;
}
}
if (r) {
for (bit = 0; bit < r->bit_count; bit++) {
int val = (int)strtol (e, &e, 10);
r->bits[bit] = val;
if (*e == ',')
++e;
else
break;
}
s = eol; s = eol;
while (isspace(0xFF & (*s)))
++s;
continue; /* process next line */
} }
while (isspace(0xFF & (*s))) if ((*s == '}') &&
++s; (3 == sscanf (s, "}%s %s %s", smp_dev, smp_reg, smp_ind))) { /* Register bit Sample Data? */
r = NULL; r = NULL;
continue; /* process next line */ for (i=0; i<p->reg_count; i++) {
} if (p->regs[i].bits == NULL)
if (!strncmp (s + strlen (sim_prompt), register_ind_echo, strlen (register_ind_echo) - 1)) { continue;
e = s + strlen (sim_prompt) + strlen (register_ind_echo); if ((!strcmp (smp_reg, p->regs[i].name)) &&
r = NULL; ((!p->device_name) || (!strcmp (smp_dev, p->device_name)))) {
for (i=0; i<p->reg_count; i++) { r = &p->regs[i];
if (p->regs[i].indirect && (!strcmp(p->regs[i].name, e))) { break;
r = &p->regs[i]; }
break;
} }
if (r) {
for (bit = 0; bit < r->bit_count; bit++) {
int val = (int)strtol (e, &e, 10);
r->bits[bit] = val;
if (*e == ',')
++e;
else
break;
}
s = eol;
}
while (isspace(0xFF & (*s)))
++s;
r = NULL;
continue; /* process next line */
} }
s = eol; if (!strncmp (s + strlen (sim_prompt), register_ind_echo, strlen (register_ind_echo) - 1)) {
while (isspace(0xFF & (*s))) e = s + strlen (sim_prompt) + strlen (register_ind_echo);
++s; r = NULL;
if (r) for (i=0; i<p->reg_count; i++) {
continue; /* process next line */ if (p->regs[i].indirect && (!strcmp(p->regs[i].name, e))) {
} r = &p->regs[i];
if (!p->io_waiting) { break;
if (r) { }
if (strcmp (s, r->name)) {
unsigned long long data;
data = strtoull (e, NULL, 16);
if (little_endian)
memcpy (r->addr, &data, r->size);
else
memcpy (r->addr, ((char *)&data) + sizeof(data)-r->size, r->size);
r = NULL;
} }
s = eol; s = eol;
while (isspace(0xFF & (*s))) while (isspace(0xFF & (*s)))
++s; ++s;
continue; /* process next line */ if (r)
continue; /* process next line */
} }
for (i=0; i<p->reg_count; i++) { if (!p->io_waiting) {
if (p->regs[i].element_count == 0) { if (r) {
if (!strcmp(p->regs[i].name, s)) { if (strcmp (s, r->name)) {
unsigned long long data; unsigned long long data;
data = strtoull (e, NULL, 16); data = strtoull (e, NULL, 16);
if (little_endian) if (little_endian)
memcpy (p->regs[i].addr, &data, p->regs[i].size); memcpy (r->addr, &data, r->size);
else else
memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size); memcpy (r->addr, ((char *)&data) + sizeof(data)-r->size, r->size);
break; r = NULL;
} }
s = eol;
while (isspace(0xFF & (*s)))
++s;
continue; /* process next line */
} }
else { for (i=0; i<p->reg_count; i++) {
size_t name_len = strlen (p->regs[i].name); if (p->regs[i].element_count == 0) {
if (!strcmp(p->regs[i].name, s)) {
unsigned long long data;
if ((0 == memcmp (p->regs[i].name, s, name_len)) && (s[name_len] == '[')) { data = strtoull (e, NULL, 16);
size_t array_index = (size_t)atoi (s + name_len + 1);
size_t end_index = array_index;
char *end = strchr (s + name_len + 1, '[');
if (end)
end_index = (size_t)atoi (end + 1);
if (strcmp (e, " same as above"))
p->array_element_data = strtoull (e, NULL, 16);
while (array_index <= end_index) {
if (little_endian) if (little_endian)
memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), &p->array_element_data, p->regs[i].size); memcpy (p->regs[i].addr, &data, p->regs[i].size);
else else
memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), ((char *)&p->array_element_data) + sizeof(p->array_element_data)-p->regs[i].size, p->regs[i].size); memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size);
++array_index; break;
}
}
else {
size_t name_len = strlen (p->regs[i].name);
if ((0 == memcmp (p->regs[i].name, s, name_len)) && (s[name_len] == '[')) {
size_t array_index = (size_t)atoi (s + name_len + 1);
size_t end_index = array_index;
char *end = strchr (s + name_len + 1, '[');
if (end)
end_index = (size_t)atoi (end + 1);
if (strcmp (e, " same as above"))
p->array_element_data = strtoull (e, NULL, 16);
while (array_index <= end_index) {
if (little_endian)
memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), &p->array_element_data, p->regs[i].size);
else
memcpy ((char *)(p->regs[i].addr) + (array_index * p->regs[i].size), ((char *)&p->array_element_data) + sizeof(p->array_element_data)-p->regs[i].size, p->regs[i].size);
++array_index;
}
break;
} }
break;
} }
} }
if (i != p->reg_count) {
s = eol;
while (isspace(0xFF & (*s)))
++s;
continue;
}
} }
if (i != p->reg_count) { --e;
s = eol; *e = ':';
while (isspace(0xFF & (*s))) /* Unexpected Register Data Found (or other output containing a : character) */
++s;
continue;
}
} }
--e;
*e = ':';
/* Unexpected Register Data Found (or other output containing a : character) */
} }
if (!strcmp (s + strlen (sim_prompt), register_repeat_echo)) { if (!strcmp (s + strlen (sim_prompt), register_repeat_end)) {
_panel_debug (p, DBG_RCV, "*Repeat Block Complete", NULL, 0);
if (p->callback) { if (p->callback) {
pthread_mutex_unlock (&p->io_lock); pthread_mutex_unlock (&p->io_lock);
p->callback (p, p->simulation_time_base + p->simulation_time, p->callback_context); p->callback (p, p->simulation_time_base + p->simulation_time, p->callback_context);
pthread_mutex_lock (&p->io_lock); pthread_mutex_lock (&p->io_lock);
} }
processing_register_output = 0;
goto Start_Next_Line;
} }
if (!strcmp (s + strlen (sim_prompt), register_get_echo)) { if ((!strcmp (s + strlen (sim_prompt), register_repeat_start)) ||
(!strcmp (s + strlen (sim_prompt), register_get_start))) {
_panel_debug (p, DBG_RCV, "*Repeat/Register Block Starting", NULL, 0);
processing_register_output = 1;
goto Start_Next_Line;
}
if (!strcmp (s + strlen (sim_prompt), register_get_end)) {
_panel_debug (p, DBG_RCV, "*Register Block Complete", NULL, 0);
--p->io_reg_query_pending; --p->io_reg_query_pending;
p->io_waiting = 0; p->io_waiting = 0;
pthread_cond_signal (&p->io_done); pthread_cond_signal (&p->io_done);
goto Start_Next_Line;
} }
else { if (!strcmp (s + strlen (sim_prompt), command_done_echo)) {
if (!strcmp (s + strlen (sim_prompt), command_done_echo)) { _panel_debug (p, DBG_RCV, "*Received Command Complete", NULL, 0);
_panel_debug (p, DBG_RCV, "Received Command Complete", NULL, 0); p->io_waiting = 0;
p->io_waiting = 0; pthread_cond_signal (&p->io_done);
pthread_cond_signal (&p->io_done); goto Start_Next_Line;
} }
else { /* Non Register Data Found (echo of EXAMINE or other commands and/or command output) */
/* Non Register Data Found (echo of EXAMINE or other commands and/or command output) */ if (p->io_waiting) {
if (p->io_waiting) { char *t;
char *t;
if (p->io_response_data + strlen (s) + 3 > p->io_response_size) { if (p->io_response_data + strlen (s) + 3 > p->io_response_size) {
t = (char *)_panel_malloc (p->io_response_data + strlen (s) + 3); t = (char *)_panel_malloc (p->io_response_data + strlen (s) + 3);
if (t == NULL) { if (t == NULL) {
_panel_debug (p, DBG_RCV, "%s", NULL, 0, sim_panel_get_error()); _panel_debug (p, DBG_RCV, "%s", NULL, 0, sim_panel_get_error());
p->State = Error; p->State = Error;
break; break;
}
memcpy (t, p->io_response, p->io_response_data);
free (p->io_response);
p->io_response = t;
p->io_response_size = p->io_response_data + strlen (s) + 3;
}
_panel_debug (p, DBG_RCV, "Receive Data Accumulated: '%s'", NULL, 0, s);
strcpy (p->io_response + p->io_response_data, s);
p->io_response_data += strlen(s);
strcpy (p->io_response + p->io_response_data, "\r\n");
p->io_response_data += 2;
} }
else memcpy (t, p->io_response, p->io_response_data);
_panel_debug (p, DBG_RCV, "Receive Data Discarded: '%s'", NULL, 0, s); free (p->io_response);
p->io_response = t;
p->io_response_size = p->io_response_data + strlen (s) + 3;
} }
_panel_debug (p, DBG_RCV, "Receive Data Accumulated: '%s'", NULL, 0, s);
strcpy (p->io_response + p->io_response_data, s);
p->io_response_data += strlen(s);
strcpy (p->io_response + p->io_response_data, "\r\n");
p->io_response_data += 2;
} }
else
_panel_debug (p, DBG_RCV, "Receive Data Discarded: '%s'", NULL, 0, s);
Start_Next_Line:
s = eol; s = eol;
while (isspace(0xFF & (*s))) while (isspace(0xFF & (*s)))
++s; ++s;
} }
memmove (buf, s, strlen (s)+1); memmove (buf, s, strlen (s)+1);
buf_data = strlen (buf); buf_data = strlen (buf);
_panel_debug (p, DBG_RSP, "Remnant Buffer Contents: '%s'", NULL, 0, buf); if (buf_data)
_panel_debug (p, DBG_RSP, "Remnant Buffer Contents: '%s'", NULL, 0, buf);
if (!memcmp ("Simulator Running...", buf, 20)) { if (!memcmp ("Simulator Running...", buf, 20)) {
_panel_debug (p, DBG_RSP, "State transitioning to Run", NULL, 0); _panel_debug (p, DBG_RSP, "State transitioning to Run", NULL, 0);
p->State = Run; p->State = Run;
@ -2280,22 +2295,25 @@ while ((p->sock != INVALID_SOCKET) &&
strlen (register_repeat_units) + /* units and spacing */ strlen (register_repeat_units) + /* units and spacing */
buf_data + /* command contents */ buf_data + /* command contents */
1 + /* carriage return */ 1 + /* carriage return */
strlen (register_repeat_echo) + /* auto repeat completion */ strlen (register_repeat_start) + /* auto repeat begin */
1 + /* carriage return */
strlen (register_repeat_end) + /* auto repeat completion */
1 + /* carriage return */ 1 + /* carriage return */
1; /* NUL */ 1; /* NUL */
char *repeat = (char *)malloc (repeat_data); char *repeat = (char *)malloc (repeat_data);
char *c; char *c;
sprintf (repeat, "%s%d%s%*.*s", register_repeat_prefix, sprintf (repeat, "%s%d%s%s%*.*s", register_repeat_prefix,
p->usecs_between_callbacks, p->usecs_between_callbacks,
register_repeat_units, register_repeat_units,
register_repeat_start,
(int)buf_data, (int)buf_data, buf); (int)buf_data, (int)buf_data, buf);
pthread_mutex_unlock (&p->io_lock); pthread_mutex_unlock (&p->io_lock);
for (c = strchr (repeat, '\r'); c != NULL; c = strchr (c, '\r')) for (c = strchr (repeat, '\r'); c != NULL; c = strchr (c, '\r'))
*c = ';'; /* replace carriage returns with semicolons */ *c = ';'; /* replace carriage returns with semicolons */
c = strstr (repeat, register_get_echo); /* remove register_done_echo string and */ c = strstr (repeat, register_get_end); /* remove register_done_echo string and */
if (c) /* always true */ if (c) /* always true */
strcpy (c, register_repeat_echo); /* replace it with the register_repeat_echo string */ strcpy (c, register_repeat_end); /* replace it with the register_repeat_end string */
if (_panel_sendf (p, &cmd_stat, NULL, "%s", repeat)) { if (_panel_sendf (p, &cmd_stat, NULL, "%s", repeat)) {
pthread_mutex_lock (&p->io_lock); pthread_mutex_lock (&p->io_lock);
free (repeat); free (repeat);
@ -2450,32 +2468,36 @@ ret = ((len + status_echo_len) == (sent_len = _panel_send (p, buf, len + status_
if (completion_status) { if (completion_status) {
if (!ret) { /* Sent OK? */ if (!ret) { /* Sent OK? */
char *tresponse = NULL;
p->io_waiting = 1; p->io_waiting = 1;
while (p->io_waiting) while (p->io_waiting)
pthread_cond_wait (&p->io_done, &p->io_lock); /* Wait for completion */ pthread_cond_wait (&p->io_done, &p->io_lock); /* Wait for completion */
if (response) { tresponse = (char *)_panel_malloc (p->io_response_data + 1);
*response = (char *)_panel_malloc (p->io_response_data + 1); if (0 == memcmp (buf, p->io_response + strlen (sim_prompt), len)) {
if (0 == memcmp (buf, p->io_response + strlen (sim_prompt), len)) { char *eol, *status;
char *eol, *status; memcpy (tresponse, p->io_response + strlen (sim_prompt) + len + 1, p->io_response_data + 1 - (strlen (sim_prompt) + len + 1));
memcpy (*response, p->io_response + strlen (sim_prompt) + len + 1, p->io_response_data + 1 - (strlen (sim_prompt) + len + 1)); *completion_status = -1;
*completion_status = -1; status = strstr (tresponse, command_status);
status = strstr (*response, command_status); if (status) {
if (status) { *(status - strlen (sim_prompt)) = '\0';
*(status - strlen (sim_prompt)) = '\0'; status += strlen (command_status) + 2;
status += strlen (command_status) + 2; eol = strchr (status, '\r');
eol = strchr (status, '\r'); if (eol)
if (eol) *eol = '\0';
*eol = '\0'; sscanf (status, "Status:%08X-", completion_status);
sscanf (status, "Status:%08X-", completion_status);
}
} }
else }
memcpy (*response, p->io_response, p->io_response_data + 1); else
memcpy (tresponse, p->io_response, p->io_response_data + 1);
if (response) {
*response = tresponse;
_panel_debug (p, DBG_RSP, "Command %d Response(Status=%d): '%s'", NULL, 0, p->command_count, *completion_status, *response); _panel_debug (p, DBG_RSP, "Command %d Response(Status=%d): '%s'", NULL, 0, p->command_count, *completion_status, *response);
} }
else { else {
free (tresponse);
if (p->io_response_data) if (p->io_response_data)
_panel_debug (p, DBG_RSP, "Discarded Unwanted Command %d Response Data:", p->io_response, p->io_response_data, p->command_count); _panel_debug (p, DBG_RSP, "Discarded Unwanted Command %d Response Data(Status=%d):", p->io_response, p->io_response_data, p->command_count, *completion_status);
} }
} }
p->io_response_data = 0; p->io_response_data = 0;

View file

@ -56,7 +56,7 @@ extern "C" {
#if !defined(__VAX) /* Unsupported platform */ #if !defined(__VAX) /* Unsupported platform */
#define SIM_FRONTPANEL_VERSION 6 #define SIM_FRONTPANEL_VERSION 7
/** /**