Commit 33a2edabead9f6108f6227e00052caabf4e67fe7
receivedMon, 15. Jul 2024, 18:54:33 (by user sx)
Mon, 15 Jul 2024 16:54:33 +0000 (18:54 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Mon, 15 Jul 2024 16:54:26 +0000 (18:54 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Mon, 15 Jul 2024 16:54:26 +0000 (18:54 +0200)
12 files changed:
software/gdb-stub/.gdbinit
software/gdb-stub/.simucinit
software/gdb-stub/.vscode/settings.json
software/gdb-stub/Makefile
software/gdb-stub/README.md
software/gdb-stub/docs/protocol.md
software/gdb-stub/sim/.gdbinit [new file with mode: 0644]
software/gdb-stub/sim/.simucinit [new file with mode: 0644]
software/gdb-stub/sim/picocom [new file with mode: 0644]
software/gdb-stub/src/bootloader.cpp
software/gdb-stub/src/bootloader.h
software/gdb-stub/src/gdb.cpp

index 62613ef17e25f1805bd2bd0356008939e8e9d7e2..300127407a69b2077ecfcd31cb25007a5a52e351 100644 (file)
@@ -1,12 +1,14 @@
-alias reset = set *((uint8_t *)0x8008fd) = 0x40
-alias startapp = set *((uint8_t *)0x8008fd) = 0x20
-alias killapp = set *((uint8_t *)0x8008fd) = 0x10
+alias reset = set *((uint8_t *)0x8010fd) = 0x40
+alias startapp = set *((uint8_t *)0x8010fd) = 0x20
+alias killapp = set *((uint8_t *)0x8010fd) = 0x10
 
 set history save on
 set history size unlimited
 set history remove-duplicates unlimited
 set pagination off
 set non-stop 1
-#file dist/gdb-stub-sm_atmega324p.elf
-#target remote localhost:2424
+file dist/gdb-stub_atmega644p.elf
+
+set serial baud 115200
+target remote /dev/ttyUSB1
 
index cc67172a2594158f14c186235ee5bfb2e546eefe..481f243862e5b0328b768a538dc8ad317a37ea16 100644 (file)
@@ -6,5 +6,5 @@
 --log none
 #--nosync
 dist/gdb-stub_atmega644p.elf
-../test-2024-07-02/dist/test-nano-644.elf
+../test-2024-07-02/sim/test-nano-644.elf
 
index 1901a6dad53e8434ac1f9e06abfed5c5d03df8ed..df0709ce2d828ef433f040778918faf5a14b6b4c 100644 (file)
@@ -25,6 +25,9 @@
     "files.trimTrailingWhitespace": true,
     "editor.tabSize": 4,
     "editor.insertSpaces": false,
+    "[markdown]": {
+        "files.trimTrailingWhitespace": false
+    },
     "cSpell.words": [
         "adiw",
         "APPINIT",
index c48e337f5d137b34f3c861ad1cf20369afd694e0..a595000fce02707cc99bd52d7de9d81e85e4267c 100644 (file)
@@ -17,10 +17,11 @@ CFLAGS = -g -DF_CPU=12000000L -Os -Wall -gdwarf-2
 LFLAGS = -gdwarf-2
 LFLAGS += -Wl,-Tldscripts/ldscript_atmega644p.x
 
-CFLAGS_SIM = -g -DF_CPU=12000000L -Os -Wall -gdwarf-2
+CFLAGS_SIM = -g -DF_CPU=12000000L -Og -Wall -gdwarf-2
 CFLAGS_SIM += -DSIMAVR
 LFLAGS_SIM = -gdwarf-2
-LFLAGS_SIM += -Wl,-Tldscripts/ldscript_atmega644p_sim.x
+#LFLAGS_SIM += -Wl,-Tldscripts/ldscript_atmega644p_sim.x
+LFLAGS_SIM += -Wl,-Tldscripts/ldscript_atmega644p.x
 
 DEVICE = atmega644p
 
index b2777f713b72c5837481a886b0314be10a14a600..b38eae1ac201387d7cc6ef6745c67a23dc5dcd08 100644 (file)
@@ -20,7 +20,7 @@ Auf der UART1 Schnittstelle erfolgt die Kommunikation mit dem avr-gdb.
 
 Programmiere EEPROM Adresse 0 mit 0x00 (im gdb-stub dauerhaft bleiben):
 ```
-avrdude -c usbasp -p atmega324p -U eeprom:w:0x00:m
+avrdude -c usbasp -p atmega644p -U eeprom:w:0x00:m
 ```
 
 Programmier EEPROM Adresse 0 mit 0xff (gdb-stub sofoert verlassen und Applikation starten):
index fe9da05080a2bdabfd80094c6c350ece552bba1e..bbfb3b6787872f4f176f7745e4e7824fd3172041 100644 (file)
@@ -3,7 +3,7 @@
 * `--->` Request from *avr-gdb* to *gdb-stub* (in µC)
 * `<---` Response from *gdb-stub* (in µC) to *avr-gdb*
 
-## Request/Response 1
+## 1 Request/Response
 
 [https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSupported-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSupported-packet)
 
@@ -19,7 +19,7 @@ Tell the remote stub about features supported by GDB, and query the stub for fea
 ```
 ------------------------------------------------------------
 
-## Request/Response 2
+## 2 Request/Response
 
 [https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#index-vMustReplyEmpty-packet](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#index-vMustReplyEmpty-packet)
 
@@ -36,7 +36,7 @@ The `vMustReplyEmpty` is used as a feature test to check how gdbserver handles u
 
 ------------------------------------------------------------
 
-## Request/Response 3
+## 3 Request/Response
 
 Set thread for subsequent operations (‘m’, ‘M’, ‘g’, ‘G’, et.al.):
 [https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-H-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-H-packet)
@@ -50,7 +50,7 @@ Set thread for subsequent operations (‘m’, ‘M’, ‘g’, ‘G’, et.al.
 
 ------------------------------------------------------------
 
-## Request/Response 4
+## 4 Request/Response
 
 [https://sourceware.org/gdb/current/onlinedocs/gdb.html/General-Query-Packets.html#index-QNonStop-packet](https://sourceware.org/gdb/current/onlinedocs/gdb.html/General-Query-Packets.html#index-QNonStop-packet)
 
@@ -65,7 +65,7 @@ Enter non-stop (‘QNonStop:1’) mode. See [Remote Non-Stop](https://sourceware
 
 ------------------------------------------------------------
 
-## Request/Response 5
+## 5 Request/Response
 
 [https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet)
 
@@ -80,7 +80,7 @@ Start to obtain a list of all active thread IDs from the target
 
 ------------------------------------------------------------
 
-## Request/Response 6
+## 6 Request/Response
 
 [https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet)
 
@@ -95,7 +95,7 @@ Continue to obtain a list of all active thread IDs from the target
 
 ------------------------------------------------------------
 
-## Request/Response 7
+## 7 Request/Response
 
  [https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qAttached-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qAttached-packet)
 
@@ -110,7 +110,7 @@ Return an indication of whether the remote server attached to an existing proces
 
 ------------------------------------------------------------
 
-## Request/Response 8
+## 8 Request/Response
 
 [https://sourceware.org/gdb/onlinedocs/gdb/Tracepoint-Packets.html#index-qTStatus-packet](https://sourceware.org/gdb/onlinedocs/gdb/Tracepoint-Packets.html#index-qTStatus-packet)
 
@@ -125,7 +125,7 @@ Ask the stub if there is a trace experiment running right now.
 
 ------------------------------------------------------------
 
-## Request/Response 9
+## 9 Request/Response
 
 [https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-_003f-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-_003f-packet)
 
@@ -140,7 +140,7 @@ This is sent when connection is first established to query the reason the target
 
 ------------------------------------------------------------
 
-## Request/Response 10
+## 10 Request/Response
 
 [https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont_003f-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont_003f-packet)
 
@@ -155,11 +155,19 @@ Request a list of actions supported by the ‘vCont’ packet.
 
 ------------------------------------------------------------
 
-## Request/Response 11
+## 11 Request/Response
 
 [https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet)
 
 Resume the inferior, specifying different actions for each thread.
+* `c` Continue.
+* `C sig` Continue with signal sig. The signal sig should be two hex digits.
+* `s` Step.
+* `S sig` Step with signal sig. The signal sig should be two hex digits.
+* **`t` Stop.**
+
+==> STOP the application  
+==> gdb-stub sends status packet "%..." when STOP is executed
 
 ```
 ---> $vCont;t:1#24
@@ -170,7 +178,21 @@ Resume the inferior, specifying different actions for each thread.
 
 ------------------------------------------------------------
 
-## Request/Response 12
+## 12 Notification Stop
+
+[https://sourceware.org/gdb/current/onlinedocs/gdb.html/Notification-Packets.html#Notification-Packets](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Notification-Packets.html#Notification-Packets)
+
+The GDB remote serial protocol includes notifications, packets that require no acknowledgment.
+
+After receiving a notification, GDB shall acknowledge it by sending a ack packet as a regular, synchronous request to the stub. Such acknowledgment is not required to happen immediately, as GDB is permitted to send other, unrelated packets to the stub first, which the stub should process normally.
+
+```
+<--- %Stop:T00thread:1;#b2
+```
+
+------------------------------------------------------------
+
+## 13 Request/Response
 
 [https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSymbol-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSymbol-packet)
 
@@ -183,3 +205,79 @@ Notify the target that GDB is prepared to serve symbol lookup requests:
 <--- $OK#9a
 ---> +
 ```
+
+------------------------------------------------------------
+
+## 14 Acknowledge for Stop-Notification (12)
+
+[https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#index-vStopped-packet](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#index-vStopped-packet)
+
+
+
+```
+---> $vStopped#55
+<--- +
+<--- $OK#9a
+---> +
+```
+
+------------------------------------------------------------
+
+## 15 Request/Response
+
+[https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-H-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-H-packet)
+
+Set thread for subsequent operations (‘m’, ‘M’, ‘g’, ‘G’, et.al.).  
+Use ‘g’ for other operations.
+
+
+```
+---> $Hg1#e0
+<--- +
+<--- $OK#9a
+---> +
+```
+
+------------------------------------------------------------
+
+## 16 Request/Response
+
+[https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-g-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-g-packet)
+
+Read general registers (used on gdb command load)
+
+```
+---> $g#67
+<--- +
+<--- $000000000000000000000000000000000000000000000000000000000000000000000000000000#a0
+--> +
+```
+
+oder:
+
+```
+---> $g#67
+<--- +
+<--- $0*j#c4
+---> +
+```
+
+------------------------------------------------------------
+
+## 17 Request/Response
+
+[https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet)
+
+Resume the inferior, specifying different actions for each thread.
+* `c` Continue.
+* `C sig` Continue with signal sig. The signal sig should be two hex digits.
+* `s` Step.
+* `S sig` Step with signal sig. The signal sig should be two hex digits.
+* **`t` Stop.**
+
+```
+---> $vCont;c#a8
+<--- +
+<--- $OK#9a
+---> +
+```
diff --git a/software/gdb-stub/sim/.gdbinit b/software/gdb-stub/sim/.gdbinit
new file mode 100644 (file)
index 0000000..328d1eb
--- /dev/null
@@ -0,0 +1,13 @@
+alias reset = set *((uint8_t *)0x8008fd) = 0x40
+alias startapp = set *((uint8_t *)0x8008fd) = 0x20
+alias killapp = set *((uint8_t *)0x8008fd) = 0x10
+
+set history save on
+set history size unlimited
+set history remove-duplicates unlimited
+set pagination off
+#set non-stop 1
+file dist/gdb-stub_atmega644p.axf
+br src/gdb.cpp:315
+target remote localhost:1234
+layout split
diff --git a/software/gdb-stub/sim/.simucinit b/software/gdb-stub/sim/.simucinit
new file mode 100644 (file)
index 0000000..050b58a
--- /dev/null
@@ -0,0 +1,10 @@
+#--board nano-644   
+--pc 0xe000
+--frequency 12000000
+--mmcu atmega644p
+#--log trace
+--log none
+#--nosync
+dist/gdb-stub_atmega644p.elf
+../../test-2024-07-02/sim/test-nano-644.elf
+
diff --git a/software/gdb-stub/sim/picocom b/software/gdb-stub/sim/picocom
new file mode 100644 (file)
index 0000000..e69de29
index f6800871263ad357f8321f97e3d68c88b283955c..0b577063775f7008216a4bde787cfc36b6a7bf2d 100644 (file)
@@ -317,8 +317,10 @@ namespace bootloader {
                                gdb::executeControl();
                                gdb::handleGdbRequest();
                                if (pgdb->ctrl.start) {
+                                       setLedOrange(1);
                                        pgdb->ctrl.start = 0;
                                        startProgram = 0;
+                                       eepromByteAddrZero = 0xff;
                                }
                                if (startProgram == 0 || TCNT1 >= 0x16E3) { // 499,966ms
                                        toggleLedRed();
@@ -341,8 +343,9 @@ namespace bootloader {
 
                uint8_t b = pgm_read_byte(0x0000); // check if app in non bootloader flash
 
-               setLedOrange(1);
                if (b != 0xff) {
+                       setLedOrange(0);
+                       setLedGreen(1);
                        struct gdb::Gdb *pgdb = GDB_PTR;
                        pgdb->status.isAppStarted = 1;
                        pgdb->status.isStopped = 0;
@@ -351,7 +354,6 @@ namespace bootloader {
                                gdb::handleGdbRequest();
                        }
                }
-               toggleLedGreen();
                putln(stdoutUart);
                // make sure that last UART Bytes are sent completely
                TCNT1 = 0;
@@ -492,6 +494,26 @@ namespace bootloader {
                }
        }
 
+       void putStatus (int8_t uart) {
+               // struct gdb::Gdb *pgdb = GDB_PTR;
+               // putln(uart);
+               // printChar(uart, 'S');
+               // printChar(uart, '-');
+               // printChar(uart, pgdb->status.isAppStarted ? 'A' : 'a');
+               // printChar(uart, pgdb->status.isStopped ? 'S' : 's');
+               // printChar(uart, pgdb->status.isConnected ? 'C' : 'x');
+               // printChar(uart, pgdb->status.isBreakpointValid ? 'B' : 'b');
+               // putln(uart);
+
+               struct gdb::Gdb *pgdb = GDB_PTR;
+               putln(uart);
+               printChar(uart, 'S');
+               printChar(uart, '-');
+               putUint8Hex(0, (uint8_t)(((uint16_t)(void *)&pgdb->ctrl) >> 8) );
+               putUint8Hex(0, (uint8_t)((uint16_t)(void *)&pgdb->ctrl) );
+               putln(uart);
+       }
+
        void memputc (int8_t uart, PGM_P p) {
                char c = pgm_read_byte(p);
                printChar(uart, c);
index fe8051566b2b2b925937eb81533f5d33d0631b7b..4476a35b94f075c95cd94f10292dfcaa02467016 100644 (file)
@@ -84,6 +84,9 @@ namespace bootloader {
        void memputs (int8_t uart, PGM_P p)               ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
        int getc (int8_t uart)                            ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
 
+       // for development
+       void putStatus (int8_t uart)                      ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
+
     uint8_t eepromReadByte (const uint8_t *p)         ATT_OPTIMIZE ATT_SECTION_BOOTLOADER __attribute__ ((naked));
        void eepromWriteByte (uint8_t *p, uint8_t value)  ATT_OPTIMIZE ATT_SECTION_BOOTLOADER __attribute__ ((naked));
 
index 289118da3a3b69c174a4a827d8f95ea242424d54..e76bab485f30cb14ced779cbc8455a40d9982e45 100644 (file)
@@ -34,6 +34,7 @@ namespace gdb {
        const char gdb_QNonStop[]           GDBMEM = "QNonStop+";
        const char gdb_QXferMemoryMapRead[] GDBMEM = "qXfer:memory-map:read+";
        const char gdb_vCont[]              GDBMEM = "$vCont;c;t;#";
+       const char gdb_StatusStop[]         GDBMEM = "\%Stop:T00thread:1;#";
        // const char gdb_QStartNoAckMode[]    GDBMEM = "QStartNoAckMode+";
        // const char gdb_QXferExecFileRead[]  GDBMEM = "qXfer:exec-file:read+";
 
@@ -167,8 +168,7 @@ namespace gdb {
        }
 
        void xputsStop () {
-               xputc('%');
-               xputc('#');
+               xputsmem(gdb_StatusStop);
        }
 
        // ATTENTION: static data not initialized when application not started !!
@@ -407,6 +407,18 @@ namespace gdb {
                                //      return;
                                // }
 
+                               case 'g': {
+                                       // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-g-packet
+                                       // Read general registers (used on gdb command load)
+                                       xputc('$');
+                                       for (i = 0; i < 78; i++) {
+                                               xputc('0');
+                                       }
+                                       // or "$0*j#"
+                                       xputc('#');
+                                       return;
+                               }
+
 
                                case 'm': {
                                        // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-m-packet
@@ -460,6 +472,7 @@ namespace gdb {
                                                        volatile uint8_t *pFrom = (volatile uint8_t *)(p->buffer + i + j + 1);
                                                        volatile uint8_t *pTo = (volatile uint8_t *)(address & 0xffff);
                                                        uint8_t addH = (address >> 16) & 0xff;
+
                                                        for (j = 0; j < l; j++) {
                                                                uint8_t vx = *pFrom++;
                                                                if (addH == 0) {
@@ -470,9 +483,9 @@ namespace gdb {
                                                                        xputsmem(gdb_OK);
                                                                        return;
                                                                }
-                                                               if ( (uint16_t)pTo >= 0x900) {
+                                                               if ( (uint16_t)pTo >= 0xf000) {
                                                                        // eeprom
-                                                                       bootloader::eepromWriteByte((uint8_t *)(pTo - 0x900), vx);
+                                                                       bootloader::eepromWriteByte((uint8_t *)(pTo - 0xf000), vx);
 
                                                                } else  if ( (uint16_t)pTo >= 0x100) {
                                                                        // sram
@@ -503,8 +516,8 @@ namespace gdb {
                                        // https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSupported-packet
                                        // Tell the remote stub about features supported by GDB, and query the stub for features it supports.
                                        xputc('$');
-                                       xputsmem(gdb_QXferMemoryMapRead);
-                                       xputc(';'); xputsmem(gdb_QNonStop);
+                                       xputsmem(gdb_QNonStop);
+                                       // xputc(';'); xputsmem(gdb_QXferMemoryMapRead);
                                        // xputc(';'); xputsmem(gdb_QStartNoAckMode);
                                        // xputc(';'); xputsmem(gdb_QXferExecFileRead);
                                        xputc('#');
@@ -617,11 +630,12 @@ namespace gdb {
                                        xputsmem(gdb_vCont);
                                        return;
 
-                               // } else if (i == 6 && sum == 0xa8) { // vCont;c
-                               //      // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet
-                               //      // Resume the inferior, specifying different actions for each thread.
-                               //      xputsmem(gdb_OK);
-                               //      return;
+                               } else if (i == 6 && sum == 0xa8) { // vCont;c
+                                       // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet
+                                       // Resume the inferior, specifying different actions for each thread.
+                                       pgdb->ctrl.proceed = 1;
+                                       xputsmem(gdb_OK);
+                                       return;
 
                                } else if (
                                           (i == 6 && sum == 0xb9)  // vCont;t (https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet  -> Resume the inferior, specifying different actions for each thread.)
@@ -634,6 +648,8 @@ namespace gdb {
                                //              case 2: gdb.ctrl.continueApplication = 1; break;
                                //              case 3: gdb.ctrl.continueInterrupts = 1; break;
                                //      }
+                                       bootloader::putStatus(0);
+                                       pgdb->ctrl.stop = 1;
                                        xputsmem(gdb_OK);
                                        return;