Add support for remote reset commands.
authorPeter Zotov <whitequark@whitequark.org>
Mon, 4 Apr 2011 08:22:40 +0000 (12:22 +0400)
committerPeter Zotov <whitequark@whitequark.org>
Mon, 4 Apr 2011 16:20:13 +0000 (20:20 +0400)
README
src/gdb-server.c

diff --git a/README b/README
index c94177bac1714011fc1926386e9254c94260c4fb..920786ebf407b57d062bafbfbba5ac5484630004 100644 (file)
--- a/README
+++ b/README
@@ -10,6 +10,22 @@ Then, in gdb:
 
 Have fun!
 
+Resetting the chip from GDB
+===========================
+
+You may reset the chip using GDB if you want. You'll need to use `target
+extended-remote' command like in this session:
+(gdb) target extended-remote localhost:1111
+Remote debugging using localhost:1111
+0x080007a8 in _startup ()
+(gdb) kill
+Kill the program being debugged? (y or n) y
+(gdb) run
+Starting program: /home/whitequark/ST/apps/bally/firmware.elf 
+
+Remember that you can shorten the commands. `tar ext :1111' is good enough
+for GDB.
+
 Running programs from SRAM
 ==========================
 
index 69ffdad61427c923278d0d5903bcf9fe7fdb18e0..b48f7d6d8256af38f9676c34aaf6f51968402ff6 100644 (file)
@@ -303,6 +303,12 @@ int serve(struct stlink* sl, int port) {
 
        printf("GDB connected.\n");
 
+       /*
+        * To allow resetting the chip from GDB it is required to
+        * emulate attaching and detaching to target.
+        */
+       unsigned int attached = 1;
+
        while(1) {
                char* packet;
 
@@ -389,16 +395,10 @@ int serve(struct stlink* sl, int port) {
                }
 
                case 'v': {
-                       char *separator = strstr(packet, ":"), *params = "";
-                       if(separator == NULL) {
-                               separator = packet + strlen(packet);
-                       } else {
-                               params = separator + 1;
-                       }
+                       char *params = NULL;
+                       char *cmdName = strtok_r(packet, ":;", &params);
 
-                       unsigned cmdNameLength = (separator - &packet[1]);
-                       char* cmdName = calloc(cmdNameLength + 1, 1);
-                       strncpy(cmdName, &packet[1], cmdNameLength);
+                       cmdName++; // vCommand -> Command
 
                        if(!strcmp(cmdName, "FlashErase")) {
                                char *s_addr, *s_length;
@@ -463,13 +463,15 @@ int serve(struct stlink* sl, int port) {
                                } else {
                                        reply = strdup("OK");
                                }
+                       } else if(!strcmp(cmdName, "Kill")) {
+                               attached = 0;
+
+                               reply = strdup("OK");
                        }
 
                        if(reply == NULL)
                                reply = strdup("");
 
-                       free(cmdName);
-
                        break;
                }
 
@@ -506,7 +508,12 @@ int serve(struct stlink* sl, int port) {
                        break;
 
                case '?':
-                       reply = strdup("S05"); // TRAP
+                       if(attached) {
+                               reply = strdup("S05"); // TRAP
+                       } else {
+                               /* Stub shall reply OK if not attached. */
+                               reply = strdup("OK");
+                       }
                        break;
 
                case 'g':
@@ -644,12 +651,28 @@ int serve(struct stlink* sl, int port) {
                        break;
                }
 
-               case 'k': {
-                       // After this function will be entered afterwards, the
-                       // chip will be reset anyway. So this is a no-op.
+               case '!': {
+                       /*
+                        * Enter extended mode which allows restarting.
+                        * We do support that always.
+                        */
+
+                       reply = strdup("OK");
+
+                       break;
+               }
+
+               case 'R': {
+                       /* Reset the core. */
+
+                       stlink_reset(sl);
+                       init_code_breakpoints(sl);
+
+                       attached = 1;
 
-                       close(client);
-                       return 0;
+                       reply = strdup("OK");
+
+                       break;
                }
 
                default: