Commit 19a6c0114d3290035fc00e0914457706916dd343
receivedMon, 22. Jul 2024, 17:44:58 (by user sx)
Mon, 22 Jul 2024 15:44:58 +0000 (17:44 +0200)
authorManfred Steiner <sx@htl-kaindorf.at>
Mon, 22 Jul 2024 15:44:51 +0000 (17:44 +0200)
committerManfred Steiner <sx@htl-kaindorf.at>
Mon, 22 Jul 2024 15:44:51 +0000 (17:44 +0200)
5 files changed:
software/gdb-stub/.gdbinit
software/gdb-stub/.gdbinit-gdbstub
software/gdb-stub/src/bootloader.cpp
software/gdb-stub/src/gdb.cpp
software/gdb-stub/src/gdb.h

index cc62ea0b6f13a6162945abeb64727d053a52e98e..760ad8e353f1e9b51c1cc45c4dabcbfb6b48b57a 100644 (file)
@@ -6,10 +6,18 @@
 alias _reset = set *((uint8_t *)0x8010fd) = 0x40
 alias _startapp = set *((uint8_t *)0x8010fd) = 0x20
 alias _killapp = set *((uint8_t *)0x8010fd) = 0x10
-alias _status = print  ((gdb::Gdb *)0x801039)->status
-alias _ctrl = print ((gdb::Gdb *)0x801039)->ctrl
-alias _breakpoint = print ((gdb::Gdb *)0x801039)->breakpoint
-alias _gdb = print *((gdb::Gdb *)0x801039)
+#alias _status = print  ((gdb::Gdb *)0x801039)->status
+#alias _ctrl = print ((gdb::Gdb *)0x801039)->ctrl
+#alias _breakpoint = print ((gdb::Gdb *)0x801039)->breakpoint
+#alias _buffer = print ((gdb::Gdb *)0x801039)->buffer
+#alias _gdb = print *((gdb::Gdb *)0x801039)
+
+alias _status = print ((gdb::Gdb *)0x800f8c)->status
+alias _ctrl = print ((gdb::Gdb *)0x800f8c)->ctrl
+alias _breakpoint = print ((gdb::Gdb *)0x800f8c)->breakpoint
+alias _buffer = print ((gdb::Gdb *)0x800f8c)->buffer
+alias __gdb = print ((gdb::Gdb *)0x800f8c)
+alias _gdb = print *((gdb::Gdb *)0x800f8c)
 
 set print pretty
 set history save on
index f01898ed1c667cfa9aeef30f3f58a33b39337fe2..838e6f332d57870545500b3996bbab43dccc36b5 100644 (file)
@@ -1,5 +1,9 @@
 target remote :1234
 layout split
 focus cmd
-br *0
+#br *0
+#br gdb.cpp:296
+#br gdb.cpp:317
+#br gdb.cpp:325
+br bootloader.cpp:150
 
index cab6c1bdd5afb15b1941ac664c71bd45c6ba8531..b6462990c8bffb9b1d10a0ab5ea0c6cf42396a59 100644 (file)
@@ -4,6 +4,7 @@
 #include <avr/io.h>
 #include <avr/pgmspace.h>
 #include <avr/wdt.h>
+#include <avr/interrupt.h>
 
 #include "bootloader.h"
 #include "gdb.h"
