From 793fbd4a1e8c0efe5405bf3b0459674c0f344431 Mon Sep 17 00:00:00 2001 From: Manfred Steiner Date: Tue, 16 Jul 2024 17:34:25 +0200 Subject: [PATCH] startapp, breakpoint OK, ... (interrupt nicht OK) --- .../docs/{protocol.md => protocol-startup.md} | 9 +- software/gdb-stub/docs/protocol-stop.md | 82 +++++++++++++++++++ software/gdb-stub/src/app.cpp | 6 +- software/gdb-stub/src/blgdb.h | 22 ++--- software/gdb-stub/src/bootloader.cpp | 55 +++++++------ software/gdb-stub/src/gdb.cpp | 34 ++++++-- software/gdb-stub/src/main.cpp | 1 + 7 files changed, 160 insertions(+), 49 deletions(-) rename software/gdb-stub/docs/{protocol.md => protocol-startup.md} (97%) create mode 100644 software/gdb-stub/docs/protocol-stop.md diff --git a/software/gdb-stub/docs/protocol.md b/software/gdb-stub/docs/protocol-startup.md similarity index 97% rename from software/gdb-stub/docs/protocol.md rename to software/gdb-stub/docs/protocol-startup.md index bbfb3b6..18069ed 100644 --- a/software/gdb-stub/docs/protocol.md +++ b/software/gdb-stub/docs/protocol-startup.md @@ -1,7 +1,7 @@ -# GDB-Stub Protocol +# GDB-Stub Protocol Startup -* `--->` Request from *avr-gdb* to *gdb-stub* (in µC) -* `<---` Response from *gdb-stub* (in µC) to *avr-gdb* +* `--->` Request or Acknownledge from *avr-gdb* to *gdb-stub* (in µC) +* `<---` Response or Notification from *gdb-stub* (in µC) to *avr-gdb* ## 1 Request/Response @@ -84,7 +84,8 @@ Start to obtain a list of all active thread IDs from the target [https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet) -Continue to obtain a list of all active thread IDs from the target +Continue to obtain a list of all active thread IDs from the target. +‘l’ (lower case letter ‘L’) denotes end of list. ``` ---> $qsThreadInfo#c8 diff --git a/software/gdb-stub/docs/protocol-stop.md b/software/gdb-stub/docs/protocol-stop.md new file mode 100644 index 0000000..09019a7 --- /dev/null +++ b/software/gdb-stub/docs/protocol-stop.md @@ -0,0 +1,82 @@ + +# GDB-Stub Protocol Break + +* `--->` Request or Acknowledge from *avr-gdb* to *gdb-stub* (in µC) +* `<---` Response or Notification from *gdb-stub* (in µC) to *avr-gdb* + +## 1 Notification/Acknowledge + +[https://sourceware.org/gdb/current/onlinedocs/gdb.html/Notification-Packets.html#Notification-Packets](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Notification-Packets.html#Notification-Packets) + +The GDB remote serial protocol includes notifications, packets that require no acknowledgment. + +After receiving a notification, GDB shall acknowledge it by sending a ack packet as a regular, synchronous request to the stub. Such acknowledgment is not required to happen immediately, as GDB is permitted to send other, unrelated packets to the stub first, which the stub should process normally. + +``` +<--- %Stop:T00thread:1;#b2 +---> $vStopped#55 +<--- +$OK#9a +---> + +``` + +## 2 Request/Response + +[https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-g-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-g-packet) + +Read general registers (used on gdb command load) + + +``` +---> $g#67 +<--- + +<--- $a0000000000000000000000000000000000120008601000101001000fe100770a03810e0010000#d3 +---> + +``` + +Response format see [https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/avr-tdep.c;h=1e39f851bac4e5e335f0a271415cbba5822fd6b0;hb=HEAD#l208](https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/avr-tdep.c;h=1e39f851bac4e5e335f0a271415cbba5822fd6b0;hb=HEAD#l208): + +``` + $a0000000000000000000000000000000000120008601000101001000fe100770a03810e0010000 + ^ ^ ^ ^ ^ ^ ^ + | | | | | | | + r0| | | | | | + r1| | | | | + r2 ................................................. | | | | + r31| | | + SREG| | + SP | + PC7:0, PC15:8, PC23:16, PC31:24 +``` + +* Register values: r0=0xa0, r1=0, ... , r17=0x01, r18=0x20, ... r31=0x77 +* Status register: SREG = 0x0a () +* Stack pointer: SP = 0x1803 +* Program counter: PC = 0x000001e0 + + +## 3 Request/Response + +[https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet) + +Start to obtain a list of all active thread IDs from the target + +``` +---> $qfThreadInfo#bb +<--- + +<--- $m1;2#0b +---> + +``` + +## 4 Request/Response + +[https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qfThreadInfo-packet) + +Continue to obtain a list of all active thread IDs from the target. +‘l’ (lower case letter ‘L’) denotes end of list. + +``` +---> $qsThreadInfo#c8 +<--- + +<--- $l#6c +---> + +``` diff --git a/software/gdb-stub/src/app.cpp b/software/gdb-stub/src/app.cpp index 3aae82b..84233ff 100644 --- a/software/gdb-stub/src/app.cpp +++ b/software/gdb-stub/src/app.cpp @@ -20,6 +20,9 @@ namespace app { struct App app; void init () { + DDRC = (1 << DDC4) | (1 << DDC3) | (1 << DDC2); + PORTC = 0; + memset((void *)&app, 0, sizeof(app)); UCSR0B |= (1 << RXCIE0); UCSR1B |= (1 << RXCIE1); @@ -36,7 +39,8 @@ namespace app { sei(); } - void __attribute__((optimize("O0"))) main () { + void __attribute__((optimize("Og"))) main () { + if (app.event) { static uint16_t cnt = 0; if (app.event & 0x01) { diff --git a/software/gdb-stub/src/blgdb.h b/software/gdb-stub/src/blgdb.h index 79bd795..7437c8e 100644 --- a/software/gdb-stub/src/blgdb.h +++ b/software/gdb-stub/src/blgdb.h @@ -21,17 +21,17 @@ -#define blgdb_init() asm volatile ( "jmp 0x7002" ) -#define blgdb_main() asm volatile ( "call 0x7004 \n ret \n" ) -#define blgdb_stop() asm volatile ( "call 0x7006 \n ret \n" ) -#define blgdb_handleUartIsrByte(b) asm volatile ( "jmp 0x7008" ) -#define blgdb_printWelcomeMessage() asm volatile ( "jmp 0x700a" ) -#define blgdb_putchar(c) ( (*(( void (*)(uint8_t) ) (0x700c / 2) )) (c) ) -#define blgdb_puts(s) ( (*(( void (*)(const char *) ) (0x700e / 2) )) (s) ); -#define blgdb_putUint8Hex(value) ( (*(( void (*)(uint8_t) ) (0x7010 / 2) )) (value) ) -#define blgdb_memputc(p) ( (*(( void (*)(PGM_P) ) (0x7012 / 2) )) (p) ) -#define blgdb_memputs(p) ( (*(( void (*)(PGM_P) ) (0x7014 / 2) )) (p) ) -#define blgdb_serve500msTimer() asm volatile ( "jmp 0x7016" ) +#define blgdb_init() asm volatile ( "jmp 0xe002" ) +#define blgdb_main() asm volatile ( "call 0xe004 \n ret \n" ) +#define blgdb_stop() asm volatile ( "call 0xe006 \n ret \n" ) +#define blgdb_handleUartIsrByte(b) asm volatile ( "jmp 0xe008" ) +#define blgdb_printWelcomeMessage() asm volatile ( "jmp 0xe00a" ) +#define blgdb_putchar(c) ( (*(( void (*)(uint8_t) ) (0xe00c / 2) )) (c) ) +#define blgdb_puts(s) ( (*(( void (*)(const char *) ) (0xe00e / 2) )) (s) ); +#define blgdb_putUint8Hex(value) ( (*(( void (*)(uint8_t) ) (0xe010 / 2) )) (value) ) +#define blgdb_memputc(p) ( (*(( void (*)(PGM_P) ) (0xe012 / 2) )) (p) ) +#define blgdb_memputs(p) ( (*(( void (*)(PGM_P) ) (0xe014 / 2) )) (p) ) +#define blgdb_serve500msTimer() asm volatile ( "jmp 0xe016" ) namespace blgdb { diff --git a/software/gdb-stub/src/bootloader.cpp b/software/gdb-stub/src/bootloader.cpp index 0b57706..07363cd 100644 --- a/software/gdb-stub/src/bootloader.cpp +++ b/software/gdb-stub/src/bootloader.cpp @@ -54,18 +54,18 @@ namespace bootloader { void __attribute__ ((naked)) bootloaderStart () { asm volatile ( "__bootloader_start: \n" - "rjmp __bootloader_start_from_reset \n" // 0x7000 - "rjmp __bootloader_start_from_app \n" // 0x7002 - "rjmp __gdb_main \n" // 0x7004 - "rjmp __gdb_stopApplication \n" // 0x7006 - "rjmp __vector_jmpTableIsrUsart1 \n" // 0x7008 - "rjmp __print_welcome_message \n" // 0x700a - "rjmp __bootloader_printChar \n" // 0x700c - "rjmp __bootloader_puts \n" // 0x701e - "rjmp __bootloader_put_uint_8_hex \n" // 0x7010 - "rjmp __bootloader_memputc \n" // 0x7012 - "rjmp __bootloader_memputs \n" // 0x7014 - "rjmp __gdb_serve500msTimer \n" // 0x7016 + "rjmp __bootloader_start_from_reset \n" // 0xe000 + "rjmp __bootloader_start_from_app \n" // 0xe002 + "rjmp __gdb_main \n" // 0xe004 + "rjmp __gdb_stopApplication \n" // 0xe006 + "rjmp __vector_jmpTableIsrUsart1 \n" // 0xe008 + "rjmp __print_welcome_message \n" // 0xe00a + "rjmp __bootloader_printChar \n" // 0xe00c + "rjmp __bootloader_puts \n" // 0xe01e + "rjmp __bootloader_put_uint_8_hex \n" // 0xe010 + "rjmp __bootloader_memputc \n" // 0xe012 + "rjmp __bootloader_memputs \n" // 0xe014 + "rjmp __gdb_serve500msTimer \n" // 0xe016 ); } @@ -168,6 +168,7 @@ namespace bootloader { #ifdef SIMAVR main(); #else + setLedGreen(1); setLedOrange(0); setLedRed(0); asm volatile ( "jmp 0x0000" // start application ); @@ -238,6 +239,16 @@ namespace bootloader { asm volatile ( "__gdb_main: \n" ); + + static uint16_t cnt = 0; + + if (cnt < 0x2000) { + cnt ++; + } else { + toggleLedOrange(); + cnt = 0; + } + struct gdb::Gdb *pgdb = GDB_PTR; if (pgdb->ctrl.interrupt) { pgdb->ctrl.interrupt = 0; @@ -256,7 +267,7 @@ namespace bootloader { asm volatile ( "__gdb_stopApplication: \n" "push r25 \n" // save r25 (used for address of gdb::gdb.breakpoint) - "lds r25, 0x08fc \n" // gdb.status + "lds r25, 0x10fc \n" // gdb.status "andi r25, 0x01 \n" // gdb.status.isConnected "breq __gdb_stopApplication_end \n" "in r25, 0x3f \n" // SFR -> r25 @@ -344,8 +355,6 @@ namespace bootloader { uint8_t b = pgm_read_byte(0x0000); // check if app in non bootloader flash if (b != 0xff) { - setLedOrange(0); - setLedGreen(1); struct gdb::Gdb *pgdb = GDB_PTR; pgdb->status.isAppStarted = 1; pgdb->status.isStopped = 0; @@ -495,22 +504,14 @@ namespace bootloader { } void putStatus (int8_t uart) { - // struct gdb::Gdb *pgdb = GDB_PTR; - // putln(uart); - // printChar(uart, 'S'); - // printChar(uart, '-'); - // printChar(uart, pgdb->status.isAppStarted ? 'A' : 'a'); - // printChar(uart, pgdb->status.isStopped ? 'S' : 's'); - // printChar(uart, pgdb->status.isConnected ? 'C' : 'x'); - // printChar(uart, pgdb->status.isBreakpointValid ? 'B' : 'b'); - // putln(uart); - struct gdb::Gdb *pgdb = GDB_PTR; putln(uart); printChar(uart, 'S'); printChar(uart, '-'); - putUint8Hex(0, (uint8_t)(((uint16_t)(void *)&pgdb->ctrl) >> 8) ); - putUint8Hex(0, (uint8_t)((uint16_t)(void *)&pgdb->ctrl) ); + printChar(uart, pgdb->status.isAppStarted ? 'A' : 'a'); + printChar(uart, pgdb->status.isStopped ? 'S' : 's'); + printChar(uart, pgdb->status.isConnected ? 'C' : 'x'); + printChar(uart, pgdb->status.isBreakpointValid ? 'B' : 'b'); putln(uart); } diff --git a/software/gdb-stub/src/gdb.cpp b/software/gdb-stub/src/gdb.cpp index e76bab4..5f1335e 100644 --- a/software/gdb-stub/src/gdb.cpp +++ b/software/gdb-stub/src/gdb.cpp @@ -313,7 +313,7 @@ namespace gdb { } else if (pgdb->ctrl.stop) { pgdb->ctrl.stop = 0; - if (!pgdb->status.isStopped) { + if (!pgdb->status.isStopped && pgdb->buffer.state == idle) { if (pgdb->status.isAppStarted) { #ifdef GDB_DEBUG_UART printdbgln(GDB_DEBUG_ID_STOP_APPLICATION); @@ -366,7 +366,8 @@ namespace gdb { // 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(); + // xputsStop(); + pgdb->ctrl.stop = 1; // send STOP notification } else { xputsmem(gdb_OK); } @@ -411,10 +412,27 @@ namespace gdb { // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-g-packet // Read general registers (used on gdb command load) xputc('$'); - for (i = 0; i < 78; i++) { - xputc('0'); + bootloader::putUart0Byte('B'); + bootloader::putUart0Byte('-'); + bootloader::putUint8Hex(0, pgdb->status.isBreakpointValid); + bootloader::putln(0); + if (pgdb->status.isBreakpointValid) { + for (uint8_t i = 0; i < 32; i++) { + xputUint8Hex(pgdb->breakpoint.regs[i]); + } + xputUint8Hex(pgdb->breakpoint.sfr); + xputUint8Hex((uint8_t)(pgdb->breakpoint.sp)); + xputUint8Hex((uint8_t)(pgdb->breakpoint.sp >> 8)); + xputUint8Hex((uint8_t)(pgdb->breakpoint.pc)); + xputUint8Hex((uint8_t)(pgdb->breakpoint.pc >> 8)); + xputUint8Hex(0); // PC23:16 + xputUint8Hex(0); // PC31:24 + } else { + for (i = 0; i < 78; i++) { + xputc('0'); + } + // or "$0*j#" } - // or "$0*j#" xputc('#'); return; } @@ -649,7 +667,11 @@ namespace gdb { // case 3: gdb.ctrl.continueInterrupts = 1; break; // } bootloader::putStatus(0); - pgdb->ctrl.stop = 1; + if (pgdb->status.isAppStarted) { + pgdb->ctrl.interrupt = 1; + } else { + pgdb->ctrl.stop = 1; + } xputsmem(gdb_OK); return; diff --git a/software/gdb-stub/src/main.cpp b/software/gdb-stub/src/main.cpp index b4b1332..479231a 100644 --- a/software/gdb-stub/src/main.cpp +++ b/software/gdb-stub/src/main.cpp @@ -39,6 +39,7 @@ int __attribute__((naked)) main () { blgdb::init(); app::init(); while (1) { + blgdb::main(); app::main(); } -- 2.39.5