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:
parent
0e4ee6ecce
commit
b4c3fa1656
3 changed files with 208 additions and 164 deletions
|
@ -62,6 +62,7 @@ unsigned int PCQ[32];
|
|||
int PSL_bits[32];
|
||||
int PC_bits[32];
|
||||
int PC_indirect_bits[32];
|
||||
int PCQ_3_bits[32];
|
||||
|
||||
int update_display = 1;
|
||||
|
||||
|
@ -422,7 +423,7 @@ if (sim_panel_set_sampling_parameters_ex (panel, 500, 10, 100)) {
|
|||
goto Done;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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());
|
||||
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) {
|
||||
unsigned int noop_noop_noop_halt = 0x00010101, addr400 = 0x00000400, pc_value;
|
||||
int mstime = 0;
|
||||
|
@ -464,7 +469,24 @@ if (1) {
|
|||
goto Done;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
344
sim_frontpanel.c
344
sim_frontpanel.c
|
@ -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_mid3 = " percent ";
|
||||
static const char *register_get_postfix = "sampleout";
|
||||
static const char *register_get_echo = "# REGISTERS-DONE";
|
||||
static const char *register_repeat_echo = "# REGISTERS-REPEAT-DONE";
|
||||
static const char *register_get_start = "# REGISTERS-START";
|
||||
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_ind_echo = "# REGISTER-INDIRECT:";
|
||||
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;
|
||||
|
||||
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++) {
|
||||
if (panel->regs[i].bits)
|
||||
++bit_reg_count;
|
||||
|
@ -466,7 +470,7 @@ for (i=0; i<panel->reg_count; i++) {
|
|||
}
|
||||
if (bit_reg_count)
|
||||
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) {
|
||||
free (*buf);
|
||||
*buf = (char *)_panel_malloc (buf_needed);
|
||||
|
@ -479,7 +483,7 @@ if (buf_needed > *buf_size) {
|
|||
}
|
||||
buf_data = 0;
|
||||
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);
|
||||
}
|
||||
dev = "";
|
||||
|
@ -540,7 +544,7 @@ if (bit_reg_count) {
|
|||
strcpy (*buf + buf_data, "\r");
|
||||
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);
|
||||
strcpy (*buf + buf_data, "\r");
|
||||
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;
|
||||
if (_panel_sendf (panel, NULL, NULL, "BOOT %s\r", device))
|
||||
return -1;
|
||||
panel->State = Run;
|
||||
msleep (100); /* Allow Run/Hslt state to settle */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1464,7 +1468,7 @@ if (_panel_sendf (panel, &cmd_stat, NULL, "SHOW TIME\r"))
|
|||
panel->simulation_time_base += panel->simulation_time;
|
||||
if (_panel_sendf (panel, NULL, NULL, "RUN -Q\r", 5))
|
||||
return -1;
|
||||
panel->State = Run;
|
||||
msleep (100); /* Allow Run/Hslt state to settle */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1485,7 +1489,7 @@ if (panel->State == Run) {
|
|||
}
|
||||
if (_panel_sendf (panel, NULL, NULL, "CONT\r", 5))
|
||||
return -1;
|
||||
panel->State = Run;
|
||||
msleep (100); /* Allow Run/Hslt state to settle */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1507,7 +1511,6 @@ if (panel->State == Run) {
|
|||
|
||||
if (5 != _panel_send (panel, "STEP\r", 5))
|
||||
return -1;
|
||||
panel->State = Run;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1951,11 +1954,12 @@ static void *
|
|||
_panel_reader(void *arg)
|
||||
{
|
||||
PANEL *p = (PANEL*)arg;
|
||||
REG *r;
|
||||
REG *r = NULL;
|
||||
int sched_policy;
|
||||
struct sched_param sched_priority;
|
||||
char buf[4096];
|
||||
int buf_data = 0;
|
||||
int processing_register_output = 0;
|
||||
|
||||
/*
|
||||
Boost Priority for this response processing thread to quickly digest
|
||||
|
@ -2020,183 +2024,194 @@ while ((p->sock != INVALID_SOCKET) &&
|
|||
s = buf;
|
||||
while ((eol = strchr (s, '\n'))) {
|
||||
/* Line to process */
|
||||
r = NULL;
|
||||
*eol++ = '\0';
|
||||
while ((*s) && (s[strlen(s)-1] == '\r'))
|
||||
s[strlen(s)-1] = '\0';
|
||||
e = strchr (s, ':');
|
||||
if (e) {
|
||||
size_t i;
|
||||
char smp_dev[32], smp_reg[32], smp_ind[32];
|
||||
unsigned int bit;
|
||||
if (processing_register_output) {
|
||||
e = strchr (s, ':');
|
||||
if (e) {
|
||||
size_t i;
|
||||
char smp_dev[32], smp_reg[32], smp_ind[32];
|
||||
unsigned int bit;
|
||||
|
||||
*e++ = '\0';
|
||||
if (!strcmp("Time", s)) {
|
||||
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;
|
||||
}
|
||||
*e++ = '\0';
|
||||
if (!strcmp("Time", s)) {
|
||||
p->simulation_time = strtoull (e, NULL, 10);
|
||||
s = eol;
|
||||
while (isspace(0xFF & (*s)))
|
||||
++s;
|
||||
continue; /* process next line */
|
||||
}
|
||||
while (isspace(0xFF & (*s)))
|
||||
++s;
|
||||
r = NULL;
|
||||
continue; /* process next line */
|
||||
}
|
||||
if (!strncmp (s + strlen (sim_prompt), register_ind_echo, strlen (register_ind_echo) - 1)) {
|
||||
e = s + strlen (sim_prompt) + strlen (register_ind_echo);
|
||||
r = NULL;
|
||||
for (i=0; i<p->reg_count; i++) {
|
||||
if (p->regs[i].indirect && (!strcmp(p->regs[i].name, e))) {
|
||||
r = &p->regs[i];
|
||||
break;
|
||||
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;
|
||||
}
|
||||
while (isspace(0xFF & (*s)))
|
||||
++s;
|
||||
r = NULL;
|
||||
continue; /* process next line */
|
||||
}
|
||||
s = eol;
|
||||
while (isspace(0xFF & (*s)))
|
||||
++s;
|
||||
if (r)
|
||||
continue; /* process next line */
|
||||
}
|
||||
if (!p->io_waiting) {
|
||||
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;
|
||||
if (!strncmp (s + strlen (sim_prompt), register_ind_echo, strlen (register_ind_echo) - 1)) {
|
||||
e = s + strlen (sim_prompt) + strlen (register_ind_echo);
|
||||
r = NULL;
|
||||
for (i=0; i<p->reg_count; i++) {
|
||||
if (p->regs[i].indirect && (!strcmp(p->regs[i].name, e))) {
|
||||
r = &p->regs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
s = eol;
|
||||
while (isspace(0xFF & (*s)))
|
||||
++s;
|
||||
continue; /* process next line */
|
||||
if (r)
|
||||
continue; /* process next line */
|
||||
}
|
||||
for (i=0; i<p->reg_count; i++) {
|
||||
if (p->regs[i].element_count == 0) {
|
||||
if (!strcmp(p->regs[i].name, s)) {
|
||||
if (!p->io_waiting) {
|
||||
if (r) {
|
||||
if (strcmp (s, r->name)) {
|
||||
unsigned long long data;
|
||||
|
||||
data = strtoull (e, NULL, 16);
|
||||
if (little_endian)
|
||||
memcpy (p->regs[i].addr, &data, p->regs[i].size);
|
||||
memcpy (r->addr, &data, r->size);
|
||||
else
|
||||
memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size);
|
||||
break;
|
||||
memcpy (r->addr, ((char *)&data) + sizeof(data)-r->size, r->size);
|
||||
r = NULL;
|
||||
}
|
||||
s = eol;
|
||||
while (isspace(0xFF & (*s)))
|
||||
++s;
|
||||
continue; /* process next line */
|
||||
}
|
||||
else {
|
||||
size_t name_len = strlen (p->regs[i].name);
|
||||
for (i=0; i<p->reg_count; i++) {
|
||||
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] == '[')) {
|
||||
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) {
|
||||
data = strtoull (e, NULL, 16);
|
||||
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
|
||||
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;
|
||||
memcpy (p->regs[i].addr, ((char *)&data) + sizeof(data)-p->regs[i].size, p->regs[i].size);
|
||||
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) {
|
||||
s = eol;
|
||||
while (isspace(0xFF & (*s)))
|
||||
++s;
|
||||
continue;
|
||||
}
|
||||
--e;
|
||||
*e = ':';
|
||||
/* Unexpected Register Data Found (or other output containing a : character) */
|
||||
}
|
||||
--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) {
|
||||
pthread_mutex_unlock (&p->io_lock);
|
||||
p->callback (p, p->simulation_time_base + p->simulation_time, p->callback_context);
|
||||
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_waiting = 0;
|
||||
pthread_cond_signal (&p->io_done);
|
||||
goto Start_Next_Line;
|
||||
}
|
||||
else {
|
||||
if (!strcmp (s + strlen (sim_prompt), command_done_echo)) {
|
||||
_panel_debug (p, DBG_RCV, "Received Command Complete", NULL, 0);
|
||||
p->io_waiting = 0;
|
||||
pthread_cond_signal (&p->io_done);
|
||||
}
|
||||
else {
|
||||
/* Non Register Data Found (echo of EXAMINE or other commands and/or command output) */
|
||||
if (p->io_waiting) {
|
||||
char *t;
|
||||
if (!strcmp (s + strlen (sim_prompt), command_done_echo)) {
|
||||
_panel_debug (p, DBG_RCV, "*Received Command Complete", NULL, 0);
|
||||
p->io_waiting = 0;
|
||||
pthread_cond_signal (&p->io_done);
|
||||
goto Start_Next_Line;
|
||||
}
|
||||
/* Non Register Data Found (echo of EXAMINE or other commands and/or command output) */
|
||||
if (p->io_waiting) {
|
||||
char *t;
|
||||
|
||||
if (p->io_response_data + strlen (s) + 3 > p->io_response_size) {
|
||||
t = (char *)_panel_malloc (p->io_response_data + strlen (s) + 3);
|
||||
if (t == NULL) {
|
||||
_panel_debug (p, DBG_RCV, "%s", NULL, 0, sim_panel_get_error());
|
||||
p->State = Error;
|
||||
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;
|
||||
if (p->io_response_data + strlen (s) + 3 > p->io_response_size) {
|
||||
t = (char *)_panel_malloc (p->io_response_data + strlen (s) + 3);
|
||||
if (t == NULL) {
|
||||
_panel_debug (p, DBG_RCV, "%s", NULL, 0, sim_panel_get_error());
|
||||
p->State = Error;
|
||||
break;
|
||||
}
|
||||
else
|
||||
_panel_debug (p, DBG_RCV, "Receive Data Discarded: '%s'", NULL, 0, s);
|
||||
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
|
||||
_panel_debug (p, DBG_RCV, "Receive Data Discarded: '%s'", NULL, 0, s);
|
||||
Start_Next_Line:
|
||||
s = eol;
|
||||
while (isspace(0xFF & (*s)))
|
||||
++s;
|
||||
}
|
||||
memmove (buf, s, strlen (s)+1);
|
||||
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)) {
|
||||
_panel_debug (p, DBG_RSP, "State transitioning to Run", NULL, 0);
|
||||
p->State = Run;
|
||||
|
@ -2280,22 +2295,25 @@ while ((p->sock != INVALID_SOCKET) &&
|
|||
strlen (register_repeat_units) + /* units and spacing */
|
||||
buf_data + /* command contents */
|
||||
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; /* NUL */
|
||||
char *repeat = (char *)malloc (repeat_data);
|
||||
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,
|
||||
register_repeat_units,
|
||||
register_repeat_start,
|
||||
(int)buf_data, (int)buf_data, buf);
|
||||
pthread_mutex_unlock (&p->io_lock);
|
||||
for (c = strchr (repeat, '\r'); c != NULL; c = strchr (c, '\r'))
|
||||
*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 */
|
||||
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)) {
|
||||
pthread_mutex_lock (&p->io_lock);
|
||||
free (repeat);
|
||||
|
@ -2450,32 +2468,36 @@ ret = ((len + status_echo_len) == (sent_len = _panel_send (p, buf, len + status_
|
|||
|
||||
if (completion_status) {
|
||||
if (!ret) { /* Sent OK? */
|
||||
char *tresponse = NULL;
|
||||
|
||||
p->io_waiting = 1;
|
||||
while (p->io_waiting)
|
||||
pthread_cond_wait (&p->io_done, &p->io_lock); /* Wait for completion */
|
||||
if (response) {
|
||||
*response = (char *)_panel_malloc (p->io_response_data + 1);
|
||||
if (0 == memcmp (buf, p->io_response + strlen (sim_prompt), len)) {
|
||||
char *eol, *status;
|
||||
memcpy (*response, p->io_response + strlen (sim_prompt) + len + 1, p->io_response_data + 1 - (strlen (sim_prompt) + len + 1));
|
||||
*completion_status = -1;
|
||||
status = strstr (*response, command_status);
|
||||
if (status) {
|
||||
*(status - strlen (sim_prompt)) = '\0';
|
||||
status += strlen (command_status) + 2;
|
||||
eol = strchr (status, '\r');
|
||||
if (eol)
|
||||
*eol = '\0';
|
||||
sscanf (status, "Status:%08X-", completion_status);
|
||||
}
|
||||
tresponse = (char *)_panel_malloc (p->io_response_data + 1);
|
||||
if (0 == memcmp (buf, p->io_response + strlen (sim_prompt), len)) {
|
||||
char *eol, *status;
|
||||
memcpy (tresponse, p->io_response + strlen (sim_prompt) + len + 1, p->io_response_data + 1 - (strlen (sim_prompt) + len + 1));
|
||||
*completion_status = -1;
|
||||
status = strstr (tresponse, command_status);
|
||||
if (status) {
|
||||
*(status - strlen (sim_prompt)) = '\0';
|
||||
status += strlen (command_status) + 2;
|
||||
eol = strchr (status, '\r');
|
||||
if (eol)
|
||||
*eol = '\0';
|
||||
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);
|
||||
}
|
||||
else {
|
||||
free (tresponse);
|
||||
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;
|
||||
|
|
|
@ -56,7 +56,7 @@ extern "C" {
|
|||
|
||||
#if !defined(__VAX) /* Unsupported platform */
|
||||
|
||||
#define SIM_FRONTPANEL_VERSION 6
|
||||
#define SIM_FRONTPANEL_VERSION 7
|
||||
|
||||
/**
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue