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
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'.
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
+#include <sys/poll.h>
static const char hex[] = "0123456789abcdef";
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;
}
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
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;