within the last 2000ms.
To fix this, add keep_alive() if you are spending >1000ms in an algorithm
thus holding up the server loop.
target_call_timer_callbacks() invokes keep_alive().
2. post_reset script is now executed at normal JTAG speed and not
reset speed.
3. Resume is now synchronous again. Hopefully it will work this time.
git-svn-id: svn://svn.berlios.de/openocd/trunk@826
b42882b7-edfa-0310-969c-
e2dbd0fdcd60
static FILE* log_output;
static log_callback_t *log_callbacks = NULL;
+static long long last_time;
+static long long current_time;
+
static long long start;
static char *log_strings[5] =
log_output = stderr;
}
+ start=last_time=timeval_ms();
+
return ERROR_OK;
}
va_end(ap);
return string;
}
+
+/* Code must return to the server loop before 1000ms has returned or invoke
+ * this function.
+ *
+ * The GDB connection will time out if it spends >2000ms and you'll get nasty
+ * error messages from GDB:
+ *
+ * Ignoring packet error, continuing...
+ * Reply contains invalid hex digit 116
+ *
+ * While it is possible use "set remotetimeout" to more than the default 2000ms
+ * in GDB, OpenOCD guarantees that it sends keep-alive packages on the
+ * GDB protocol and it is a bug in OpenOCD not to either return to the server
+ * loop or invoke keep_alive() every 1000ms.
+ *
+ * This function will send a keep alive packet if >500ms has passed since last time
+ * it was invoked.
+ *
+ */
+void keep_alive()
+{
+ current_time=timeval_ms();
+ if (current_time-last_time>1000)
+ {
+ LOG_WARNING("keep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (%d)", current_time-last_time);
+ last_time=current_time;
+ } else if (current_time-last_time>500)
+ {
+ /* this will keep the GDB connection alive */
+ LOG_USER_N("%s", "");
+ last_time=current_time;
+ }
+}
+
+/* reset keep alive timer without sending message */
+void kept_alive()
+{
+ current_time=timeval_ms();
+ last_time=current_time;
+}
extern int log_register_commands(struct command_context_s *cmd_ctx);
extern int log_init(struct command_context_s *cmd_ctx);
extern int set_log_output(struct command_context_s *cmd_ctx, FILE *output);
+extern void keep_alive();
+extern void kept_alive();
typedef void (*log_callback_fn)(void *priv, const char *file, int line,
const char *function, const char *string);
#endif
openocd_sleep_prelude();
+ kept_alive();
// Only while we're sleeping we'll let others run
retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
openocd_sleep_postlude();
int target_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
{
int retval;
+ int timeout_ms = 5000;
+
+ enum target_state resume_state = debug_execution ? TARGET_DEBUG_RUNNING : TARGET_RUNNING;
/* We can't poll until after examine */
if (!target->type->examined)
if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK)
return retval;
+ /* wait for target to exit halted mode */
+ target_poll(target);
+
+ while (target->state != resume_state)
+ {
+ target_call_timer_callbacks();
+ usleep(10000);
+ target_poll(target);
+ if ((timeout_ms -= 10) <= 0)
+ {
+ LOG_ERROR("timeout waiting for target resume");
+ return ERROR_TARGET_TIMEOUT;
+ }
+ }
+
return retval;
}
return retval;
}
+ /* post reset scripts can be quite long, increase speed now. If post
+ * reset scripts needs a different speed, they can set the speed to
+ * whatever they need.
+ */
+ jtag->speed(jtag_speed_post_reset);
LOG_DEBUG("Waiting for halted stated as approperiate");
}
target_unregister_event_callback(target_init_handler, cmd_ctx);
- jtag->speed(jtag_speed_post_reset);
return retval;
}
target_timer_callback_t *next_callback;
struct timeval now;
+ keep_alive();
+
gettimeofday(&now, NULL);
while (callback)