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;
// 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
#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;
xputc('$');
xputsmem(gdb_QNonStop);
xputc(';'); xputsmem(gdb_QXferMemoryMapRead);
+ xputc(';'); xputsmem(gdb_PacketSize);
xputc('#');
return;
} else if (
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;
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;