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)

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)