#--board nano-644
--pc 0xe000
--frequency 12000000
+--mmcu atmega644p
#--log trace
--log none
#--nosync
--- /dev/null
+{
+ "configurations": [
+ {
+ "name": "Linux",
+ "includePath": [
+ "/usr/lib/avr/include/**",
+ "/usr/lib/avr/include/**"
+ ],
+ "defines": [ ],
+ "forcedInclude": [
+ "/usr/lib/avr/include/stdio.h"
+ ],
+ "compilerPath": "/usr/bin/avr-gcc",
+ "compilerArgs": [
+ "-mmcu=atmega644p",
+ "-DF_CPU=12000000",
+ "-Os"
+ ],
+ "cStandard": "gnu11",
+ "cppStandard": "gnu++11",
+ "intelliSenseMode": "linux-gcc-x64"
+ }
+ ],
+ "version": 4
+}
\ No newline at end of file
--- /dev/null
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "(gdb) Launch",
+ "type": "cppdbg",
+ "request": "launch",
+ "program": "enter program name, for example ${workspaceFolder}/a.out",
+ "args": [],
+ "stopAtEntry": false,
+ "cwd": "${workspaceFolder}",
+ "environment": [],
+ "externalConsole": false,
+ "MIMode": "gdb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ }
+ ]
+ },
+ {
+ "name": "(avr-gdb) Launch",
+ "type": "cppdbg",
+ "request": "launch",
+ "program": "${workspaceFolder}/sim/dist/atmega324p_u1_bootloader.elf",
+ "args": [],
+ "stopAtEntry": false,
+ "cwd": "${workspaceFolder}",
+ "environment": [],
+ "externalConsole": true,
+ "MIMode": "gdb",
+ "miDebuggerPath": "/usr/bin/avr-gdb",
+ "miDebuggerServerAddress": ":1234",
+ "setupCommands": [
+ {
+ "description": "Remote debug enable",
+ "text": "-gdb-set debug remote 1",
+ "ignoreFailures": false
+ }
+ ]
+ },
+ {
+ "request": "launch",
+ "type": "node-terminal",
+ "name": "Easyprogrammer",
+ "preLaunchTask": "easyprogrammer",
+ },
+ {
+ "name": "pi-hc2",
+ "request": "launch",
+ "type": "node",
+ //"preLaunchTask": "build",
+ "program": ".vscode/scripts/build-for-hc2.js",
+ "args": [ ],
+ "cwd": "${workspaceFolder}",
+ "console": "internalConsole",
+ // "internalConsoleOptions": "neverOpen"
+ "internalConsoleOptions": "openOnFirstSessionStart"
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+console.log('Start...')
+const { exec } = require('child_process');
+exec('/usr/bin/make hc2', (error, stdout, stderr) => {
+ if (error) {
+ console.error(`exec error: ${error}`);
+ return;
+ }
+ console.log(`stdout: ${stdout}`);
+ console.error(`stderr: ${stderr}`);
+});
--- /dev/null
+{
+ "files.associations": {
+ "global.h": "c",
+ "stdio.h": "c",
+ "io.h": "c",
+ "cctype": "cpp",
+ "cmath": "cpp",
+ "cstdint": "cpp",
+ "cstdio": "cpp",
+ "cstdlib": "cpp",
+ "limits": "cpp",
+ "*.tcc": "cpp",
+ "cinttypes": "cpp",
+ "type_traits": "cpp",
+ "typeinfo": "cpp",
+ "iom324p.h": "c"
+ },
+ "cpplint": {
+ "lineLength": 140,
+ "root": "src",
+ "filters": [ "-whitespace/parens", "-whitespace/blank_line", "-readability/casting", "-legal/copyright", "-build/include" ]
+ },
+ "files.autoSave": "afterDelay",
+ "files.autoSaveDelay": 5000,
+ "files.trimTrailingWhitespace": true,
+ "editor.tabSize": 4,
+ "editor.insertSpaces": false,
+ "cSpell.words": [
+ "adiw",
+ "APPINIT",
+ "APPMEM",
+ "atmega",
+ "avrdude",
+ "blgdb",
+ "Bootloader",
+ "BOOTLOADERMEM",
+ "brne",
+ "COMPA",
+ "DDRB",
+ "EECR",
+ "EEPE",
+ "EEPROM",
+ "efuse",
+ "Entf",
+ "EVWS",
+ "execerr",
+ "execovf",
+ "fdev",
+ "FLASHERASE",
+ "FLASHWRITE",
+ "fprintln",
+ "fputnchar",
+ "gdbin",
+ "GDBMEM",
+ "gdbout",
+ "gputc",
+ "gtkwave",
+ "hfuse",
+ "lfuse",
+ "memputc",
+ "memputs",
+ "MMCU",
+ "Modbus",
+ "monin",
+ "movw",
+ "multiprocess",
+ "mytrace",
+ "OCIE",
+ "ONLYLOCASE",
+ "padd",
+ "pmon",
+ "PORTB",
+ "printdbg",
+ "printdbgln",
+ "PROGMEM",
+ "putch",
+ "putln",
+ "putnc",
+ "putnchar",
+ "pval",
+ "RAMEND",
+ "RAMPZ",
+ "rbuffer",
+ "Recived",
+ "rjmp",
+ "rpos",
+ "RXCIE",
+ "RXEN",
+ "sbic",
+ "simavr",
+ "SPMCSR",
+ "SPMEN",
+ "SRAM",
+ "SREG",
+ "TCCR",
+ "TCNT",
+ "TIFR",
+ "TIMSK",
+ "tnotrun",
+ "TXEN",
+ "UBRR",
+ "UCSR",
+ "UCSZ",
+ "UDRE",
+ "USART",
+ "usbasp",
+ "vect",
+ "waitack",
+ "WDRF",
+ "WDTO",
+ "wpos",
+ "xmemprint",
+ "xprint",
+ "xprintmem",
+ "xput",
+ "xputc",
+ "xputs",
+ "xputsmem"
+ ],
+ "C_Cpp.errorSquiggles": "Disabled"
+}
--- /dev/null
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=733558
+ // for the documentation about the tasks.json format
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "build",
+ "type": "shell",
+ "command": "make",
+ "args": [],
+ "problemMatcher": [ "$gcc" ],
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ },
+ {
+ "label": "clean",
+ "type": "shell",
+ "command": "make",
+ "args": [
+ "clean"
+ ]
+ },
+ {
+ "label": "easyprogrammer",
+ "type": "process",
+ "command": "/usr/bin/easyprogrammer",
+ "args": [
+ "--target",
+ "atmega324p",
+ "--interface",
+ "/dev/ttyUSB0:115200",
+ "-f",
+ "dist/atmega324p.hex"
+ ],
+ "isBackground": true,
+ "problemMatcher": []
+ }
+ ]
+}
\ No newline at end of file
## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
-CFLAGS = -g -Os -Wall -gdwarf-2
+CFLAGS = -g -DF_CPU=12000000L -Os -Wall -gdwarf-2
LFLAGS = -gdwarf-2
-LFLAGS += -Wl,-Tldscripts/ldscript_atmega324p.x
+LFLAGS += -Wl,-Tldscripts/ldscript_atmega644p.x
CFLAGS_SIM = -g -DF_CPU=12000000L -Os -Wall -gdwarf-2
CFLAGS_SIM += -DSIMAVR
build-xsim: sim/dist/$(PRJ).axf sim/dist/$(PRJ).bin
-gui: gui/dist/gui.elf
+#sim: build-sim
+ #simavr -m $(DEVICE) sim/dist/$(PRJ).elf
+ ## /work/sx/simavr/simavr/run_avr -m $(DEVICE) sim/dist/$(PRJ).axf
-sim: build-sim
- simavr -m $(DEVICE) sim/dist/$(PRJ).elf
- # /work/sx/simavr/simavr/run_avr -m $(DEVICE) sim/dist/$(PRJ).axf
+#xsim: build-xsim
+ #simavr -m $(DEVICE) sim/dist/$(PRJ).axf
+ ## /work/sx/simavr/simavr/run_avr -m $(DEVICE) sim/dist/$(PRJ).axf
-xsim: build-xsim
- simavr -m $(DEVICE) sim/dist/$(PRJ).axf
- # /work/sx/simavr/simavr/run_avr -m $(DEVICE) sim/dist/$(PRJ).axf
+#gdb: sim/dist/$(PRJ).axf
+ #simavr -g -m $(DEVICE) sim/dist/$(PRJ).axf
+ ## /work/sx/simavr/simavr/run_avr -g -m $(DEVICE) sim/$(PRJ).axf
-gdb: sim/dist/$(PRJ).axf
- simavr -g -m $(DEVICE) sim/dist/$(PRJ).axf
- # /work/sx/simavr/simavr/run_avr -g -m $(DEVICE) sim/$(PRJ).axf
-
-xgdb: sim/dist/$(PRJ).axf
- simavr -g -m $(DEVICE) sim/dist/$(PRJ).axf
- # /work/sx/simavr/simavr/run_avr -g -m $(DEVICE) sim/$(PRJ).axf
-
-
-rsync: dist/$(PRJ).hex
- rsync -aP dist/ pi-hc2:/tmp/dist
+#xgdb: sim/dist/$(PRJ).axf
+ #simavr -g -m $(DEVICE) sim/dist/$(PRJ).axf
+ ## /work/sx/simavr/simavr/run_avr -g -m $(DEVICE) sim/$(PRJ).axf
#dist/$(PRJ).elf: build/bootloader.o build/startup.o build/main.o build/gdb.o
sim/build/simavr.o: sim/simavr.c
avr-gcc -o $@ $(CFLAGS_SIM) -std=gnu99 -Wall -gdwarf-2 -mmcu=$(DEVICE) -c $<
+
+simuc:
+ simuc
+
+isp:
+ avrdude -c usbasp -p m644p -U lock:r:-:h
+
+isp-flash: dist/$(PRJ).elf all
+ avrdude -c usbasp -p m644p -e -U flash:w:$<
+
+isp-read:
+ avrdude -c usbasp -p m644p -U flash:r:/tmp/flash.bin
+
+isp-erase:
+ avrdude -c usbasp -p m644p -e
+
+isp-fuse:
+ avrdude -c usbasp -p m644p -U lfuse:w:0xFF:m -U hfuse:w:0xD0:m -U efuse:w:0xFE:m -U lock:w:0xEF:m
+
+
clean:
-@rm -r dist
-@rm -r build
-# gdb-stub-sm_atmega324p
+# gdb-stub
-Small version of gdb stub for Atmega324P. Gdb must connect to target via [gdb-gateway](../gdb-gateway/README.md).
-
-## avrdude
+Der gdb-stub im Bootloader-Bereich des µC-Flash liest die EEPROM-Speicherstelle 0 um das Startverhalten zu entscheiden:
+* `0xFF`: starte die Applikation sofort
+* `0x01` ... `0xFE`: Warte eine bestimmte Zeit bis die Applikation gestartet wird. Der Wert gibt die Wartezeit an (je kleiner der Wert desto länger wird gewartet).
+* `0x00`: der gdb-stub bleibt dauerhaft aktiv. Die Applikation kann nur aus dem gdb gestartet werden.
+Auf der UART0 Schnittstelle erfolgt eine textuelle Ausgabe des gdb-stub:
-Start on address 0:
```
-user@pi: $ avrdude -c usbasp -p atmega324p -U efuse:w:0xff:m -U hfuse:w:0xd1:m -U lfuse:w:0xd6:m
+e0 gdb-stub V0.1 (Jul 14 2024,16:49:20)
+```
+
+Der erste Hex-Wert startet mit dem Wert an der EEPROM-Speicheradresse 0 und wird alle 0.5s dekrementiert. Erreicht er 0 wird die Applikation (sofern der EEPROM Wert nicht 0 war) gestartet. Mit ESC im Terminal kann der Wert wieder zurückgesetzt werden.
+
+Auf der UART1 Schnittstelle erfolgt die Kommunikation mit dem avr-gdb.
+
+## avrdude
+
+Programmiere EEPROM Adresse 0 mit 0x00 (im gdb-stub dauerhaft bleiben):
+```
+avrdude -c usbasp -p atmega324p -U eeprom:w:0x00:m
```
-Start on address 0x7000, bootloader 4K:
+Programmier EEPROM Adresse 0 mit 0xff (gdb-stub sofoert verlassen und Applikation starten):
```
-user@pi: $ avrdude -c usbasp -p atmega324p -U efuse:w:0xff:m -U hfuse:w:0xd0:m -U lfuse:w:0xd6:m
+avrdude -c usbasp -p atmega644p -U eeprom:w:0xff:m
+```
+
+## avr-gdb
+Im gdb ist der NonStop Modus zu setzen bevor eine Verbindung hergestellt wird:
+```
+(gdb) set non-stop 1
```
-Programm eeprom with 0x00 (stay in gdb-stub):
+Die ELF-Datei des Programms muss geladen werden, damit der gdb über die Programminformationen (Symbole, ...) verfügt.
```
-avrdude -c usbasp -p atmega324p -U eeprom:w:0x00:m
+(gdb) file dist/test.elf
```
-Programm eeprom with 0xff (skip gdb-stub in bootloader section and start application):
+Danach kann die Verbindung hergestellt werden:
```
-avrdude -c usbasp -p atmega324p -U eeprom:w:0x00:m
-```
\ No newline at end of file
+(gdb) target remote /dev/ttyUSB1
+```
+
+
+
--- /dev/null
+# GDB-Stub Protocol
+
+* `--->` Request from *avr-gdb* to *gdb-stub* (in µC)
+* `<---` Response from *gdb-stub* (in µC) to *avr-gdb*
+
+## Request/Response 1
+
+[https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSupported-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSupported-packet)
+
+
+Tell the remote stub about features supported by GDB, and query the stub for features it supports.
+
+```
+---> +
+---> $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+#df
+
+<--- +
+<--- $qXfer:memory-map:read+;QNonStop+#cd
+```
+------------------------------------------------------------
+
+## Request/Response 2
+
+[https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#index-vMustReplyEmpty-packet](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#index-vMustReplyEmpty-packet)
+
+The correct reply to an unknown `v` packet is to return the empty string, however, some older versions of gdbserver would incorrectly return `OK` for unknown `v` packets.
+
+The `vMustReplyEmpty` is used as a feature test to check how gdbserver handles unknown packets, it is important that this packet be handled in the same way as other unknown `v` packets. If this packet is handled differently to other unknown `v` packets then it is possible that GDB may run into problems in other areas, specifically around use of `vFile:setfs:`
+
+```
+---> $vMustReplyEmpty#3a
+<--- +
+<--- $#00
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 3
+
+Set thread for subsequent operations (‘m’, ‘M’, ‘g’, ‘G’, et.al.):
+[https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-H-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-H-packet)
+
+```
+---> $Hg0#df
+<--- +
+<--- $OK#9a
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 4
+
+[https://sourceware.org/gdb/current/onlinedocs/gdb.html/General-Query-Packets.html#index-QNonStop-packet](https://sourceware.org/gdb/current/onlinedocs/gdb.html/General-Query-Packets.html#index-QNonStop-packet)
+
+Enter non-stop (‘QNonStop:1’) mode. See [Remote Non-Stop](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Remote-Non_002dStop.html#Remote-Non_002dStop), for more information.
+
+```
+--> $QNonStop:1#8d
+<--- +
+<--- $OK#9a
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 5
+
+[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#9e
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 6
+
+[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
+
+```
+---> $qsThreadInfo#c8
+<--- +
+<--- $l#6c
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 7
+
+ [https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qAttached-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qAttached-packet)
+
+Return an indication of whether the remote server attached to an existing process or created a new process
+
+```
+---> $qAttached#8f
+<--- +
+<--- $1#31
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 8
+
+[https://sourceware.org/gdb/onlinedocs/gdb/Tracepoint-Packets.html#index-qTStatus-packet](https://sourceware.org/gdb/onlinedocs/gdb/Tracepoint-Packets.html#index-qTStatus-packet)
+
+Ask the stub if there is a trace experiment running right now.
+
+```
+---> $qTStatus#49
+<--- +
+<--- $#00
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 9
+
+[https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-_003f-packet](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.
+
+```
+---> $?#3f
+<--- +
+<--- OK#9a
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 10
+
+[https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont_003f-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont_003f-packet)
+
+Request a list of actions supported by the ‘vCont’ packet.
+
+```
+---> $vCont?#49
+<--- +
+<--- $vCont;c;t;#92
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 11
+
+[https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet](https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet)
+
+Resume the inferior, specifying different actions for each thread.
+
+```
+---> $vCont;t:1#24
+<--- +
+<--- $OK#9a
+---> +
+```
+
+------------------------------------------------------------
+
+## Request/Response 12
+
+[https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSymbol-packet](https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSymbol-packet)
+
+Notify the target that GDB is prepared to serve symbol lookup requests:
+* 'OK' -> The target does not need to look up any (more) symbols
+
+```
+---> $qSymbol::#5b
+<--- +
+<--- $OK#9a
+---> +
+```
#include <avr/pgmspace.h>
#ifndef F_CPU
- #define F_CPU 20000000L
+ #define F_CPU 12000000L
#endif
#ifdef SIMAVR
#define GLOBAL_UART0_BITRATE 115200
#define GLOBAL_UART1_BITRATE 115200
#ifndef F_CPU
- #define F_CPU 20000000L
+ #define F_CPU 12000000L
#endif
// #define GLOBAL_GDB_UART0
#define GLOBAL_GDB_UART1
void init () {
- DDRB |= (1 << PB0); // ~K1-ON via SW6D or Life-LED via JP9
- setLifeLed(1);
+ DDRC = 0x1c;
UBRR0L = (F_CPU / GLOBAL_UART0_BITRATE + 4) / 8 - 1;
UBRR0H = 0x00;
// pgdb->status.isAppStarted = 1;
// pgdb->status.isStopped = 0;
// }
- setLifeLed(0);
}
uint8_t prepareAppStart () {
struct gdb::Gdb *pgdb = GDB_PTR;
- TCCR1B = (1 << CS12) | (1 << CS10); // fCPU/1024 = 19,53125kHz@20MHz = 51.2µs/Tick -> 3.36s to 0xffff
+ TCCR1B = (1 << CS12) | (1 << CS10); // fCPU/1024 = 11718,75Hz@12MHz = 85.333µs/Tick -> 5.59s to 0xffff
uint8_t eepromByteAddrZero = eepromReadByte(0);
do {
pgdb->ctrl.start = 0;
startProgram = 0;
}
- if (startProgram == 0 || TCNT1 >= 0x2626) { // 500,0192ms
+ if (startProgram == 0 || TCNT1 >= 0x16E3) { // 499,966ms
+ toggleLedRed();
TCNT1 = 0;
gdb::serve500msTimer();
if (startProgram > 0 && !pgdb->status.isStopped) {
putUint8Hex(stdoutUart, startProgram);
printChar(stdoutUart, ' ');
printWelcomeMessage();
- toggleLifeLed();
}
int b = getc(stdinUart);
if ( b == 27) { // escape pressed
uint8_t b = pgm_read_byte(0x0000); // check if app in non bootloader flash
+ setLedOrange(1);
if (b != 0xff) {
struct gdb::Gdb *pgdb = GDB_PTR;
pgdb->status.isAppStarted = 1;
gdb::handleGdbRequest();
}
}
+ toggleLedGreen();
putln(stdoutUart);
// make sure that last UART Bytes are sent completely
TCNT1 = 0;
- while (TCNT1 < 0x2000) {} // delay startup app
+ while (TCNT1 < 0x3000) {} // delay startup app
#ifndef SIMAVR
UCSR0B = 0; // disable UART0
printChar(stdoutUart, '\r');
}
- void setLifeLed (bool on) {
+ void setLedRed (bool on) {
if (on) {
- PORTB |= (1 << PB0);
+ PORTC |= (1 << PC2);
} else {
- PORTB &= ~(1 << PB0);
+ PORTC &= ~(1 << PC2);
}
}
- void toggleLifeLed () {
- PORTB ^= (1 << PB0);
+ void setLedOrange (bool on) {
+ if (on) {
+ PORTC |= (1 << PC3);
+ } else {
+ PORTC &= ~(1 << PC3);
+ }
+ }
+
+ void setLedGreen (bool on) {
+ if (on) {
+ PORTC |= (1 << PC4);
+ } else {
+ PORTC &= ~(1 << PC4);
+ }
+ }
+
+ void toggleLedRed () {
+ PORTC ^= (1 << PC2);
+ }
+
+ void toggleLedOrange () {
+ PORTC ^= (1 << PC3);
+ }
+
+ void toggleLedGreen () {
+ PORTC ^= (1 << PC4);
}
int getUart0Byte () {
void printStringInFlash (int8_t uart, PGM_P s) ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
void printWelcomeMessage () ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
- void setLifeLed (bool on) ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
- void toggleLifeLed () ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
+ void setLedRed (bool on) ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
+ void setLedOrange (bool on) ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
+ void setLedGreen (bool on) ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
+ void toggleLedRed () ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
+ void toggleLedOrange () ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
+ void toggleLedGreen () ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
int getUart0Byte () ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
int getUart1Byte () ATT_OPTIMIZE ATT_SECTION_BOOTLOADER;
const char gdb_OK[] GDBMEM = "$OK#";
const char gdb_E00[] GDBMEM = "$E00#";
+ const char gdb_QNonStop[] GDBMEM = "QNonStop+";
+ const char gdb_QXferMemoryMapRead[] GDBMEM = "qXfer:memory-map:read+";
+ const char gdb_vCont[] GDBMEM = "$vCont;c;t;#";
+ // const char gdb_QStartNoAckMode[] GDBMEM = "QStartNoAckMode+";
+ // const char gdb_QXferExecFileRead[] GDBMEM = "qXfer:exec-file:read+";
// struct Gdb gdb;
// struct Buffer buf;
switch(*p->buffer) {
- // 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.
- // xputsmem(gdb_OK);
- // // if (gdb.appInfo.isStarted && !gdb.appInfo.isRunning) {
- // // xputsStop(0);
- // // } else {
- // // xputsmem(gdb_OK);
- // // }
- // return;
- // }
+ 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();
+ } else {
+ xputsmem(gdb_OK);
+ }
+ return;
+ }
case 'D': {
// https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-D-packet
xputsmem(gdb_OK);
return;
}
+ case 'H': {
+ // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-H-packet
+ // Set thread for subsequent operations (‘m’, ‘M’, ‘g’, ‘G’, et.al.)
+ xputsmem(gdb_OK);
+ return;
+ }
// case 'T': {
// // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-T-packet
// https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSupported-packet
// Tell the remote stub about features supported by GDB, and query the stub for features it supports.
xputc('$');
+ xputsmem(gdb_QXferMemoryMapRead);
+ xputc(';'); xputsmem(gdb_QNonStop);
+ // xputc(';'); xputsmem(gdb_QStartNoAckMode);
+ // xputc(';'); xputsmem(gdb_QXferExecFileRead);
xputc('#');
return;
} else if (
- (i == 7 && sum == 0x55) // vStopped
- // // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vStopped-packet
- // Notification Packet, send queued events, if not events pending send OK
+ (i == 7 && sum == 0x55) // vStopped (https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vStopped-packet)
+ || (i == 9 && sum == 0x8d) // QNonStop:1 (https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-QNonStop-packet)
+ || (i == 6 && sum == 0xe7) // qSymbol (https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qSymbol-packet)
) {
xputsmem(gdb_OK);
return;
+ } else if (i == 11 && sum == 0xbb) { // qfThreadInfo
+ // 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
+ // !! don't user xputs here, because dgb_stub does not initialize static data in sram
+ xputc('$'); xputc('m'); xputc('1');
+ // xputs("$m1");
+ if (pgdb->status.isAppStarted) {
+ xputc(';'); xputc('2');
+ }
+ xputc('#');
+ return;
+
+ } else if (i == 8 && sum==0x8f) { // qAttached
+ // https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#index-qAttached-packet
+ // Return an indication of whether the remote server attached to an existing process or created a new process
+ xputc('$');
+ xputc('1');
+ xputc('#');
+ return;
+
+ } else if (i == 7 && sum == 0x49) { // qTStatus
+ // https://sourceware.org/gdb/onlinedocs/gdb/Tracepoint-Packets.html#index-qTStatus-packet
+ // Ask the stub if there is a trace experiment running right now.
+ xputc('$');
+ xputc('#');
+ return;
+
} else if (i == 11 && sum == 0x8e) { // vFlashErase:
i = 12;
uint32_t addressStart, addressEnd;
xputsmem(gdb_OK);
}
return;
- }
+
+ // } else if (i == 13 && sum == 0x4b) { // QStartNoAckMode
+ // // https://sourceware.org/gdb/current/onlinedocs/gdb.html/General-Query-Packets.html#index-QStartNoAckMode-packet
+ // // Request that the remote stub disable the normal ‘+’/‘-’ protocol acknowledgments (see Packet Acknowledgment).
+ // xputsmem(gdb_OK);
+
+
+
// } else if (i == 11 && sum == 0xbb) { // qfThreadInfo
// // 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
// xputc('#');
// return;
- // } else if (i == 11 && sum == 0xc8) { // qsThreadInfo
- // // 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
- // // !! don't user xputs here, because dgb_stub does not initialize static data in sram
- // xputsmem(gdb_l);
- // // xputc('$');
- // // xputc('l');
- // // xputc('#');
- // return;
-
- // } else if (i == 5 && sum == 0x49) { // vCont?
- // // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont_003f-packet
- // // Request a list of actions supported by the ‘vCont’ packet.
- // xputsmem(gdb_vCont);
- // return;
+ } else if (i == 11 && sum == 0xc8) { // qsThreadInfo
+ // 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
+ // !! don't user xputs here, because dgb_stub does not initialize static data in sram
+ xputc('$');
+ xputc('l');
+ xputc('#');
+ return;
+
+ } else if (i == 5 && sum == 0x49) { // vCont?
+ // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont_003f-packet
+ // Request a list of actions supported by the ‘vCont’ packet.
+ xputsmem(gdb_vCont);
+ return;
// } else if (i == 6 && sum == 0xa8) { // vCont;c
// // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet
// xputsmem(gdb_OK);
// return;
- // } else if (
- // (i == 6 && sum == 0xb9) // vCont;t
- // // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet
- // // Resume the inferior, specifying different actions for each thread.
- // || (i == 5 && sum == 0x4e) // vCtrlC
- // // https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCtrlC-packet
- // // Interrupt remote target as if a control-C was pressed on the remote terminal.
- // ) {
+ } else if (
+ (i == 6 && sum == 0xb9) // vCont;t (https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCont-packet -> Resume the inferior, specifying different actions for each thread.)
+ || (i == 5 && sum == 0x4e) // vCtrlC (https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#index-vCtrlC-packet -> Interrupt remote target as if a control-C was pressed on the remote terminal.)
+ ) {
// uint8_t threadId = p->buffer[8] - '0';
// gdb.status.currentThread = threadId & 0x03;
// switch (threadId) {
// case 2: gdb.ctrl.continueApplication = 1; break;
// case 3: gdb.ctrl.continueInterrupts = 1; break;
// }
- // xputsmem(gdb_OK);
- // return;
- // }
+ xputsmem(gdb_OK);
+ 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);
+ }
+
}
// request not supported
stdout = &mystdout;
stderr = &mystderr;
sei();
- printf("UART1 -> UART0 ready\n");
while (1) {
}
ISR (USART0_RX_vect) {
PORTC ^= (1 << PC3);
uint8_t b = UDR0;
+ UDR1 = b;
}
ISR (USART1_RX_vect) {