From 19a6c0114d3290035fc00e0914457706916dd343 Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Mon, 22 Jul 2024 17:44:51 +0200 Subject: [PATCH] vFlashWrite/vFlashDone working, no vector table in bootloader area --- software/gdb-stub/.gdbinit | 16 ++- software/gdb-stub/.gdbinit-gdbstub | 6 +- software/gdb-stub/src/bootloader.cpp | 15 ++ software/gdb-stub/src/gdb.cpp | 207 ++++++++++++++------------- software/gdb-stub/src/gdb.h | 14 +- 5 files changed, 151 insertions(+), 107 deletions(-) diff --git a/software/gdb-stub/.gdbinit b/software/gdb-stub/.gdbinit index cc62ea0..760ad8e 100644 --- a/software/gdb-stub/.gdbinit +++ b/software/gdb-stub/.gdbinit @@ -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 diff --git a/software/gdb-stub/.gdbinit-gdbstub b/software/gdb-stub/.gdbinit-gdbstub index f01898e..838e6f3 100644 --- a/software/gdb-stub/.gdbinit-gdbstub +++ b/software/gdb-stub/.gdbinit-gdbstub @@ -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 diff --git a/software/gdb-stub/src/bootloader.cpp b/software/gdb-stub/src/bootloader.cpp index cab6c1b..b646299 100644 --- a/software/gdb-stub/src/bootloader.cpp +++ b/software/gdb-stub/src/bootloader.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #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 ); diff --git a/software/gdb-stub/src/gdb.cpp b/software/gdb-stub/src/gdb.cpp index 61978e2..20ee10c 100644 --- a/software/gdb-stub/src/gdb.cpp +++ b/software/gdb-stub/src/gdb.cpp @@ -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 = "$l0x100'0x01#"; - const char gdb_mem[] GDBMEM = "$l0x100'#"; + // const char gdb_mem[] GDBMEM = "$l0x100'0x01#"; + // const char gdb_mem[] GDBMEM = "$l0x100'#"; + const char gdb_mem[] GDBMEM = "$l0x80'#"; // 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; diff --git a/software/gdb-stub/src/gdb.h b/software/gdb-stub/src/gdb.h index c8dc84e..56c4a95 100644 --- a/software/gdb-stub/src/gdb.h +++ b/software/gdb-stub/src/gdb.h @@ -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; -- 2.39.5