Commit cc422cb211074b3b5e054160cd87e5325c43f4e8
receivedSat, 20. Jul 2024, 19:46:17 (by user sx)
Sat, 20 Jul 2024 17:46:17 +0000 (19:46 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Sat, 20 Jul 2024 17:46:10 +0000 (19:46 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Sat, 20 Jul 2024 17:46:10 +0000 (19:46 +0200)
3 files changed:
software/gdb-stub/Makefile
software/gdb-stub/src/gdb.cpp
software/gdb-stub/src/gdb.h

index a595000fce02707cc99bd52d7de9d81e85e4267c..f7d4a6790470dfeed4f843c0cfee2fed010e09cb 100644 (file)
@@ -13,7 +13,7 @@ SECTION_BOOTLOADER = 0xE004
 ## Intel Hex file production flags
 HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
 
-CFLAGS = -g -DF_CPU=12000000L -Os -Wall -gdwarf-2
+CFLAGS = -g -DF_CPU=12000000L -Og -Wall -gdwarf-2
 LFLAGS = -gdwarf-2
 LFLAGS += -Wl,-Tldscripts/ldscript_atmega644p.x
 
index 711f06ba87c3387e00018f84ea9303a737f4a40e..66ad7dad06193abc27b55f4b9b0f82b4b919f12a 100644 (file)
@@ -38,6 +38,8 @@ namespace gdb {
        // const char gdb_QStartNoAckMode[]    GDBMEM = "QStartNoAckMode+";
        // const char gdb_QXferExecFileRead[]  GDBMEM = "qXfer:exec-file:read+";
 
+       const char gdb_mem[]                GDBMEM = "$l<memory-map><memory type=\"flash\" start=\"0\" length=\"0x10000\"><property name=\"blocksize\">0x100</property></memory><memory type=\"flash\" start=\"0x810000\" length=\"0x800\"><property name=\"blocksize\">0x01</property></memory></memory-map>#";
+
        // struct Gdb gdb;
        // struct Buffer buf;
 
@@ -167,9 +169,9 @@ namespace gdb {
                do {} while(1);
        }
 
-       void xputsStop () {
-               xputsmem(gdb_StatusStop);
-       }
+       // void xputsStop () {
+       //      xputsmem(gdb_StatusStop);
+       // }
 
        // ATTENTION: static data not initialized when application not started !!
        // ---> xputs('hello'); not working!!!
@@ -223,10 +225,8 @@ namespace gdb {
        // }
 
        void eraseFlash (uint16_t addressStart, uint16_t addressEnd) {
-               // do {} while ((SPMCSR & (1 << SPMEN)) == 1); // = boot_spm_busy_wait()
-               // do {} while ((EECR & (1 << EEPE)) == 1);    // = eeprom_busy_wait()
                bootloader::putln(0);
-               for (uint16_t addr = addressStart; addr < 0x7000 && addr <= addressEnd; addr += SPM_PAGESIZE) {
+               for (uint16_t addr = addressStart; addr < 0xe000 && addr <= addressEnd; addr += SPM_PAGESIZE) {
                        boot_spm_busy_wait();
                        eeprom_busy_wait();
                        boot_page_erase(addr);
@@ -243,7 +243,13 @@ namespace gdb {
                #endif
        }
 
-       void writeFlash (uint8_t *from, uint8_t size, uint16_t toPage) {
+       void writeFlash (uint16_t *from, uint8_t size, uint16_t startAddress) {
+               for (uint8_t i = 0; i < size; i += 2) {
+                       boot_page_fill(startAddress + i, *from++);
+               }
+       }
+
+       void writeFlashOld (uint8_t *from, uint8_t size, uint16_t toPage) {
                #ifdef GDB_DEBUG_UART_FLASHWRITE
                        printdbg(GDB_DEBUG_ID_FLASH_WRITE);
                #endif
@@ -311,8 +317,13 @@ namespace gdb {
                                pgdb->status.isAppStarted = 0;
                        }
 
+               } else if (pgdb->ctrl.notify && pgdb->buffer.state != idle) {
+                       pgdb->ctrl.notify = 0;
+                       pgdb->timer = 20;
+                       xputsmem(gdb_StatusStop);
+
                } else if (pgdb->ctrl.stop) {
-                       if (!pgdb->status.isStopped && pgdb->buffer.state == idle) {
+                       if (!pgdb->status.isStopped) {
                                pgdb->ctrl.stop = 0;
                                if (pgdb->status.isAppStarted) {
                                #ifdef GDB_DEBUG_UART
@@ -320,9 +331,9 @@ namespace gdb {
                                #endif
                                }
                                pgdb->status.isStopped = 1;
-                               pgdb->timer = 20;
-                               xputsStop();
+
                        }
+                       pgdb->ctrl.notify = 1;
 
                } else if (pgdb->ctrl.proceed) {
                        pgdb->ctrl.proceed = 0;
@@ -365,12 +376,14 @@ namespace gdb {
                                case '?': {
                                        // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-_003f-packet
                                        // This is sent when connection is first established to query the reason the target halted.
-                                       if (pgdb->status.isAppStarted && pgdb->status.isStopped) {
-                                               // xputsStop();
-                                               pgdb->ctrl.stop = 1; // send STOP notification
-                                       } else {
-                                               xputsmem(gdb_OK);
-                                       }
+                                       // if (pgdb->status.isAppStarted && pgdb->status.isStopped) {
+                                       //      // xputsStop();
+                                       //      pgdb->ctrl.stop = 1;
+                                       // } else {
+                                       //      xputsmem(gdb_OK);
+                                       // }
+                                       pgdb->ctrl.notify = 1;
+                                       xputsmem(gdb_OK);
                                        return;
                                }
 
@@ -526,6 +539,7 @@ namespace gdb {
                                        // Tell the remote stub about features supported by GDB, and query the stub for features it supports.
                                        xputc('$');
                                        xputsmem(gdb_QNonStop);
+                                       xputc(';'); xputsmem(gdb_QXferMemoryMapRead);
                                        xputc('#');
                                        return;
                                } else if (
@@ -595,7 +609,8 @@ namespace gdb {
                                                asm volatile (
                                                        "nop \n"
                                                );
-                                               writeFlash((uint8_t *)&p->buffer[i], p->rpos - i, (uint16_t)addressStart / SPM_PAGESIZE);
+                                               // writeFlash((uint8_t *)&p->buffer[i], p->rpos - i, (uint16_t)addressStart / SPM_PAGESIZE);
+                                               writeFlash((uint16_t *)&p->buffer[i], p->rpos - i, (uint16_t)addressStart);
                                                xputsmem(gdb_OK);
                                        }
                                        return;
@@ -642,11 +657,22 @@ namespace gdb {
                                        pgdb->ctrl.interrupt = 1;
                                        return;
 
+                               } else if (i == 22 && sum == 0x8e) { // qXfer:memory-map:read::
+                                       uint32_t address, length;
+                                       uint8_t j = parseHex(p->buffer, i + 1, &address);
+                                       if (j > 0 && p->buffer[i + j + 1] == ',') {
+                                               j = parseHex(p->buffer, i + j + 2, &length);
+                                               if (j > 0) {
+                                                       xputsmem(gdb_mem);
+                                                       return;
+                                               }
+                                       }
+
                                } else  {
-                                       // bootloader::putnc(0, c, 1);
-                                       // bootloader::putnc(0, ' ', 1); bootloader::putUint8Hex(0, i);
-                                       // bootloader::putnc(0, ' ',2); bootloader::putUint8Hex(0, sum);
-                                       // bootloader::putln(0);
+                                       bootloader::putnc(0, c, 1);
+                                       bootloader::putnc(0, ' ', 1); bootloader::putUint8Hex(0, i);
+                                       bootloader::putnc(0, ' ',2); bootloader::putUint8Hex(0, sum);
+                                       bootloader::putln(0);
                                }
 
                        }
@@ -706,12 +732,12 @@ namespace gdb {
                struct Buffer *pbuf = &pgdb->buffer;
                bootloader::printChar(gdboutUart, c);
                switch (c) {
-                       case '$': pbuf->chkSumToGdb = 0; pgdb->status.sendingNotification = 0; break;
-                       case '%': pbuf->chkSumToGdb = 0; pgdb->status.sendingNotification = 1; break;
+                       case '$': pbuf->chkSumToGdb = 0; pgdb->status.isSendingNotification = 0; break;
+                       case '%': pbuf->chkSumToGdb = 0; pgdb->status.isSendingNotification = 1; break;
                        case '#': {
                                gputc(dec2hex((pbuf->chkSumToGdb >> 4) & 0x0f));
                                gputc(dec2hex(pbuf->chkSumToGdb & 0x0f));
-                               if (!pgdb->status.sendingNotification ) {
+                               if (!pgdb->status.isSendingNotification ) {
                                        pbuf->state = waitack;
                                }
                                break;
index 702c6ebaabc5b637523cc05aea6aa93df94b62ba..eb6217596094d64315ab594d2e8f06fda06ba0d3 100644 (file)
@@ -27,12 +27,12 @@ namespace gdb {
 
 
        struct Status { // (gdb) print *((struct gdb::Status *)0x8010fb)
-               uint8_t errorFlags;             // @0x18fb
-               uint8_t isConnected:1;          // @0x18fc.0x01, address used in bootloader::jmpTableGdbStopApplication()
-               uint8_t isAppStarted:1;         // @0x18fc.0x02
-               uint8_t isStopped:1;            // @0x18fc.0x04
-               uint8_t isBreakpointValid:1;    // @0x18fc.0x08
-               uint8_t sendingNotification:1;  // @0x18fc.0x10
+               uint8_t errorFlags;               // @0x18fb
+               uint8_t isConnected:1;            // @0x18fc.0x01, address used in bootloader::jmpTableGdbStopApplication()
+               uint8_t isAppStarted:1;           // @0x18fc.0x02
+               uint8_t isStopped:1;              // @0x18fc.0x04
+               uint8_t isBreakpointValid:1;      // @0x18fc.0x08
+               uint8_t isSendingNotification:1;  // @0x18fc.0x10
        };
 
        struct Control { // (gdb) print *((struct gdb::Control *)0x8010fd)
@@ -43,13 +43,9 @@ namespace gdb {
                uint8_t kill:1;        // @0x18fd.0x10
                uint8_t start:1;       // @0x18fd.0x20
                uint8_t reset:1;       // @0x18fd.0x40
+               uint8_t notify:1;      // @0x18fd.0x80
        };
 
-       // struct Notify {
-       //      uint8_t timer;
-       //      uint8_t stop:1;
-       // };
-
        struct Buffer {
                enum BufferState state;
                uint8_t rpos;
@@ -92,7 +88,8 @@ namespace gdb {
        void saveBreakpointRegs (struct Breakpoint *p)                    ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
        void checkByteFromGdb ()                                          ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
        void eraseFlash (uint16_t addressStart, uint16_t addressEnd)      ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
-       void writeFlash (uint8_t *from, uint8_t size, uint16_t toPage)    ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
+       void writeFlashOld (uint8_t *from, uint8_t size, uint16_t toPage)    ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
+       void writeFlash (uint16_t *from, uint8_t size, uint16_t startAddress) ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
        uint16_t updateModbusCRC (uint16_t crc, uint8_t b)                ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
        uint16_t flashCrc (uint16_t startAddress, uint16_t endAddress)    ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
        uint8_t createFlashCrc (PGM_P startAddress, size_t size)          ATT_OPTIMIZE_GDB ATT_SECTION_GDB;