@@ -147,7 +148,21 @@ namespace bootloader {
                        #ifdef SIMAVR
                                main();
                        #else
+                               cli();
                                setLedGreen(1); setLedOrange(0); setLedRed(0);
+                               UCSR0A = 0;
+                               UCSR0B = 0;
+                               UCSR0C = 0;
+                               UCSR1A = 0;
+                               UCSR1B = 0;
+                               UCSR1C = 0;
+                               UBRR0L = 0;
+                               UBRR0H = 0;
+                               UBRR1L = 0;
+                               UBRR1H = 0;
+                               TCCR1A = 0;
+                               TCCR1B = 0;
+
                                asm volatile (
                                        "jmp 0x0000" // start application
                                );
index 61978e26a3806501a3619c96127c0dcdf346f83d..20ee10c581b270a07dfb6e04c8c8cc16e4ba21ba 100644 (file)
@@ -34,13 +34,15 @@ namespace gdb {
        const char gdb_E00[]                GDBMEM = "$E00#";
        const char gdb_QNonStop[]           GDBMEM = "QNonStop+";
        const char gdb_QXferMemoryMapRead[] GDBMEM = "qXfer:memory-map:read+";
+       const char gdb_PacketSize[]         GDBMEM = "PacketSize=128";
        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+";
 
-       //const char gdb_mem[]                GDBMEM = "$l<memory-map><memory type=\"flash\" start=\"0\" length=\"0x10000\"><property name=\"blocksize\">0x100</property></memory><memory type=\"ram\" start=\"0x800000\" length=\"0x1100\"/>'<memory type=\"flash\" start=\"0x810000\" length=\"0x800\"><property name=\"blocksize\">0x01</property></memory></memory-map>#";
-       const char gdb_mem[]                GDBMEM = "$l<memory-map><memory type=\"flash\" start=\"0\" length=\"0x10000\"><property name=\"blocksize\">0x100</property></memory><memory type=\"ram\" start=\"0x800000\" length=\"0x1100\"/>'<memory type=\"ram\" start=\"0x810000\" length=\"0x800\"/></memory-map>#";
+       // const char gdb_mem[]                GDBMEM = "$l<memory-map><memory type=\"flash\" start=\"0\" length=\"0x10000\"><property name=\"blocksize\">0x100</property></memory><memory type=\"ram\" start=\"0x800000\" length=\"0x1100\"/>'<memory type=\"flash\" start=\"0x810000\" length=\"0x800\"><property name=\"blocksize\">0x01</property></memory></memory-map>#";
+       // const char gdb_mem[]                GDBMEM = "$l<memory-map><memory type=\"flash\" start=\"0\" length=\"0x10000\"><property name=\"blocksize\">0x100</property></memory><memory type=\"ram\" start=\"0x800000\" length=\"0x1100\"/>'<memory type=\"ram\" start=\"0x810000\" length=\"0x800\"/></memory-map>#";
+       const char gdb_mem[]                GDBMEM = "$l<memory-map><memory type=\"flash\" start=\"0\" length=\"0x10000\"><property name=\"blocksize\">0x80</property></memory><memory type=\"ram\" start=\"0x800000\" length=\"0x1100\"/>'<memory type=\"ram\" start=\"0x810000\" length=\"0x800\"/></memory-map>#";
 
        // struct Gdb gdb;
        // struct Buffer buf;
@@ -229,7 +231,7 @@ namespace gdb {
        //      return crc;
        // }
 
-       void eraseFlash (uint16_t addressStart, int32_t length) {
+       void flashErase (uint16_t addressStart, int32_t length) {
                #ifndef __AVR_ATmega644P__
                        #error wrong CPU -> check end of application flash area
                #else
@@ -259,117 +261,132 @@ namespace gdb {
                #endif
        }
 
-       void writeFlash (uint16_t *from, uint8_t size, uint16_t startAddress) {
-               #ifndef __AVR_ATmega644P__
-                       #error wrong CPU -> check end of application flash area
+       void flashWrite () {
+               #ifdef __AVR_ATmega644P__
+                       #define MEM_BOOTLOADER_START 0xe000
                #else
-                       // 0xffff - 0x2000 (bootloader size)
-                       #define MEM_APP_END 0xdfff
+                       #error wrong CPU -> check MEM_BOOTLOADER_START
                #endif
                struct gdb::Gdb *pgdb = GDB_PTR;
-               if (size <= 0 || startAddress > MEM_APP_END) {
-                       return;
-               }
-
-               if (pgdb->status.flashPage < 0) {
-                       pgdb->status.flashPage = startAddress / SPM_PAGESIZE;
+               if (pgdb->status.flashPage >= 0 && (uint16_t)pgdb->status.flashPage < (MEM_BOOTLOADER_START / SPM_PAGESIZE)) {
+                       uint16_t address = pgdb->status.flashPage * SPM_PAGESIZE;
+                       uint16_t *p = (uint16_t *)RAMSTART;
+                       for (uint16_t i = 0; i < SPM_PAGESIZE; i += 2) {
+                               boot_page_fill(address + i, p[i / 2]);
+                       }
+                       boot_page_write(address);
+                       boot_spm_busy_wait();
                        #ifdef GDB_DEBUG_UART_FLASHWRITE
-                               printdbg(GDB_DEBUG_ID_FLASH_WRITE);
+                               bootloader::printChar(GDB_DEBUG_UART, ' ');
+                               bootloader::printChar(GDB_DEBUG_UART, 'W');
+                               bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(address >> 8));
+                               bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(address));
                        #endif
+
                }
+               pgdb->status.flashPage = -1;
+       }
 
-               uint16_t address = startAddress;
-               for (uint8_t i = 0; i < size &&  address <= MEM_APP_END; i += 2, address += 2) {
-                       if ( (int16_t)(address / SPM_PAGESIZE) != pgdb->status.flashPage) {
-                               boot_page_write(pgdb->status.flashPage * SPM_PAGESIZE);
-                               #ifdef GDB_DEBUG_UART_FLASHWRITE
-                                       bootloader::printChar(GDB_DEBUG_UART, ' ');
-                                       bootloader::printChar(GDB_DEBUG_UART, 'W');
-                                       bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)pgdb->status.flashPage);
-                               #endif
-                               boot_spm_busy_wait();
-                               pgdb->status.flashPage = address / SPM_PAGESIZE;
-                       }
-                       boot_page_fill(address, *from++);
+       void flashFill (uint8_t *from, uint16_t size, uint16_t startAddress) {
+               #ifdef __AVR_ATmega644P__
+                       #define MEM_BOOTLOADER_START 0xe000
+               #else
+                       #error wrong CPU -> check MEM_BOOTLOADER_START
+               #endif
+               struct gdb::Gdb *pgdb = GDB_PTR;
+               if (size <= 0 || startAddress >= MEM_BOOTLOADER_START) {
+                       return;
                }
+
                #ifdef GDB_DEBUG_UART_FLASHWRITE
                        bootloader::printChar(GDB_DEBUG_UART, ' ');
                        bootloader::printChar(GDB_DEBUG_UART, 'F');
                        bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(startAddress >> 8));
-                       bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(startAddress));
+                       bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)startAddress);
                        bootloader::printChar(GDB_DEBUG_UART, '-');
-                       bootloader::putUint8Hex(GDB_DEBUG_UART, size);
+                       bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(size >> 8));
+                       bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)size);
                #endif
