// 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;
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!!!
// }
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);
#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
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
#endif
}
pgdb->status.isStopped = 1;
- pgdb->timer = 20;
- xputsStop();
+
}
+ pgdb->ctrl.notify = 1;
} else if (pgdb->ctrl.proceed) {
pgdb->ctrl.proceed = 0;
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;
}
// 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 (
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;
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);
}
}
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;
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)
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;
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;