From cc422cb211074b3b5e054160cd87e5325c43f4e8 Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Sat, 20 Jul 2024 19:46:10 +0200 Subject: [PATCH] ... --- software/gdb-stub/Makefile | 2 +- software/gdb-stub/src/gdb.cpp | 74 +++++++++++++++++++++++------------ software/gdb-stub/src/gdb.h | 21 +++++----- 3 files changed, 60 insertions(+), 37 deletions(-) diff --git a/software/gdb-stub/Makefile b/software/gdb-stub/Makefile index a595000..f7d4a67 100644 --- a/software/gdb-stub/Makefile +++ b/software/gdb-stub/Makefile @@ -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 diff --git a/software/gdb-stub/src/gdb.cpp b/software/gdb-stub/src/gdb.cpp index 711f06b..66ad7da 100644 --- a/software/gdb-stub/src/gdb.cpp +++ b/software/gdb-stub/src/gdb.cpp @@ -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 = "$l0x1000x01#"; + // 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; diff --git a/software/gdb-stub/src/gdb.h b/software/gdb-stub/src/gdb.h index 702c6eb..eb62175 100644 --- a/software/gdb-stub/src/gdb.h +++ b/software/gdb-stub/src/gdb.h @@ -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; -- 2.39.5