+
+               uint8_t *p = (uint8_t *)RAMSTART;
+               uint16_t address = startAddress;
+               for (uint16_t i = 0; i < size; i++, address++) {
+                       uint16_t page = address / SPM_PAGESIZE;
+                       if (pgdb->status.flashPage >= 0 && page != (uint16_t)pgdb->status.flashPage) {
+                               flashWrite();
+                               p = (uint8_t *)RAMSTART;
+                       }
+                       if (pgdb->status.flashPage < 0) {
+                               pgdb->status.flashPage = address / SPM_PAGESIZE;
+                               for (uint16_t j = 0; j < SPM_PAGESIZE; j++) {
+                                       p[j] = 0xff;
+                               }
+                       }
+                       *p++ = *from++;
+               }
+
        }
 
-       void writeFlashDone () {
+       void flashFinish () {
                struct gdb::Gdb *pgdb = GDB_PTR;
-               if (pgdb->status.flashPage < 0) {
-                       return;
+               if (pgdb->status.flashPage >= 0) {
+                       flashWrite();
                }
-               #ifdef GDB_DEBUG_UART_FLASHWRITE
-                       bootloader::printChar(GDB_DEBUG_UART, ' ');
-                       bootloader::printChar(GDB_DEBUG_UART, 'W');
-                       bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)pgdb->status.flashPage);
-               #endif
-               boot_page_write(pgdb->status.flashPage * SPM_PAGESIZE);
-               boot_spm_busy_wait();
                boot_rww_enable();
                #ifdef GDB_DEBUG_UART_FLASHWRITE
                        bootloader::printChar(GDB_DEBUG_UART, ' ');
                        bootloader::printChar(GDB_DEBUG_UART, '@');
                        bootloader::putln(GDB_DEBUG_UART);
                #endif
-               pgdb->status.flashPage = -1;
        }
 
