1. GDB will print cryptic error messages if it is not fed keep-alive packets
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
This commit is contained in:
parent
7648d6b287
commit
94e75e0c06
|
@ -40,6 +40,9 @@ int debug_level = -1;
|
||||||
static FILE* log_output;
|
static FILE* log_output;
|
||||||
static log_callback_t *log_callbacks = NULL;
|
static log_callback_t *log_callbacks = NULL;
|
||||||
|
|
||||||
|
static long long last_time;
|
||||||
|
static long long current_time;
|
||||||
|
|
||||||
static long long start;
|
static long long start;
|
||||||
|
|
||||||
static char *log_strings[5] =
|
static char *log_strings[5] =
|
||||||
|
@ -229,6 +232,8 @@ int log_init(struct command_context_s *cmd_ctx)
|
||||||
log_output = stderr;
|
log_output = stderr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start=last_time=timeval_ms();
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,3 +332,43 @@ char *alloc_printf(const char *format, ...)
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return string;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ __attribute__ ((format (printf, 5, 6)));
|
||||||
extern int log_register_commands(struct command_context_s *cmd_ctx);
|
extern int log_register_commands(struct command_context_s *cmd_ctx);
|
||||||
extern int log_init(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 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,
|
typedef void (*log_callback_fn)(void *priv, const char *file, int line,
|
||||||
const char *function, const char *string);
|
const char *function, const char *string);
|
||||||
|
|
|
@ -310,6 +310,7 @@ int server_loop(command_context_t *command_context)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
openocd_sleep_prelude();
|
openocd_sleep_prelude();
|
||||||
|
kept_alive();
|
||||||
// Only while we're sleeping we'll let others run
|
// Only while we're sleeping we'll let others run
|
||||||
retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
|
retval = select(fd_max + 1, &read_fds, NULL, NULL, &tv);
|
||||||
openocd_sleep_postlude();
|
openocd_sleep_postlude();
|
||||||
|
|
|
@ -266,6 +266,9 @@ int target_halt(struct target_s *target)
|
||||||
int target_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
|
int target_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
|
||||||
{
|
{
|
||||||
int retval;
|
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 */
|
/* We can't poll until after examine */
|
||||||
if (!target->type->examined)
|
if (!target->type->examined)
|
||||||
|
@ -277,6 +280,21 @@ int target_resume(struct target_s *target, int current, u32 address, int handle_
|
||||||
if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK)
|
if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK)
|
||||||
return retval;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,6 +425,11 @@ int target_process_reset(struct command_context_s *cmd_ctx)
|
||||||
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");
|
LOG_DEBUG("Waiting for halted stated as approperiate");
|
||||||
|
|
||||||
|
@ -464,7 +487,6 @@ int target_process_reset(struct command_context_s *cmd_ctx)
|
||||||
}
|
}
|
||||||
target_unregister_event_callback(target_init_handler, cmd_ctx);
|
target_unregister_event_callback(target_init_handler, cmd_ctx);
|
||||||
|
|
||||||
jtag->speed(jtag_speed_post_reset);
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -738,6 +760,8 @@ static int target_call_timer_callbacks_check_time(int checktime)
|
||||||
target_timer_callback_t *next_callback;
|
target_timer_callback_t *next_callback;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
|
|
||||||
|
keep_alive();
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
|
|
||||||
while (callback)
|
while (callback)
|
||||||
|
|
Loading…
Reference in New Issue