From: Manfred Steiner <sx@htl-kaindorf.at>
Date: Sat, 20 Jul 2024 17:46:10 +0000 (+0200)
Subject: ...
X-Git-Url: https://git.htl-mechatronik.at/public/?a=commitdiff_plain;h=cc422cb211074b3b5e054160cd87e5325c43f4e8;p=nano-x.git

...
---

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 = "$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;
 
@@ -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;