-       void writeFlashOld (uint8_t *from, uint8_t size, uint16_t toPage) {
-               #ifdef GDB_DEBUG_UART_FLASHWRITE
-                       printdbg(GDB_DEBUG_ID_FLASH_WRITE);
-               #endif
-               uint8_t i;
-               for (i = size; i < SPM_PAGESIZE; i++ ) {
-                       from[i] = 0xff;
-               }
-               uint16_t toAddress = (toPage * SPM_PAGESIZE);
-               for (i = 0; i < SPM_PAGESIZE; i++ ) {
-                       uint8_t bFrom = pgm_read_byte((PGM_P)(toAddress + i));
-                       if (bFrom != from[i]) {
-                               break;
-                       }
-               }
-               if (i < SPM_PAGESIZE) {
-                       #ifdef GDB_DEBUG_UART_FLASHERASE
-                               printdbg(GDB_DEBUG_ID_FLASH_ERASE);
-                               bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(toAddress >> 8));
-                               bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(toAddress));
-                               #endif
-                       eeprom_busy_wait();
-                       boot_page_erase(toAddress);
-                       boot_spm_busy_wait();
-                       for (i = 0; i < SPM_PAGESIZE; i += 2) {
-                               uint16_t w = *from++;
-                               w += (*from++) << 8;
-                               boot_page_fill(toAddress + i, w);
-                               #ifdef GDB_DEBUG_UART_FLASHWRITE
-                                       bootloader::printChar(GDB_DEBUG_UART, ' ');
-                                       bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(w >> 8));
-                                       bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(w));
-                               #endif
-                       }
-                       boot_page_write(toAddress);
-                       #ifdef GDB_DEBUG_UART_FLASHWRITE
-                               bootloader::printChar(GDB_DEBUG_UART, 'W');
-                       #endif
-                       boot_spm_busy_wait();
-               }
+       // void writeFlashOld (uint8_t *from, uint8_t size, uint16_t toPage) {
+       //      #ifdef GDB_DEBUG_UART_FLASHWRITE
+       //              printdbg(GDB_DEBUG_ID_FLASH_WRITE);
+       //      #endif
+       //      uint8_t i;
+       //      for (i = size; i < SPM_PAGESIZE; i++ ) {
+       //              from[i] = 0xff;
+       //      }
+       //      uint16_t toAddress = (toPage * SPM_PAGESIZE);
+       //      for (i = 0; i < SPM_PAGESIZE; i++ ) {
+       //              uint8_t bFrom = pgm_read_byte((PGM_P)(toAddress + i));
+       //              if (bFrom != from[i]) {
+       //                      break;
+       //              }
+       //      }
+       //      if (i < SPM_PAGESIZE) {
+       //              #ifdef GDB_DEBUG_UART_FLASHERASE
+       //                      printdbg(GDB_DEBUG_ID_FLASH_ERASE);
+       //                      bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(toAddress >> 8));
+       //                      bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(toAddress));
+       //                      #endif
+       //              eeprom_busy_wait();
+       //              boot_page_erase(toAddress);
+       //              boot_spm_busy_wait();
+       //              for (i = 0; i < SPM_PAGESIZE; i += 2) {
+       //                      uint16_t w = *from++;
+       //                      w += (*from++) << 8;
+       //                      boot_page_fill(toAddress + i, w);
+       //                      #ifdef GDB_DEBUG_UART_FLASHWRITE
+       //                              bootloader::printChar(GDB_DEBUG_UART, ' ');
+       //                              bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(w >> 8));
+       //                              bootloader::putUint8Hex(GDB_DEBUG_UART, (uint8_t)(w));
+       //                      #endif
+       //              }
+       //              boot_page_write(toAddress);
+       //              #ifdef GDB_DEBUG_UART_FLASHWRITE
+       //                      bootloader::printChar(GDB_DEBUG_UART, 'W');
+       //              #endif
+       //              boot_spm_busy_wait();
+       //      }
 
