Fix continue command.
authorPeter Zotov <whitequark@whitequark.org>
Tue, 15 Feb 2011 21:21:38 +0000 (00:21 +0300)
committerPeter Zotov <whitequark@whitequark.org>
Tue, 15 Feb 2011 21:24:00 +0000 (00:24 +0300)
README
src/gdb-remote.c
src/gdb-remote.h
src/gdb-server.c

diff --git a/README b/README
index 47c7c2f05e81bb47128f7fc15731cadb4d4de903..a09cd442c3f46c5dea5e3e38d916e62cf13c3982 100644 (file)
--- a/README
+++ b/README
@@ -31,10 +31,6 @@ then it would be written to the memory.
 Caveats
 =======
 
-`continue' GDB command does not work: target does not step at
-all or steps with a turtle speed. Looks like there's something
-wrong with SCSI requests.
-
 GDB sends requests for a multi-sectioned ELF files (most ones;
 having both .text and .rodata is enough) in a quite strange way which
 absolutely does not conform to flash page boundaries. Which is even more
@@ -42,4 +38,8 @@ weird when you think about FlashErase requests which it sends correctly.
 And I couldn't think of a way which will resolve this correctly now.
 
 Hardware breakpoints are not supported yet. You can still run your code from
-RAM, and then GDB will insert bkpt opcodes automagically.
+RAM, and then GDB will insert `bkpt' opcodes automagically.
+
+Sometimes when you will try to use GDB `next' command to skip a loop,
+it will use a rather inefficient single-stepping way of doing that.
+Set up a breakpoint manually in that case and do `continue'.
index 8ed132f1d24ae0fb0e1a7931082dfc133e31a69c..474af9dcc46f9c04d1f799331466722194f8e1c1 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdint.h>
+#include <sys/poll.h>
 
 static const char hex[] = "0123456789abcdef";
 
@@ -132,14 +133,24 @@ start:
        return packet_size;
 }
 
-int gdb_wait_for_interrupt(int fd) {
-       char c;
-       while(1) {
+// Here we skip any characters which are not \x03, GDB interrupt.
+// As we use the mode with ACK, in a (very unlikely) situation of a packet
+// lost because of this skipping, it will be resent anyway.
+int gdb_check_for_interrupt(int fd) {
+       struct pollfd pfd;
+       pfd.fd = fd;
+       pfd.events = POLLIN;
+
+       if(poll(&pfd, 1, 0) != 0) {
+               char c;
+
                if(read(fd, &c, 1) != 1)
                        return -2;
 
                if(c == '\x03') // ^C
-                       return 0;
+                       return 1;
        }
+
+       return 0;
 }
 
index d4c7d7a69b953db1ab5705eca1c4a951fc9beafa..bfa01046c45cdb7803b8d741efaf94ffad3d1bc7 100644 (file)
@@ -3,6 +3,6 @@
 
 int gdb_send_packet(int fd, char* data);
 int gdb_recv_packet(int fd, char** buffer);
-int gdb_wait_for_interrupt(int fd);
+int gdb_check_for_interrupt(int fd);
 
 #endif
index 615bf06c04e5d872911c88be734047df9f63b339..e98f78078bfb6e23ca89a85bc4e0cd0f6e40ed64 100644 (file)
@@ -271,15 +271,27 @@ int serve(struct stlink* sl, int port) {
                case 'c':
                        stlink_run(sl);
 
-                       printf("Core running, waiting for interrupt.\n");
+                       printf("Core running, waiting for interrupt (either in chip or GDB).\n");
 
-                       int status = gdb_wait_for_interrupt(client);
-                       if(status < 0) {
-                               fprintf(stderr, "cannot wait for int: %d\n", status);
-                               return 1;
-                       }
+                       while(1) {
+                               int status = gdb_check_for_interrupt(client);
+                               if(status < 0) {
+                                       fprintf(stderr, "cannot check for int: %d\n", status);
+                                       return 1;
+                               }
+
+                               if(status == 1) {
+                                       stlink_force_debug(sl);
+                                       break;
+                               }
+
+                               stlink_status(sl);
+                               if(sl->core_stat == STLINK_CORE_HALTED) {
+                                       break;
+                               }
 
-                       stlink_force_debug(sl);
+                               usleep(200000);
+                       }
 
                        reply = strdup("S05"); // TRAP
                        break;