FRONTPANEL: sim_frontpanel API release 10
- Reworked STEP, HALT, BOOT, and RUN API's to properly interlock with the receive thread. - Shorten destroy delay while debugging to 1 second. - Allow execution and text breakpoints to be set and/or cleared while simulator is running.
This commit is contained in:
parent
634a92f8bf
commit
2de2b9bd80
3 changed files with 152 additions and 91 deletions
|
@ -438,11 +438,11 @@ if (sim_panel_add_register_bits (panel, "PCQ[3]", NULL, 32, PCQ_3_bits)) {
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
if (1) {
|
if (1) {
|
||||||
unsigned int noop_noop_noop_halt = 0x00010101, addr400 = 0x00000400, pc_value;
|
unsigned int noop_noop_noop_halt = 0x00010101, brb_self = 0x0000FE11, addr400 = 0x00000400, pc_value;
|
||||||
int mstime = 0;
|
int mstime = 0;
|
||||||
|
|
||||||
if (sim_panel_mem_deposit (panel, sizeof(addr400), &addr400, sizeof(noop_noop_noop_halt), &noop_noop_noop_halt)) {
|
if (sim_panel_mem_deposit (panel, sizeof(addr400), &addr400, sizeof(noop_noop_noop_halt), &noop_noop_noop_halt)) {
|
||||||
printf ("Error setting 00000000 to %08X: %s\n", noop_noop_noop_halt, sim_panel_get_error());
|
printf ("Error setting %08X to %08X: %s\n", addr400, noop_noop_noop_halt, sim_panel_get_error());
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
if (sim_panel_gen_deposit (panel, "PC", sizeof(addr400), &addr400)) {
|
if (sim_panel_gen_deposit (panel, "PC", sizeof(addr400), &addr400)) {
|
||||||
|
@ -488,6 +488,31 @@ if (1) {
|
||||||
printf ("Unexpected PC value after STEP: %08X, expected: %08X\n", pc_value, addr400 + 1);
|
printf ("Unexpected PC value after STEP: %08X, expected: %08X\n", pc_value, addr400 + 1);
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
if (sim_panel_mem_deposit (panel, sizeof(addr400), &addr400, sizeof(brb_self), &brb_self)) {
|
||||||
|
printf ("Error setting %08X to %08X: %s\n", addr400, brb_self, sim_panel_get_error());
|
||||||
|
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_run(panel)) {
|
||||||
|
printf ("Error starting simulator execution: %s\n", sim_panel_get_error());
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
while ((sim_panel_get_state (panel) == Run) &&
|
||||||
|
(mstime < 1000)) {
|
||||||
|
usleep (100000);
|
||||||
|
mstime += 100;
|
||||||
|
}
|
||||||
|
if (sim_panel_exec_halt (panel)) {
|
||||||
|
printf ("Error executing halt: %s\n", sim_panel_get_error());
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
if (sim_panel_get_state (panel) != Halt) {
|
||||||
|
printf ("State not Halt after successful Halt\n");
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -511,7 +536,7 @@ if (panel_setup())
|
||||||
if (1) {
|
if (1) {
|
||||||
struct {
|
struct {
|
||||||
unsigned int addr;
|
unsigned int addr;
|
||||||
char *instr;
|
const char *instr;
|
||||||
} long_running_program[] = {
|
} long_running_program[] = {
|
||||||
{0x2000, "MOVL #7FFFFFFF,R0"},
|
{0x2000, "MOVL #7FFFFFFF,R0"},
|
||||||
{0x2007, "MOVL #7FFFFFFF,R1"},
|
{0x2007, "MOVL #7FFFFFFF,R1"},
|
||||||
|
@ -522,7 +547,7 @@ if (1) {
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sim_panel_debug (panel, "Testing sim_panel_destroy() with simulator in Run State");
|
sim_panel_debug (panel, "Testing sim_panel_exec_halt and sim_panel_destroy() () with simulator in Run State");
|
||||||
for (i=0; long_running_program[i].instr; i++)
|
for (i=0; long_running_program[i].instr; i++)
|
||||||
if (sim_panel_mem_deposit_instruction (panel, sizeof(long_running_program[i].addr),
|
if (sim_panel_mem_deposit_instruction (panel, sizeof(long_running_program[i].addr),
|
||||||
&long_running_program[i].addr, long_running_program[i].instr)) {
|
&long_running_program[i].addr, long_running_program[i].instr)) {
|
||||||
|
@ -538,7 +563,18 @@ if (1) {
|
||||||
printf ("Error starting simulator execution: %s\n", sim_panel_get_error());
|
printf ("Error starting simulator execution: %s\n", sim_panel_get_error());
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
usleep (2000000); /* 2 Seconds */
|
usleep (100000); /* .1 seconds */
|
||||||
|
sim_panel_debug (panel, "Testing sim_panel_exec_halt");
|
||||||
|
if (sim_panel_exec_halt (panel)) {
|
||||||
|
printf ("Error halting simulator execution: %s\n", sim_panel_get_error());
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
sim_panel_debug (panel, "Testing sim_panel_exec_run");
|
||||||
|
if (sim_panel_exec_run (panel)) {
|
||||||
|
printf ("Error resuming simulator execution: %s\n", sim_panel_get_error());
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
usleep (2000000); /* 2 Seconds */
|
||||||
sim_panel_debug (panel, "Shutting down while simulator is running");
|
sim_panel_debug (panel, "Shutting down while simulator is running");
|
||||||
sim_panel_destroy (panel);
|
sim_panel_destroy (panel);
|
||||||
}
|
}
|
||||||
|
|
195
sim_frontpanel.c
195
sim_frontpanel.c
|
@ -158,6 +158,7 @@ struct PANEL {
|
||||||
char *io_response;
|
char *io_response;
|
||||||
size_t io_response_data;
|
size_t io_response_data;
|
||||||
size_t io_response_size;
|
size_t io_response_size;
|
||||||
|
const char *completion_string;
|
||||||
pthread_cond_t io_done;
|
pthread_cond_t io_done;
|
||||||
pthread_cond_t startup_done;
|
pthread_cond_t startup_done;
|
||||||
PANEL_DISPLAY_PCALLBACK callback;
|
PANEL_DISPLAY_PCALLBACK callback;
|
||||||
|
@ -392,6 +393,8 @@ static void *
|
||||||
_panel_debugflusher(void *arg)
|
_panel_debugflusher(void *arg)
|
||||||
{
|
{
|
||||||
PANEL *p = (PANEL*)arg;
|
PANEL *p = (PANEL*)arg;
|
||||||
|
int flush_interval = 15;
|
||||||
|
int sleeps = 0;
|
||||||
|
|
||||||
pthread_setspecific (panel_thread_id, "debugflush");
|
pthread_setspecific (panel_thread_id, "debugflush");
|
||||||
|
|
||||||
|
@ -403,8 +406,9 @@ msleep (100);
|
||||||
pthread_mutex_lock (&p->io_lock);
|
pthread_mutex_lock (&p->io_lock);
|
||||||
while (p->sock != INVALID_SOCKET) {
|
while (p->sock != INVALID_SOCKET) {
|
||||||
pthread_mutex_unlock (&p->io_lock);
|
pthread_mutex_unlock (&p->io_lock);
|
||||||
msleep (15000);
|
msleep (1000);
|
||||||
sim_panel_flush_debug (p);
|
if (0 == (sleeps++)%flush_interval)
|
||||||
|
sim_panel_flush_debug (p);
|
||||||
pthread_mutex_lock (&p->io_lock);
|
pthread_mutex_lock (&p->io_lock);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock (&p->io_lock);
|
pthread_mutex_unlock (&p->io_lock);
|
||||||
|
@ -469,6 +473,9 @@ return sent;
|
||||||
static int
|
static int
|
||||||
_panel_sendf (PANEL *p, int *completion_status, char **response, const char *fmt, ...);
|
_panel_sendf (PANEL *p, int *completion_status, char **response, const char *fmt, ...);
|
||||||
|
|
||||||
|
static int
|
||||||
|
_panel_sendf_completion (PANEL *p, char **response, const char *completion, const char *fmt, ...);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_panel_register_query_string (PANEL *panel, char **buf, size_t *buf_size)
|
_panel_register_query_string (PANEL *panel, char **buf, size_t *buf_size)
|
||||||
{
|
{
|
||||||
|
@ -1046,15 +1053,8 @@ if (panel) {
|
||||||
sim_panel_set_display_callback_interval (panel, NULL, NULL, 0);
|
sim_panel_set_display_callback_interval (panel, NULL, NULL, 0);
|
||||||
/* Next, attempt a simulator shutdown only with the master panel */
|
/* Next, attempt a simulator shutdown only with the master panel */
|
||||||
if (panel->parent == NULL) {
|
if (panel->parent == NULL) {
|
||||||
if (panel->State == Run) {
|
if (panel->State == Run)
|
||||||
int i;
|
sim_panel_exec_halt (panel);
|
||||||
|
|
||||||
_panel_send (panel, "\005\r", 2);
|
|
||||||
for (i=0; (panel->State == Run) && (i < 10); i++)
|
|
||||||
msleep(100);
|
|
||||||
if (panel->State == Run)
|
|
||||||
_panel_debug (panel, DBG_THR, "Unable to HALT running simulator for shutdown", NULL, 0);
|
|
||||||
}
|
|
||||||
_panel_send (panel, "EXIT\r", 5);
|
_panel_send (panel, "EXIT\r", 5);
|
||||||
}
|
}
|
||||||
/* Wait for up to 2 seconds for a graceful shutdown */
|
/* Wait for up to 2 seconds for a graceful shutdown */
|
||||||
|
@ -1459,8 +1459,14 @@ if (panel->parent) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (panel->State == Run) {
|
if (panel->State == Run) {
|
||||||
if (1 != _panel_send (panel, "\005", 1))
|
if (_panel_sendf_completion (panel, NULL, sim_prompt, "\005")) {
|
||||||
|
_panel_debug (panel, DBG_THR, "Error trying to HALT running simulator: %s", NULL, 0, sim_panel_get_error ());
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
if (panel->State == Run) {
|
||||||
|
_panel_debug (panel, DBG_THR, "Unable to HALT running simulator", NULL, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1469,6 +1475,7 @@ int
|
||||||
sim_panel_exec_boot (PANEL *panel, const char *device)
|
sim_panel_exec_boot (PANEL *panel, const char *device)
|
||||||
{
|
{
|
||||||
int cmd_stat;
|
int cmd_stat;
|
||||||
|
char *response, *simtime;
|
||||||
|
|
||||||
if (!panel || (panel->State == Error)) {
|
if (!panel || (panel->State == Error)) {
|
||||||
sim_panel_set_error (NULL, "Invalid Panel");
|
sim_panel_set_error (NULL, "Invalid Panel");
|
||||||
|
@ -1485,12 +1492,17 @@ if (panel->State == Run) {
|
||||||
/* A BOOT or RUN command will restart the simulator's time base. */
|
/* A BOOT or RUN command will restart the simulator's time base. */
|
||||||
/* We account for that so that the frontpanel application sees ever */
|
/* We account for that so that the frontpanel application sees ever */
|
||||||
/* increasing time values when register data is delivered. */
|
/* increasing time values when register data is delivered. */
|
||||||
if (_panel_sendf (panel, &cmd_stat, NULL, "SHOW TIME\r"))
|
if (_panel_sendf (panel, &cmd_stat, &response, "SHOW TIME\r"))
|
||||||
return -1;
|
return -1;
|
||||||
panel->simulation_time_base += panel->simulation_time;
|
if ((simtime = strstr (response, "Time:"))) {
|
||||||
if (_panel_sendf (panel, NULL, NULL, "BOOT %s\r", device))
|
panel->simulation_time = strtoull (simtime + 5, NULL, 10);
|
||||||
|
panel->simulation_time_base += panel->simulation_time;
|
||||||
|
}
|
||||||
|
free (response);
|
||||||
|
if (_panel_sendf_completion (panel, NULL, "Simulator Running...", "BOOT %s\r", device)) {
|
||||||
|
_panel_debug (panel, DBG_THR, "Unable to BOOT simulator: %s", NULL, 0, sim_panel_get_error());
|
||||||
return -1;
|
return -1;
|
||||||
msleep (100); /* Allow Run/Hslt state to settle */
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1498,6 +1510,7 @@ int
|
||||||
sim_panel_exec_start (PANEL *panel)
|
sim_panel_exec_start (PANEL *panel)
|
||||||
{
|
{
|
||||||
int cmd_stat;
|
int cmd_stat;
|
||||||
|
char *response, *simtime;
|
||||||
|
|
||||||
if (!panel || (panel->State == Error)) {
|
if (!panel || (panel->State == Error)) {
|
||||||
sim_panel_set_error (NULL, "Invalid Panel");
|
sim_panel_set_error (NULL, "Invalid Panel");
|
||||||
|
@ -1514,12 +1527,20 @@ if (panel->State == Run) {
|
||||||
/* A BOOT or RUN command will restart the simulator's time base. */
|
/* A BOOT or RUN command will restart the simulator's time base. */
|
||||||
/* We account for that so that the frontpanel application sees ever */
|
/* We account for that so that the frontpanel application sees ever */
|
||||||
/* increasing time values when register data is delivered. */
|
/* increasing time values when register data is delivered. */
|
||||||
if (_panel_sendf (panel, &cmd_stat, NULL, "SHOW TIME\r"))
|
if (_panel_sendf (panel, &cmd_stat, &response, "SHOW TIME\r")) {
|
||||||
|
_panel_debug (panel, DBG_THR, "Unable to send SHOW TIME command while starting simulator: %s", NULL, 0, sim_panel_get_error());
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
if ((simtime = strstr (response, "Time:"))) {
|
||||||
|
panel->simulation_time = strtoull (simtime + 5, NULL, 10);
|
||||||
|
panel->simulation_time_base += panel->simulation_time;
|
||||||
|
}
|
||||||
|
free (response);
|
||||||
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_completion (panel, NULL, "Simulator Running...", "RUN -Q\r", 5)) {
|
||||||
|
_panel_debug (panel, DBG_THR, "Unable to start simulator: %s", NULL, 0, sim_panel_get_error());
|
||||||
return -1;
|
return -1;
|
||||||
msleep (100); /* Allow Run/Hslt state to settle */
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1538,9 +1559,8 @@ if (panel->State == Run) {
|
||||||
sim_panel_set_error (NULL, "Not Halted");
|
sim_panel_set_error (NULL, "Not Halted");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (_panel_sendf (panel, NULL, NULL, "CONT\r", 5))
|
if (_panel_sendf_completion (panel, NULL, "Simulator Running...", "CONT\r"))
|
||||||
return -1;
|
return -1;
|
||||||
msleep (100); /* Allow Run/Hslt state to settle */
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1559,9 +1579,10 @@ if (panel->State == Run) {
|
||||||
sim_panel_set_error (NULL, "Not Halted");
|
sim_panel_set_error (NULL, "Not Halted");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (_panel_sendf_completion (panel, NULL, sim_prompt, "STEP")) {
|
||||||
if (5 != _panel_send (panel, "STEP\r", 5))
|
_panel_debug (panel, DBG_THR, "Error trying to STEP running simulator: %s", NULL, 0, sim_panel_get_error ());
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1579,11 +1600,6 @@ if (panel->parent) {
|
||||||
sim_panel_set_error (NULL, "Can't establish a breakpoint from device front panel");
|
sim_panel_set_error (NULL, "Can't establish a breakpoint from device front panel");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (panel->State == Run) {
|
|
||||||
sim_panel_set_error (NULL, "Not Halted");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_panel_sendf (panel, &cmd_stat, &response, "BREAK %s\r", condition)) ||
|
if ((_panel_sendf (panel, &cmd_stat, &response, "BREAK %s\r", condition)) ||
|
||||||
(*response)) {
|
(*response)) {
|
||||||
sim_panel_set_error (NULL, "Error establishing breakpoint at '%s': %s", condition, response ? response : "");
|
sim_panel_set_error (NULL, "Error establishing breakpoint at '%s': %s", condition, response ? response : "");
|
||||||
|
@ -1608,11 +1624,6 @@ if (panel->parent) {
|
||||||
sim_panel_set_error (NULL, "Can't clear a breakpoint from device front panel");
|
sim_panel_set_error (NULL, "Can't clear a breakpoint from device front panel");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (panel->State == Run) {
|
|
||||||
sim_panel_set_error (NULL, "Not Halted");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_panel_sendf (panel, &cmd_stat, &response, "NOBREAK %s\r", condition)) ||
|
if ((_panel_sendf (panel, &cmd_stat, &response, "NOBREAK %s\r", condition)) ||
|
||||||
(*response)) {
|
(*response)) {
|
||||||
sim_panel_set_error (NULL, "Error clearing breakpoint at '%s': %s", condition, response ? response : "");
|
sim_panel_set_error (NULL, "Error clearing breakpoint at '%s': %s", condition, response ? response : "");
|
||||||
|
@ -1637,11 +1648,6 @@ if (panel->parent) {
|
||||||
sim_panel_set_error (NULL, "Can't establish an output breakpoint from device front panel");
|
sim_panel_set_error (NULL, "Can't establish an output breakpoint from device front panel");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (panel->State == Run) {
|
|
||||||
sim_panel_set_error (NULL, "Not Halted");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_panel_sendf (panel, &cmd_stat, &response, "EXPECT %s\r", condition)) ||
|
if ((_panel_sendf (panel, &cmd_stat, &response, "EXPECT %s\r", condition)) ||
|
||||||
(*response)) {
|
(*response)) {
|
||||||
sim_panel_set_error (NULL, "Error establishing output breakpoint for '%s': %s", condition, response ? response : "");
|
sim_panel_set_error (NULL, "Error establishing output breakpoint for '%s': %s", condition, response ? response : "");
|
||||||
|
@ -1666,11 +1672,6 @@ if (panel->parent) {
|
||||||
sim_panel_set_error (NULL, "Can't clear an output breakpoint from device front panel");
|
sim_panel_set_error (NULL, "Can't clear an output breakpoint from device front panel");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (panel->State == Run) {
|
|
||||||
sim_panel_set_error (NULL, "Not Halted");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_panel_sendf (panel, &cmd_stat, &response, "NOEXPECT %s\r", condition)) ||
|
if ((_panel_sendf (panel, &cmd_stat, &response, "NOEXPECT %s\r", condition)) ||
|
||||||
(*response)) {
|
(*response)) {
|
||||||
sim_panel_set_error (NULL, "Error clearing output breakpoint for '%s': %s", condition, response ? response : "");
|
sim_panel_set_error (NULL, "Error clearing output breakpoint for '%s': %s", condition, response ? response : "");
|
||||||
|
@ -1962,17 +1963,9 @@ if (!panel || (panel->State == Error)) {
|
||||||
sim_panel_set_error (NULL, "Invalid Panel");
|
sim_panel_set_error (NULL, "Invalid Panel");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock (&panel->io_lock);
|
|
||||||
OrigState = panel->State;
|
OrigState = panel->State;
|
||||||
if (OrigState == Run) {
|
if (OrigState == Run)
|
||||||
sim_panel_exec_halt (panel);
|
sim_panel_exec_halt (panel);
|
||||||
while (panel->State == Run) {
|
|
||||||
pthread_mutex_unlock (&panel->io_lock);
|
|
||||||
msleep (100);
|
|
||||||
pthread_mutex_lock (&panel->io_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock (&panel->io_lock);
|
|
||||||
do {
|
do {
|
||||||
if (_panel_sendf (panel, &cmd_stat, &response, "ATTACH %s %s %s", switches, device, path)) {
|
if (_panel_sendf (panel, &cmd_stat, &response, "ATTACH %s %s %s", switches, device, path)) {
|
||||||
stat = -1;
|
stat = -1;
|
||||||
|
@ -1983,10 +1976,8 @@ do {
|
||||||
stat = -1;
|
stat = -1;
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
pthread_mutex_lock (&panel->io_lock);
|
|
||||||
if (OrigState == Run)
|
if (OrigState == Run)
|
||||||
sim_panel_exec_run (panel);
|
sim_panel_exec_run (panel);
|
||||||
pthread_mutex_unlock (&panel->io_lock);
|
|
||||||
free (response);
|
free (response);
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
@ -2010,17 +2001,9 @@ if (!panel || (panel->State == Error)) {
|
||||||
sim_panel_set_error (NULL, "Invalid Panel");
|
sim_panel_set_error (NULL, "Invalid Panel");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock (&panel->io_lock);
|
|
||||||
OrigState = panel->State;
|
OrigState = panel->State;
|
||||||
if (OrigState == Run) {
|
if (OrigState == Run)
|
||||||
sim_panel_exec_halt (panel);
|
sim_panel_exec_halt (panel);
|
||||||
while (panel->State == Run) {
|
|
||||||
pthread_mutex_unlock (&panel->io_lock);
|
|
||||||
msleep (100);
|
|
||||||
pthread_mutex_lock (&panel->io_lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock (&panel->io_lock);
|
|
||||||
do {
|
do {
|
||||||
if (_panel_sendf (panel, &cmd_stat, &response, "DETACH %s", device)) {
|
if (_panel_sendf (panel, &cmd_stat, &response, "DETACH %s", device)) {
|
||||||
stat = -1;
|
stat = -1;
|
||||||
|
@ -2031,10 +2014,8 @@ do {
|
||||||
stat = -1;
|
stat = -1;
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
pthread_mutex_lock (&panel->io_lock);
|
|
||||||
if (OrigState == Run)
|
if (OrigState == Run)
|
||||||
sim_panel_exec_run (panel);
|
sim_panel_exec_run (panel);
|
||||||
pthread_mutex_unlock (&panel->io_lock);
|
|
||||||
free (response);
|
free (response);
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
@ -2302,6 +2283,13 @@ Start_Next_Line:
|
||||||
buf_data = strlen (buf);
|
buf_data = strlen (buf);
|
||||||
if (buf_data)
|
if (buf_data)
|
||||||
_panel_debug (p, DBG_RSP, "Remnant Buffer Contents: '%s'", NULL, 0, buf);
|
_panel_debug (p, DBG_RSP, "Remnant Buffer Contents: '%s'", NULL, 0, buf);
|
||||||
|
if ((!p->parent) &&
|
||||||
|
(p->completion_string) &&
|
||||||
|
(!memcmp (buf, p->completion_string, strlen (p->completion_string)))) {
|
||||||
|
_panel_debug (p, DBG_RCV, "*Received Command Complete - Match: '%s'", NULL, 0, p->completion_string);
|
||||||
|
p->io_waiting = 0;
|
||||||
|
pthread_cond_signal (&p->io_done);
|
||||||
|
}
|
||||||
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;
|
||||||
|
@ -2513,20 +2501,20 @@ return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_panel_sendf (PANEL *p, int *completion_status, char **response, const char *fmt, ...)
|
_panel_vsendf_completion (PANEL *p, int *completion_status, char **response, const char *completion_string, const char *fmt, va_list arglist)
|
||||||
{
|
{
|
||||||
char stackbuf[1024];
|
char stackbuf[1024];
|
||||||
int bufsize = sizeof(stackbuf);
|
int bufsize = sizeof(stackbuf);
|
||||||
char *buf = stackbuf;
|
char *buf = stackbuf;
|
||||||
int len, status_echo_len = 0, sent_len;
|
int len, status_echo_len = 0, sent_len;
|
||||||
int post_fix_len = completion_status ? 7 + sizeof (command_done_echo) + sizeof (command_status) : 1;
|
int post_fix_len = completion_status ? 7 + sizeof (command_done_echo) + sizeof (command_status) : 1;
|
||||||
va_list arglist;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
if (completion_status && completion_string) /* one or the other, but */
|
||||||
|
return -1; /* not both */
|
||||||
|
|
||||||
while (1) { /* format passed string, args */
|
while (1) { /* format passed string, args */
|
||||||
va_start (arglist, fmt);
|
|
||||||
len = vsnprintf (buf, bufsize-1, fmt, arglist);
|
len = vsnprintf (buf, bufsize-1, fmt, arglist);
|
||||||
va_end (arglist);
|
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return sim_panel_set_error (NULL, "Format encoding error while processing '%s'", fmt);
|
return sim_panel_set_error (NULL, "Format encoding error while processing '%s'", fmt);
|
||||||
|
@ -2554,17 +2542,20 @@ if (len && (buf[len-1] != '\r')) {
|
||||||
|
|
||||||
pthread_mutex_lock (&p->io_command_lock);
|
pthread_mutex_lock (&p->io_command_lock);
|
||||||
++p->command_count;
|
++p->command_count;
|
||||||
if (completion_status) {
|
if (completion_status || completion_string) {
|
||||||
sprintf (&buf[len], "%s\r%s\r", command_status, command_done_echo);
|
if (completion_status) {
|
||||||
status_echo_len = strlen (&buf[len]);
|
sprintf (&buf[len], "%s\r%s\r", command_status, command_done_echo);
|
||||||
|
status_echo_len = strlen (&buf[len]);
|
||||||
|
}
|
||||||
pthread_mutex_lock (&p->io_lock);
|
pthread_mutex_lock (&p->io_lock);
|
||||||
|
p->completion_string = completion_string;
|
||||||
p->io_response_data = 0;
|
p->io_response_data = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_panel_debug (p, DBG_REQ, "Command %d Request%s: %*.*s", NULL, 0, p->command_count, completion_status ? " (with response)" : "", len, len, buf);
|
_panel_debug (p, DBG_REQ, "Command %d Request%s: %*.*s", NULL, 0, p->command_count, completion_status ? " (with response)" : "", len, len, buf);
|
||||||
ret = ((len + status_echo_len) == (sent_len = _panel_send (p, buf, len + status_echo_len))) ? 0 : -1;
|
ret = ((len + status_echo_len) == (sent_len = _panel_send (p, buf, len + status_echo_len))) ? 0 : -1;
|
||||||
|
|
||||||
if (completion_status) {
|
if (completion_status || completion_string) {
|
||||||
if (!ret) { /* Sent OK? */
|
if (!ret) { /* Sent OK? */
|
||||||
char *tresponse = NULL;
|
char *tresponse = NULL;
|
||||||
|
|
||||||
|
@ -2575,29 +2566,39 @@ if (completion_status) {
|
||||||
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 (tresponse, p->io_response + strlen (sim_prompt) + len + 1, p->io_response_data + 1 - (strlen (sim_prompt) + len + 1));
|
||||||
*completion_status = -1;
|
if (completion_status) {
|
||||||
status = strstr (tresponse, command_status);
|
*completion_status = -1;
|
||||||
if (status) {
|
status = strstr (tresponse, command_status);
|
||||||
*(status - strlen (sim_prompt)) = '\0';
|
if (status) {
|
||||||
status += strlen (command_status) + 2;
|
*(status - strlen (sim_prompt)) = '\0';
|
||||||
eol = strchr (status, '\r');
|
status += strlen (command_status) + 2;
|
||||||
if (eol)
|
eol = strchr (status, '\r');
|
||||||
*eol = '\0';
|
if (eol)
|
||||||
sscanf (status, "Status:%08X-", completion_status);
|
*eol = '\0';
|
||||||
|
sscanf (status, "Status:%08X-", completion_status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
memcpy (tresponse, p->io_response, p->io_response_data + 1);
|
memcpy (tresponse, p->io_response, p->io_response_data + 1);
|
||||||
if (response) {
|
if (response) {
|
||||||
*response = tresponse;
|
*response = tresponse;
|
||||||
_panel_debug (p, DBG_RSP, "Command %d Response(Status=%d): '%s'", NULL, 0, p->command_count, *completion_status, *response);
|
if (completion_status)
|
||||||
|
_panel_debug (p, DBG_RSP, "Command %d Response(Status=%d): '%s'", NULL, 0, p->command_count, *completion_status, *response);
|
||||||
|
else
|
||||||
|
_panel_debug (p, DBG_RSP, "Command %d Response - Match '%s': '%s'", NULL, 0, p->command_count, completion_string, *response);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
free (tresponse);
|
free (tresponse);
|
||||||
if (p->io_response_data)
|
if (p->io_response_data) {
|
||||||
_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);
|
if (completion_status)
|
||||||
|
_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);
|
||||||
|
else
|
||||||
|
_panel_debug (p, DBG_RSP, "Discarded Unwanted Command %d Response Data - Match '%s':", p->io_response, p->io_response_data, p->command_count, completion_string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
p->completion_string = NULL;
|
||||||
p->io_response_data = 0;
|
p->io_response_data = 0;
|
||||||
p->io_response[0] = '\0';
|
p->io_response[0] = '\0';
|
||||||
pthread_mutex_unlock (&p->io_lock);
|
pthread_mutex_unlock (&p->io_lock);
|
||||||
|
@ -2613,6 +2614,30 @@ if (buf != stackbuf)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_panel_sendf (PANEL *p, int *completion_status, char **response, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list arglist;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
va_start (arglist, fmt);
|
||||||
|
status = _panel_vsendf_completion (p, completion_status, response, NULL, fmt, arglist);
|
||||||
|
va_end (arglist);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_panel_sendf_completion (PANEL *p, char **response, const char *completion, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list arglist;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
va_start (arglist, fmt);
|
||||||
|
status = _panel_vsendf_completion (p, NULL, response, completion, fmt, arglist);
|
||||||
|
va_end (arglist);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ extern "C" {
|
||||||
|
|
||||||
#if !defined(__VAX) /* Unsupported platform */
|
#if !defined(__VAX) /* Unsupported platform */
|
||||||
|
|
||||||
#define SIM_FRONTPANEL_VERSION 9
|
#define SIM_FRONTPANEL_VERSION 10
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue