]> git.sur5r.net Git - openocd/commitdiff
1. GDB will print cryptic error messages if it is not fed keep-alive packets
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Fri, 18 Jul 2008 10:20:10 +0000 (10:20 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Fri, 18 Jul 2008 10:20:10 +0000 (10:20 +0000)
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

src/helper/log.c
src/helper/log.h
src/server/server.c
src/target/target.c

index e9c1fa205d2a5aa5273a3b2fa445593aa6d5ee88..0a416244829452571c60fbf5cfbd96484717dd28 100644 (file)
@@ -40,6 +40,9 @@ int debug_level = -1;
 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] =
@@ -229,6 +232,8 @@ int log_init(struct command_context_s *cmd_ctx)
                log_output = stderr;
        }
        
+       start=last_time=timeval_ms();
+       
        return ERROR_OK;
 }
        
@@ -327,3 +332,43 @@ char *alloc_printf(const char *format, ...)
        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;
+}
index 37490a8603d2af47bd4bc0cdbda785d785cb8e00..7a7c90cbc462678afe690aa3188074bac4f133f1 100644 (file)
@@ -56,6 +56,8 @@ __attribute__ ((format (printf, 5, 6)));
 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);
index 2d910a1ab0ee9bc5d794253046dca642f6ad29cb..ce0ee6cd231863a41fbbe973042d608a2860f4a3 100644 (file)
@@ -310,6 +310,7 @@ int server_loop(command_context_t *command_context)
 #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();
index 589f626f0902f61a6f551cca298eeada31614b03..ea130ce3a52e42c06cfa4b69a937d0198a41b188 100644 (file)
@@ -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 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)
@@ -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)
                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;
 }
 
@@ -407,6 +425,11 @@ int target_process_reset(struct command_context_s *cmd_ctx)
                        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");
        
@@ -464,7 +487,6 @@ int target_process_reset(struct command_context_s *cmd_ctx)
        }
        target_unregister_event_callback(target_init_handler, cmd_ctx);
        
-       jtag->speed(jtag_speed_post_reset);
        
        return retval;
 }
@@ -738,6 +760,8 @@ static int target_call_timer_callbacks_check_time(int checktime)
        target_timer_callback_t *next_callback;
        struct timeval now;
 
+       keep_alive();
+       
        gettimeofday(&now, NULL);
        
        while (callback)