-               #ifdef GDB_DEBUG_UART_FLASHWRITE
-                       bootloader::printChar(GDB_DEBUG_UART, '@');
-                       bootloader::putln(GDB_DEBUG_UART);
-               #endif
+       //      #ifdef GDB_DEBUG_UART_FLASHWRITE
+       //              bootloader::printChar(GDB_DEBUG_UART, '@');
+       //              bootloader::putln(GDB_DEBUG_UART);
+       //      #endif
 
-       }
+       // }
 
        void executeControl () {
                struct gdb::Gdb *pgdb = GDB_PTR;
@@ -612,6 +629,7 @@ namespace gdb {
                                        xputc('$');
                                        xputsmem(gdb_QNonStop);
                                        xputc(';'); xputsmem(gdb_QXferMemoryMapRead);
+                                       xputc(';'); xputsmem(gdb_PacketSize);
                                        xputc('#');
                                        return;
                                } else if (
@@ -659,12 +677,12 @@ namespace gdb {
                                        i += parseHex(p->buffer, i, &length);
                                        pgdb->ctrl.kill = 1;
                                        executeControl();
-                                       eraseFlash((uint16_t)addressStart, (int32_t)length);
+                                       flashErase((uint16_t)addressStart, (int32_t)length);
                                        xputsmem(gdb_OK);
                                        return;
 
                                } else if (i == 9 && sum == 0xea) { // vFlashDone
-                                       writeFlashDone();
+                                       flashFinish();
                                        xputsmem(gdb_OK);
                                        return;
 
@@ -672,16 +690,13 @@ namespace gdb {
                                        pgdb->ctrl.kill = 1;
                                        executeControl();
                                        uint8_t i = 12;
-                                       uint32_t addressStart;
-                                       i += parseHex(p->buffer, i, &addressStart);
-                                       if (p->buffer[i++] != ':') {
+                                       uint32_t address;
+                                       uint8_t size = parseHex(p->buffer, i, &address);
+                                       i += size;
+                                       if (size <= 0 || p->buffer[i++] != ':') {
                                                xputsmem(gdb_E00);
                                        } else {
-                                               asm volatile (
-                                                       "nop \n"
-                                               );
-                                               // 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);
+                                               flashFill((uint8_t *)&p->buffer[i], p->rpos - i, (uint16_t)address);
                                                xputsmem(gdb_OK);
                                        }
                                        return;
index c8dc84e349e52b6c0d7f4b45bf7ba9c96d072cd2..56c4a95dc4b2bf53b540c22827306b0f6297af62 100644 (file)
@@ -22,7 +22,8 @@
 
 namespace gdb {
 
-       const uint8_t BUFFER_SIZE = 13 + 5 + 128 + 3; // "$vFlashWrite:" + "ffff:" + 128 Bytes  + "#00"
+       //const uint8_t BUFFER_SIZE = 13 + 5 + 128 + 3; // "$vFlashWrite:" + "ffff:" + 128 Bytes  + "#00"
+       const uint16_t BUFFER_SIZE = 13 + 5 + 300 + 3; // "$vFlashWrite:" + "ffff:" + 128 Bytes  + "#00"
 
        enum BufferState { idle = 0, data, esc, chk1, chk2, chk2err, exec, execerr, send, waitack };
 
@@ -50,7 +51,7 @@ namespace gdb {
 
        struct Buffer { // (gdb) print ((gdb::Gdb *)0x801039)->buffer
                enum BufferState state;
-               uint8_t rpos;
+               uint16_t rpos;
                uint8_t chkSumFromGdb;
                uint8_t chkSumToGdb;
                char    buffer[BUFFER_SIZE];
@@ -88,10 +89,11 @@ namespace gdb {
        // void restart ()                                                   ATT_OPTIMIZE_GDB ATT_SECTION_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, int32_t length)           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;
-       void writeFlashDone ()                                                ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
+       //void writeFlashOld (uint8_t *from, uint8_t size, uint16_t toPage)    ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
+       void flashErase (uint16_t addressStart, int32_t length)           ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
+       void flashFill (uint8_t *from, uint16_t size, uint16_t address)   ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
+       void flashWrite ()                                                ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
+       void flashFinish ()                                               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;