# start gdb with:
-# avr-gdb -nx -x .gdbinit-sim `-ex="target remote $(cat /tmp/sim-megaavr-atmega644p-uart1)"
-# avr-gdb -nx -x .gdbinit-nano
+# avr-gdb -x .gdbinit-gdbstub
+# avr-gdb -x .gdbinit-sim `-ex="target remote $(cat /tmp/sim-megaavr-atmega644p-uart1)"
+# avr-gdb -x .gdbinit-nano
-alias reset = set *((uint8_t *)0x8010fd) = 0x40
-alias startapp = set *((uint8_t *)0x8010fd) = 0x20
-alias killapp = set *((uint8_t *)0x8010fd) = 0x10
-alias gdbstatus = print *((struct gdb::Status *)0x8010fb)
-alias gdbctrl = print *((struct gdb::Control *)0x8010fd)
-alias gdbbreakpoint = print *((struct gdb::Breakpoint *)0x8010d7)
+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)
+set print pretty
set history save on
set history size unlimited
set history remove-duplicates unlimited
set pagination off
-#set non-stop 1
-file dist/gdb-stub_atmega644p.elf
-set serial baud 115200
-#target remote /dev/pts/19
-#target remote /dev/ttyUSB1
+file dist/gdb-stub_atmega644p.elf
// #define GLOBAL_GDB_UART0
#define GLOBAL_GDB_UART1
-// #define ATT_SECTION_BOOTLOADER
-// __attribute__((optimize("O0")))
#define ATT_SECTION_APP_START __attribute__((section(".app_start"))) __attribute__((strong))
-// extern const char BOOTLOADER_MSG[] BOOTLOADERMEM_0 = "gdb-stub V0.1";
-// extern const char BOOTLOADER_MSG_SEP1[] BOOTLOADERMEM_1 = " (";
-// extern const char BOOTLOADER_MSG_DATE[] BOOTLOADERMEM_2 = __DATE__;
-// extern const char BOOTLOADER_MSG_SEP2[] BOOTLOADERMEM_3 = ",";
-// extern const char BOOTLOADER_MSG_TIME[] BOOTLOADERMEM_4 = __TIME__;
-// extern const char BOOTLOADER_MSG_END[] BOOTLOADERMEM_5 = ")\0";
-
extern const char BOOTLOADER_MSG_TEXT[] BOOTLOADERMEM_0 = "gdb-stub V0.1";
-// const char BOOTLOADER_MSG_SEP1[] PROGMEM = " (";
extern const char BOOTLOADER_MSG_DATE[] BOOTLOADERMEM_1 = __DATE__;
-// const char BOOTLOADER_MSG_SEP2[] PROGMEM = ",";
extern const char BOOTLOADER_MSG_TIME[] BOOTLOADERMEM_2 = __TIME__;
-// const char BOOTLOADER_MSG_END[] PROGMEM = ")";
uint8_t eeprom[1] __attribute__((section(".eeprom"))) = { 0x80 };
uint8_t fusex[3] __attribute__((section(".fuse"))) = { 0xe7, 0xd8, 0xff };
extern int main ();
-
-
-
namespace bootloader {
void __attribute__ ((naked)) bootloaderStart () {
}
void __attribute__((naked)) bootloaderStartFromReset () {
- asm volatile (
+ #ifndef __AVR_ATmega644P__
+ #error wrong CPU, fix RAMEND
+ #endif
+ __asm__ (
+ ".equ RAMEND, 0x10ff \n"
"__bootloader_start_from_reset: \n"
"eor r1, r1 \n"
"out 0x3f, r1 \n" // SREG = 0
- "ldi r28, 0xFF \n" // reset SP to 0x01ff (RAMEND for Atmega644p)
- "ldi r29, 0x10 \n"
+ //"ldi r28, 0xFF \n" // reset SP to 0x01ff (RAMEND for Atmega644p)
+ // "ldi r29, 0x10 \n"
+ "ldi r28, lo8(RAMEND) \n" // reset SP to 0x01ff (RAMEND for Atmega644p)
+ "ldi r29, hi8(RAMEND) \n"
"out 0x3e, r29 \n" // SPH = 0x08
"out 0x3d, r28 \n" // SPL = 0xFF
"nop \n"
gdb::handleUartIsrByte(UDR1);
}
- // void jmpTablePutc (char c) {
- // asm volatile (
- // "__bootloader_putc: \n"
- // );
- // putc(stdoutUart, c);
- // }
-
void jmpTablePuts (const char *s) {
asm volatile (
"__bootloader_puts: \n"
void bootloaderLoop () {
- // asm volatile (
- // "__bootloader_loop: \n"
- // );
- // init();
-
#ifdef SIMAVR
eepromWriteByte(0, 0x80);
#else
);
}
- // void __attribute__((naked)) bootloaderInit () {
- // asm volatile (
- // "eor r1, r1 \n"
- // "out 0x3f, r1 \n" // SREG = 0
- // "pop r23 \n" // return address to r23:r22
- // "pop r22 \n"
- // "ldi r28, 0xFF \n" // reset SP to 0x08ff (RAMEND)
- // "ldi r29, 0x08 \n"
- // "out 0x3e, r29 \n" // SPH = 0x08
- // "out 0x3d, r28 \n" // SPL = 0xFF
- // );
- // bootloaderInit2 (sizeof(struct gdb::Gdb));
- // }
-
void __attribute__((naked)) bootloaderInit (size_t gdbSize) {
+ #ifndef __AVR_ATmega644P__
+ #error wrong CPU -> check SPH, SPL
+ #endif
asm volatile (
- " pop r23 \n" // get two return addresses from stack
- " pop r22 \n"
- " pop r21 \n"
- " pop r20 \n"
-
- " movw r26, r28 \n"
- " ldi r30,0xfe \n" // gdb.magic
- " st X, r30 \n"
- " ldi r30,0x01 \n" // gdb.version
- " st -X, r30 \n"
-
- " sub r28, r24 \n" // allocate struct Gdb on stack
- " sbc r29, r25 \n"
- " out 0x3e, r29 \n" // SPH = ...
- " out 0x3d, r28 \n" // SPL = ...
-
- "loop: st Y+, r1 \n" // initialize struct Gdb
- " cp r28, r26 \n"
- " cpc r29, r27 \n"
- " brne loop \n"
-
- " push r20 \n" // restore the two return addresses on stack
- " push r21 \n"
- " push r22 \n"
- " push r23 \n"
+ " .equ SPH, 0x3e \n"
+ " .equ SPL, 0x3d \n"
+ " pop r23 \n" // get two return addresses from stack
+ " pop r22 \n"
+ " pop r21 \n"
+ " pop r20 \n"
+
+ " movw r26, r28 \n"
+ " ldi r30, 0xfe \n" // gdb.magic
+ " st X, r30 \n"
+ " ldi r30,0x01 \n" // gdb.version
+ " st -X, r30 \n"
+
+ " sub r28, r24 \n" // allocate struct Gdb on stack
+ " sbc r29, r25 \n"
+ " out SPH, r29 \n" // SPH = ...
+ " out SPL, r28 \n" // SPL = ...
+
+ "loop: st Y+, r1 \n" // initialize struct Gdb
+ " cp r28, r26 \n"
+ " cpc r29, r27 \n"
+ " brne loop \n"
+
+ " push r20 \n" // restore the two return addresses on stack
+ " push r21 \n"
+ " push r22 \n"
+ " push r23 \n"
);
// disable watchdog (maybe enabled from restart command)
}
void __attribute__((naked)) jmpTableGdbStopApplication () {
- // void jmpTableGdbStopApplication () {
+ #ifndef __AVR_ATmega644P__
+ #error wrong CPU -> check RAMEND, SFR
+ #endif
asm volatile (
- "__gdb_stopApplication: \n"
- "push r25 \n" // save r25 (used for address of gdb::gdb.breakpoint)
- "lds r25, 0x10fc \n" // gdb.status
- "andi r25, 0x01 \n" // gdb.status.isConnected
+ ".equ RAMEND, 0x10ff \n"
+ ".equ SFR, 0x3f \n"
+ "__gdb_stopApplication: \n"
+ "push r25 \n" // save r25 (used for address of gdb::gdb.breakpoint)
+ "lds r25, RAMEND - 3 \n" // gdb.status
+ "andi r25, 0x01 \n" // gdb.status.isConnected
"breq __gdb_stopApplication_end \n"
- "in r25, 0x3f \n" // SFR -> r25
- "cli \n" // disable interrupts while saveBreakpoints()
- "push r25 \n" // save original SFR
- "push r24 \n" // save parameter register
+ "in r25, SFR \n" // SFR -> r25
+ "cli \n" // disable interrupts while saveBreakpoints()
+ "push r25 \n" // save original SFR
+ "push r24 \n" // save parameter register
);
gdb::saveBreakpointRegs(GDB_BREAKPOINT_PTR);
struct gdb::Gdb *pgdb = GDB_PTR;
);
gdb::stopApplication();
asm volatile (
- "pop r25 \n" // restore SFR
- "out 0x3f, r25 \n"
+ ".equ SFR, 0x3f \n"
+ "pop r25 \n" // restore SFR
+ "out SFR, r25 \n"
"__gdb_stopApplication_end: \n"
- "pop r25 \n" // restore r25
- "ret \n"
+ "pop r25 \n" // restore r25
+ "ret \n"
);
}
UCSR1B = (1 << TXEN1) | (1 << RXEN1);
gdb::init();
- // if (SPL == 0xfb) { // init called from main() via blgdb::init()
- // struct gdb::Gdb *pgdb = GDB_PTR;
- // pgdb->status.isAppStarted = 1;
- // pgdb->status.isStopped = 0;
- // }
}
uint8_t prepareAppStart () {
asm volatile (
"__bootloader_printChar: \n"
);
- // switch (uart) {
- // case 0: putUart0Byte(c); break;
- // case 1: putUart1Byte(c); break;
- // }
if (uart == 0) {
putUart0Byte(c);
} else {
}
void eepromWriteByte (uint8_t *p, uint8_t value) {
- // eeprom_write_byte(p, value)
asm volatile (
"mov r18, r22 \n"
"sbic 0x1f, 1 \n"
#endif
-#define GDB_PTR (gdb::Gdb *)(RAMEND - sizeof(gdb::Gdb) + 1)
-// #define GDB_BREAKPOINT_PTR (struct gdb::Breakpoint *)(RAMEND - 2 - sizeof(gdb::Control) - sizeof(gdb::Status) - sizeof(gdb::Breakpoint))
-#define GDB_BREAKPOINT_PTR (struct gdb::Breakpoint *)(RAMEND - 4 - sizeof(gdb::Breakpoint))
+#define GDB_PTR ((gdb::Gdb *)(RAMEND - sizeof(gdb::Gdb) + 1))
+#define GDB_BREAKPOINT_PTR &((GDB_PTR)->breakpoint)
+// #define GDB_BREAKPOINT_PTR (struct gdb::Breakpoint *)(RAMEND - 2 - sizeof(gdb::Control) - sizeof(gdb::Status) - sizeof(gdb::Breakpoint) + 1)
// #define GDB_BREAKPOINT_PTR (struct gdb::Breakpoint *)(RAMEND - 6 - sizeof(gdb::Breakpoint))
namespace gdb {
enum BufferState { idle = 0, data, esc, chk1, chk2, chk2err, exec, execerr, send, waitack };
- struct Status { // (gdb) print *((struct gdb::Status *)0x8010f9)
+ struct Status { // (gdb) print ((gdb::Gdb *)0x801039)->status
uint8_t errorFlags; // @0x10f9
- // int16_t flashPage; // @0x10fa
- uint8_t isConnected:1; // @0x10fc.0x01, address used in bootloader::jmpTableGdbStopApplication()
- uint8_t isAppStarted:1; // @0x10fc.0x02
- uint8_t isStopped:1; // @0x10fc.0x04
- uint8_t isBreakpointValid:1; // @0x10fc.0x08
- uint8_t isSendingNotification:1; // @0x10fc.0x10
+ int16_t flashPage; // @0x10fa
+ uint8_t isConnected:1; // @0x10fc Bit 0, address used in bootloader::jmpTableGdbStopApplication()
+ uint8_t isAppStarted:1; // @0x10fc Bit 1
+ uint8_t isStopped:1; // @0x10fc Bit 2
+ uint8_t isBreakpointValid:1; // @0x10fc Bit 3
+ uint8_t isSendingNotification:1; // @0x10fc Bit 4
};
- struct Control { // (gdb) print *((struct gdb::Control *)0x8010fd)
- uint8_t clearErrors:1; // @0x10fd.0x01
- uint8_t interrupt:1; // @0x10fd.0x02
- uint8_t stop:1; // @0x10fd.0x04
- uint8_t proceed:1; // @0x10fd.0x08
- uint8_t kill:1; // @0x10fd.0x10
- uint8_t start:1; // @0x10fd.0x20
- uint8_t reset:1; // @0x10fd.0x40
- uint8_t notify:1; // @0x10fd.0x80
+ struct Control { // (gdb) print ((gdb::Gdb *)0x801039)->ctrl
+ uint8_t clearErrors:1; // Bit 0
+ uint8_t interrupt:1; // Bit 1
+ uint8_t stop:1; // Bit 2
+ uint8_t proceed:1; // Bit 3
+ uint8_t kill:1; // Bit 4
+ uint8_t start:1; // Bit 5
+ uint8_t reset:1; // Bit 6
+ uint8_t notify:1; // Bit 7
};
- struct Buffer {
+ struct Buffer { // (gdb) print ((gdb::Gdb *)0x801039)->buffer
enum BufferState state;
uint8_t rpos;
uint8_t chkSumFromGdb;
char buffer[BUFFER_SIZE];
};
- struct Breakpoint {
+ struct Breakpoint { // (gdb) print ((gdb::Gdb *)0x801039)->breakpoint
uint8_t regs[32];
uint16_t sp;
uint16_t pc;
uint8_t sfr;
};
- struct Gdb { // (gdb) set print pretty (gdb) print *((gdb::Gdb *)0x80103b)
+ struct Gdb { // (gdb) set print pretty (gdb) print *((gdb::Gdb *)0x801039)
uint8_t timer;
struct Buffer buffer;
struct Breakpoint breakpoint;
uint8_t magic;
};
- // extern struct Gdb gdb;
-
+ // --------------------------------------------------------------------------------------------------------
void init () ATT_OPTIMIZE_GDB ATT_SECTION_GDB;
void main () ATT_OPTIMIZE_GDB ATT_SECTION_GDB;