From edd93411fe4ef5a07b89de25b18562e3bbccdf1f Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 27 Mar 2019 13:45:25 +0100 Subject: [PATCH 1/9] dist: De-duplicated AVR debug config & scripts Use common debug.sh, debug_srv.sh and gdb.conf for all AVR boards. --- boards/common/arduino-atmega/dist/debug.sh | 12 ------------ boards/common/arduino-atmega/dist/debug_srv.sh | 7 ------- boards/common/arduino-atmega/dist/gdb.conf | 1 - boards/mega-xplained/dist/debug.sh | 12 ------------ boards/mega-xplained/dist/debug_srv.sh | 7 ------- boards/mega-xplained/dist/gdb.conf | 1 - boards/waspmote-pro/dist/debug.sh | 12 ------------ boards/waspmote-pro/dist/debug_srv.sh | 7 ------- boards/waspmote-pro/dist/gdb.conf | 1 - .../dist => dist/tools/avarice}/debug.sh | 0 .../dist => dist/tools/avarice}/debug_srv.sh | 0 .../dist => dist/tools/avarice}/gdb.conf | 0 makefiles/tools/avrdude.inc.mk | 7 ++++--- 13 files changed, 4 insertions(+), 63 deletions(-) delete mode 100644 boards/common/arduino-atmega/dist/debug.sh delete mode 100644 boards/common/arduino-atmega/dist/debug_srv.sh delete mode 100644 boards/common/arduino-atmega/dist/gdb.conf delete mode 100755 boards/mega-xplained/dist/debug.sh delete mode 100755 boards/mega-xplained/dist/debug_srv.sh delete mode 100644 boards/mega-xplained/dist/gdb.conf delete mode 100755 boards/waspmote-pro/dist/debug.sh delete mode 100755 boards/waspmote-pro/dist/debug_srv.sh delete mode 100644 boards/waspmote-pro/dist/gdb.conf rename {boards/atmega256rfr2-xpro/dist => dist/tools/avarice}/debug.sh (100%) rename {boards/atmega256rfr2-xpro/dist => dist/tools/avarice}/debug_srv.sh (100%) rename {boards/atmega256rfr2-xpro/dist => dist/tools/avarice}/gdb.conf (100%) diff --git a/boards/common/arduino-atmega/dist/debug.sh b/boards/common/arduino-atmega/dist/debug.sh deleted file mode 100644 index 46dc7377ca..0000000000 --- a/boards/common/arduino-atmega/dist/debug.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -# The setsid command is needed so that Ctrl+C in GDB doesn't kill avarice -: ${SETSID:=setsid} - -sleep 2 -${SETSID} -w avarice $1 & -#sleep 2 && $2/avr-gdb-wrapper -ex "target remote localhost:$3" $4 -sleep 3 && avr-gdb -ex "target remote localhost:$3" $4 - -# avarice exits with 1 if the connection is released, therefore we always exit with 0 -exit 0 diff --git a/boards/common/arduino-atmega/dist/debug_srv.sh b/boards/common/arduino-atmega/dist/debug_srv.sh deleted file mode 100644 index 8e7de053ab..0000000000 --- a/boards/common/arduino-atmega/dist/debug_srv.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -sleep 2 -avarice $1 - -# avarice exits with 1 if the connection is released, therefore we always exit with 0 -exit 0 diff --git a/boards/common/arduino-atmega/dist/gdb.conf b/boards/common/arduino-atmega/dist/gdb.conf deleted file mode 100644 index ca68eb344c..0000000000 --- a/boards/common/arduino-atmega/dist/gdb.conf +++ /dev/null @@ -1 +0,0 @@ -set $pc=0x00 diff --git a/boards/mega-xplained/dist/debug.sh b/boards/mega-xplained/dist/debug.sh deleted file mode 100755 index 46dc7377ca..0000000000 --- a/boards/mega-xplained/dist/debug.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -# The setsid command is needed so that Ctrl+C in GDB doesn't kill avarice -: ${SETSID:=setsid} - -sleep 2 -${SETSID} -w avarice $1 & -#sleep 2 && $2/avr-gdb-wrapper -ex "target remote localhost:$3" $4 -sleep 3 && avr-gdb -ex "target remote localhost:$3" $4 - -# avarice exits with 1 if the connection is released, therefore we always exit with 0 -exit 0 diff --git a/boards/mega-xplained/dist/debug_srv.sh b/boards/mega-xplained/dist/debug_srv.sh deleted file mode 100755 index 8e7de053ab..0000000000 --- a/boards/mega-xplained/dist/debug_srv.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -sleep 2 -avarice $1 - -# avarice exits with 1 if the connection is released, therefore we always exit with 0 -exit 0 diff --git a/boards/mega-xplained/dist/gdb.conf b/boards/mega-xplained/dist/gdb.conf deleted file mode 100644 index ca68eb344c..0000000000 --- a/boards/mega-xplained/dist/gdb.conf +++ /dev/null @@ -1 +0,0 @@ -set $pc=0x00 diff --git a/boards/waspmote-pro/dist/debug.sh b/boards/waspmote-pro/dist/debug.sh deleted file mode 100755 index 46dc7377ca..0000000000 --- a/boards/waspmote-pro/dist/debug.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -# The setsid command is needed so that Ctrl+C in GDB doesn't kill avarice -: ${SETSID:=setsid} - -sleep 2 -${SETSID} -w avarice $1 & -#sleep 2 && $2/avr-gdb-wrapper -ex "target remote localhost:$3" $4 -sleep 3 && avr-gdb -ex "target remote localhost:$3" $4 - -# avarice exits with 1 if the connection is released, therefore we always exit with 0 -exit 0 diff --git a/boards/waspmote-pro/dist/debug_srv.sh b/boards/waspmote-pro/dist/debug_srv.sh deleted file mode 100755 index 8e7de053ab..0000000000 --- a/boards/waspmote-pro/dist/debug_srv.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -sleep 2 -avarice $1 - -# avarice exits with 1 if the connection is released, therefore we always exit with 0 -exit 0 diff --git a/boards/waspmote-pro/dist/gdb.conf b/boards/waspmote-pro/dist/gdb.conf deleted file mode 100644 index ca68eb344c..0000000000 --- a/boards/waspmote-pro/dist/gdb.conf +++ /dev/null @@ -1 +0,0 @@ -set $pc=0x00 diff --git a/boards/atmega256rfr2-xpro/dist/debug.sh b/dist/tools/avarice/debug.sh similarity index 100% rename from boards/atmega256rfr2-xpro/dist/debug.sh rename to dist/tools/avarice/debug.sh diff --git a/boards/atmega256rfr2-xpro/dist/debug_srv.sh b/dist/tools/avarice/debug_srv.sh similarity index 100% rename from boards/atmega256rfr2-xpro/dist/debug_srv.sh rename to dist/tools/avarice/debug_srv.sh diff --git a/boards/atmega256rfr2-xpro/dist/gdb.conf b/dist/tools/avarice/gdb.conf similarity index 100% rename from boards/atmega256rfr2-xpro/dist/gdb.conf rename to dist/tools/avarice/gdb.conf diff --git a/makefiles/tools/avrdude.inc.mk b/makefiles/tools/avrdude.inc.mk index c5a317b892..97c283a27b 100644 --- a/makefiles/tools/avrdude.inc.mk +++ b/makefiles/tools/avrdude.inc.mk @@ -1,11 +1,12 @@ FLASHER = avrdude DIST_PATH = $(BOARDSDIR)/$(BOARD)/dist +AVARICE_PATH = $(RIOTTOOLS)/avarice DEBUGSERVER_PORT = 4242 -DEBUGSERVER = $(DIST_PATH)/debug_srv.sh +DEBUGSERVER = $(AVARICE_PATH)/debug_srv.sh DEBUGSERVER_INTERFACE ?= DEBUGSERVER_FLAGS = "-g -j usb $(DEBUGSERVER_INTERFACE) :$(DEBUGSERVER_PORT)" -DEBUGGER_FLAGS = "-x $(RIOTBOARD)/$(BOARD)/dist/gdb.conf $(ELFFILE)" -DEBUGGER = $(DIST_PATH)/debug.sh $(DEBUGSERVER_FLAGS) $(DIST_PATH) $(DEBUGSERVER_PORT) +DEBUGGER_FLAGS = "-x $(AVARICE_PATH)/gdb.conf $(ELFFILE)" +DEBUGGER = "$(AVARICE_PATH)/debug.sh" $(DEBUGSERVER_FLAGS) $(AVARICE_PATH) $(DEBUGSERVER_PORT) PROGRAMMER_FLAGS = -p $(subst atmega,m,$(CPU)) From f2edcf96746a0c8a7238efb37a4385c102af1ed3 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 27 Mar 2019 15:59:29 +0100 Subject: [PATCH 2/9] makefiles/tools/avrdude: Improved debug handling - Choose correct debug protocol for ATmega328P (which supports debugWIRE instead of JTAG) - Allow overwriting debugger device via AVR_DEBUGDEVICE environment variable, default to the Atmel-ICE (least expensive, supports most AVR devices) --- boards/atmega256rfr2-xpro/Makefile.include | 3 --- makefiles/tools/avrdude.inc.mk | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/boards/atmega256rfr2-xpro/Makefile.include b/boards/atmega256rfr2-xpro/Makefile.include index af929bcfd5..5323cefc1e 100644 --- a/boards/atmega256rfr2-xpro/Makefile.include +++ b/boards/atmega256rfr2-xpro/Makefile.include @@ -5,7 +5,4 @@ BAUD ?= 115200 # Use EDBG (xplainedpro) programmer with avrdude PROGRAMMER ?= xplainedpro -# Use edbg interface for debugging -DEBUGSERVER_INTERFACE ?= --edbg - include $(RIOTBOARD)/common/atmega/Makefile.include diff --git a/makefiles/tools/avrdude.inc.mk b/makefiles/tools/avrdude.inc.mk index 97c283a27b..17b7810dc9 100644 --- a/makefiles/tools/avrdude.inc.mk +++ b/makefiles/tools/avrdude.inc.mk @@ -3,8 +3,19 @@ DIST_PATH = $(BOARDSDIR)/$(BOARD)/dist AVARICE_PATH = $(RIOTTOOLS)/avarice DEBUGSERVER_PORT = 4242 DEBUGSERVER = $(AVARICE_PATH)/debug_srv.sh -DEBUGSERVER_INTERFACE ?= -DEBUGSERVER_FLAGS = "-g -j usb $(DEBUGSERVER_INTERFACE) :$(DEBUGSERVER_PORT)" +# Allow choosing debugger hardware via AVR_DEBUGDEVICE, default to Atmel ICE, +# which is compatible to all AVR devices and since the AVR Dragon is no longer +# produced, the least expensive option +AVR_DEBUGDEVICE ?= --edbg +AVR_DEBUGINTERFACE ?= usb +ifneq (,$(filter $(CPU),atmega328p)) + # Use debugWIRE as protocol for debugging (ATmega328P does not support JTAG) + DEBUGPROTO := -w +else + # Use JTAG as protocol for debugging + DEBUGPROTO := -j $(AVR_DEBUGINTERFACE) +endif +DEBUGSERVER_FLAGS = "$(AVR_DEBUGDEVICE) $(DEBUGPROTO) :$(DEBUGSERVER_PORT)" DEBUGGER_FLAGS = "-x $(AVARICE_PATH)/gdb.conf $(ELFFILE)" DEBUGGER = "$(AVARICE_PATH)/debug.sh" $(DEBUGSERVER_FLAGS) $(AVARICE_PATH) $(DEBUGSERVER_PORT) From a9fc84cc04889d123558abbb61ac04532173b60d Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 27 Mar 2019 16:02:02 +0100 Subject: [PATCH 3/9] boards/arduino-uno: Added documentation for OCD --- boards/arduino-uno/doc.txt | 146 ++++++++++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 17 deletions(-) diff --git a/boards/arduino-uno/doc.txt b/boards/arduino-uno/doc.txt index 00d4ff6436..8d67e273aa 100644 --- a/boards/arduino-uno/doc.txt +++ b/boards/arduino-uno/doc.txt @@ -10,21 +10,21 @@ electronics and embedded coding. It is based on Atmel's AVR architecture and sports an ATmega328p MCU. It is like many Arduinos extensible by using shields. ### MCU -| MCU | ATmega328p | -|:------------- |:--------------------- | -| Family | AVR/ATmega | -| Vendor | Atmel | -| RAM | 2Kb | -| Flash | 32Kb | -| Frequency | 16MHz | -| Timers | 3 (2x 8bit, 1x 16bit) | -| ADCs | 6 analog input pins | -| UARTs | 1 | -| SPIs | 1 | -| I2Cs | 1 (called TWI) | -| Vcc | 5.0V | -| Datasheet / Reference Manual | [Datasheet and Reference Manual](http://www.atmel.com/images/atmel-8271-8-bit-avr-microcontroller-atmega48a-48pa-88a-88pa-168a-168pa-328-328p_datasheet_complete.pdf) | -| Board Manual | [Board Manual](https://www.arduino.cc/en/Main/ArduinoBoardUno)| +| MCU | ATmega328p | +|:---------------------------- |:--------------------- | +| Family | AVR/ATmega | +| Vendor | Atmel/Microchip | +| RAM | 2 KiB | +| Flash | 32 KiB | +| Frequency | 16 MHz | +| Timers | 3 (2x 8bit, 1x 16bit) | +| ADCs | 6 analog input pins | +| UARTs | 1 | +| SPIs | 1 | +| I2Cs | 1 (called TWI) | +| Vcc | 5.0 V | +| Datasheet / Reference Manual | [Datasheet and Reference Manual](http://www.atmel.com/images/atmel-8271-8-bit-avr-microcontroller-atmega48a-48pa-88a-88pa-168a-168pa-328-328p_datasheet_complete.pdf) | +| Board Manual | [Board Manual](https://www.arduino.cc/en/Main/ArduinoBoardUno) | ## Flashing the device Flashing RIOT on the Arduino Uno is quite straight forward, just connect your @@ -42,6 +42,118 @@ flash More pins can be used for hardware interrupts using the Pin Change Interrupt feature. See @ref boards_common_atmega for details. -##Caution +## Caution Don't expect having a working network stack due to very limited resources. - */ + +## On-Chip Debugging +On-Chip Debugging on the Arduino Uno is not supported via the usual JTAG +interface used in ATmega MCUs with higher pin counts, but via debugWIRE. While +debugWIRE has the advantage of only using the RESET pin to transfer data, the +features provided are extremely limited. If the same issue can be reproduced on +an Arduino Mega2560, which supports JTAG, it will be much easier and more +productive to debug your code on the Arduino Mega2560. If the bug cannot be +reproduced, limited on chip debugging is possible on the Arduino Uno +nonetheless. + +### Prerequisites +#### Debugging Hardware +In order to be able to use On-Chip Debugging you will need the AVR Dragon, which +is the ~~cheapest~~ least expensive programmer and debugger available that +supports programming via SPI ("normal ISP"), High Voltage Serial Programming, +and Parallel Programming, as well as debugging via JTAG, debugWIRE, PDI and +aWire. So at least can use it for just about every AVR device. + +#### Board Modifications +On the Arduino Uno the RESET pin of the MCU is connected to a 100 nF capacitor, +which in turn is connected to the ATmega16U2 (or an CH340 TTL Adapter in case of +most clones). This allows the device to be automatically reseted when you +connected to the board via a serial. This is particularly useful during +programming via the bootloader (without external ISP programmer), as avrdude +can trigger the reset and, thus, start the bootloader without the user having +to press a button. + +In order to use on-chip debugging, the capacitor needs however to be +disconnected from the reset pin. With the original Arduino Uno this can be done +by cutting the solder jumper labeled "RESET EN". This can easily be resoldered +to restore the original state. Most clones do not have this solder jumper and +you will likely have to break off the usually surface mounted capacitor. A +multimeter can be used to detect which capacitor is connected to the reset pin. +Keep in mind that the capacitor will likely be destroyed when removed by force +and it will be difficult to restore the auto-reset feature of the clones. + +#### Software +You need to have [AVaRICE](http://avarice.sourceforge.net/) installed. Some +distros have this packaged already. If you need to compile it by hand, go for +the latest SVN revision. The latest release cannot be compiled on anything but +historic platforms and contains bugs that prevent it from debugging the +ATmega328P anyway. + +#### Fuses +In order to use On-Chip Debugging, the `DWEN` bit in the high fuse needs to be +enabled (set to zero). The exact fuse settings for debugging and the default +fuse setting are these: + +| Fuse | Default Setting | Debug Setting | +|:------------- |:--------------- |:------------- | +| Low Fuse | `0xFF` | `0xFF` | +| High Fuse | `0xDE` | `0x9E` | +| Extended Fuse | `0xFD` | `0xFD` | + +You can enable debugWIRE debugging by running (replace `` by the +name of your programmer, e.g. `dragon_isp` in case of the AVR Dragon): + + avrdude -p m328p -c -U hfuse:w:0x9e:m + +And disable debugging via: + + avrdude -p m328p -c -U hfuse:w:0xde:m + + +@note You can use a different ISP to enable debugging, but disabling it + again will only work with the AVR Dragon: The ISP will require the RESET + pin to work, but the RESET pin is re-purposed for debugWIRE when + debugging is enabled. Recent versions of avrdude will use the debugWIRE + interface to temporarily disable debugWIRE and restore the RESET pin's + default behavior in order to use the ISP. But this requires a + programmer/debugger that can be used as both ISP and debugWIRE debugger + using the same connector. So don't enable debugging unless you have an + AVR Dragon or another plan on how to disable debugging again. + +### Debugging +With the AVR Dragon, debugging is as simple as running: + + make BOARD=arduino-uno debug + +@warning For flashing the device via ISP, avrdude will temporarily disable + debugWIRE. If AVaRICE complains that synchronization with the device + is not possible after having it flashed, the device might need a + cold boot to enable debugWIRE again. + +The memory map of the ELF file does not take the bootloader into account. The +author of this text used an ISP to program the Arduino Uno during debugging to +avoid any issues. You might want to do the same, e.g. via: + + make BOARD=arduino-uno PROGRAMMER=dragon_isp flash + +@warning Flashing via ISP overwrites the bootloader. But you can restore it + easily using the ISP. Consult the Arduino documentation on how to + restore the bootloader. + +@note If you are using a different debugger than the AVR Dragon, you have + to export the `AVR_DEBUGDEVICE` environment variable to the required + flag to pass to AVaRICE, e.g. when using the Atmel-ICE you have to + export `AVR_DEBUGDEVICE=--edbg`. If the debug device is not + connected via USB, you also need to export `AVR_DEBUGINTERFACE` to + the correct value. + +### Breakpoints / Watchpoints +The ATmega328P only has a single hardware break point and zero watchpoints. The +single hardware breakpoint is used for single-stepping. As a result neither +breakpoints nor watchpoints can be used. AVaRICE tries to emulate breakpoints +be inserting the break machine instruction into the ROM in place of the +original instruction to break on. Once this break instruction is reached, the +original instruction is restored. This is not only super slow, but also +wastes two flash cycles every time a breakpoint is hit. This cumulates to +significant flash wear during long debugging sessions. + +*/ From 72e497c0c3f664789fda9da7997a7ed739a29cda Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Fri, 25 Oct 2019 14:15:39 +0200 Subject: [PATCH 4/9] boards/microduino-corerf: Added OCD doc --- boards/microduino-corerf/doc.txt | 70 ++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/boards/microduino-corerf/doc.txt b/boards/microduino-corerf/doc.txt index 2c6fc8a476..ab371fad21 100644 --- a/boards/microduino-corerf/doc.txt +++ b/boards/microduino-corerf/doc.txt @@ -100,4 +100,74 @@ as system clock source. More pins can be used for hardware interrupts using the Pin Change Interrupt feature. See @ref boards_common_atmega for details. +## Debugging +The ATmega128RFR1 supports JTAG debugging. To use the JTAG debugging an external +JTAG debugger is required. There are several options for this MCU/board: + +* [AVR JTAGICE mkII](http://www.atmel.com/tools/avrjtagicemkii.aspx) +* [JTAGICE3](http://www.atmel.com/tools/jtagice3.aspx) +* [AVR Dragon](http://www.atmel.com/tools/avrdragon.aspx) + +Hint: The AVR Dragon is the ~~cheapest~~ least expensive debugger and also is +compatible with almost every AVR MCU. + +@warning With the default fuse settings, on chip debugging is disabled. + +@note If you are using a different debugger than the AVR Dragon, you have + to export the `AVR_DEBUGDEVICE` environment variable to the required + flag to pass to AVaRICE, e.g. when using the Atmel-ICE you have to + export `AVR_DEBUGDEVICE=--edbg`. If the debug device is not + connected via USB, you also need to export `AVR_DEBUGINTERFACE` to + the correct value. + + +### JTAG Pin Mapping + +| Pin | Pin Label | Signal | AVR Dragon Pin | +|:------|:----------|:----------|:------------------| +| PF7 | A0 | TDI | JTAG-9 | +| PF6 | A1 | TDO | JTAG-3 | +| PF5 | A2 | TMS | JTAG-5 | +| PF4 | A3 | TCK | JTAG-1 | +| VDD | 3V3 | VTG | JTAG-4 | +| GND | GND | GND | JTAG-2 | + +### Fuse Settings + +Be aware that changing the fuse settings can "brick" your MCU, e.g. if you +select a different clock setting that is not available on your board. Or if +you disable all options for programming the MCU. + +You can always de-brick your MCU using high voltage programming mode, which can +also be done using the AVR Dragon. But being careful to not brick your MCU in +the first place is clearly the better option ;-) + +In the following it is assumed that you connect the Dragon ISP header to the +Microduino CoreRF for ISP programming. + +#### Default Fuse Settings + +The default fuse settings of the Microduino CoreRF are: `E:F5, H:DA, L:FF`. +These settings can be restored via from the OCD settings via: + +``` +avrdude -c dragon_isp -p m128rfa1 -U hfuse:w:0xda:m +``` + +If you touched other fuse settings, you can restore the fuse settings using: + +``` +avrdude -c dragon_isp -p m128rfa1 -U efuse:w:0xf5:m -U hfuse:w:0xda:m -U lfuse:w:0xff:m +``` + +### On-Chip Debugging Fuse Settings + +To enable on-chip debugging, the `JTAGEN` (enable JTAG) and the `OCDEN` (enable +on-chip debugging) bits should be set: `E:F5, H:1A, L:FF`. This can be done +(when starting with the default settings) via: + +``` +avrdude -c dragon_isp -p m128rfa1 -U hfuse:w:0x1a:m +``` + */ From fd602407c922113f745477b1dd97e02038078134 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Sun, 17 Nov 2019 15:50:30 +0100 Subject: [PATCH 5/9] boards/atmega1284p: Extended doc with OCD info Added details on On-Chip Debugging (OCD) to the ATmega1284P documentation. --- boards/atmega1284p/doc.txt | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/boards/atmega1284p/doc.txt b/boards/atmega1284p/doc.txt index f9c77879b1..e0b5dbabb6 100644 --- a/boards/atmega1284p/doc.txt +++ b/boards/atmega1284p/doc.txt @@ -98,4 +98,51 @@ Connect a TTL adapter with pins 14/RXD0 and 15/TXD0 an run Please note that the supply voltage should be compatible with the logic level of the TTL adapter. Usually everything between 3.3 V and 5 V should work. +## On-Chip Debugging + +In order to debug the ATmega1284P, an compatible debugger is needed. The AVR +Dragon is the ~~cheapest~~ least expensive option currently available. (But at +least it can program and debug pretty much all AVRs and can even be used to +de-brick ATmega MCUs using high voltage programming.) + +Once the AVR Dragon is correctly connected, the ATmega1284P has the JTAG +interface enabled, and the required software is installed, debugging can be +started using + + make debug + +@note If you are using a different debugger than the AVR Dragon, you have + to export the `AVR_DEBUGDEVICE` environment variable to the required + flag to pass to AVaRICE, e.g. when using the Atmel-ICE you have to + export `AVR_DEBUGDEVICE=--edbg`. If the debug device is not + connected via USB, you also need to export `AVR_DEBUGINTERFACE` to + the correct value. + +#### Software Requirements + +In order to debug you'll need an GDB version with AVR support and +[AVaRICE](http://avarice.sourceforge.net/). Note that AVaRICE sadly is not +being actively maintained and the latest release will not compile on most +systems. Thus, unless your distribution already ships a package of the SVN +version of AVaRICE, you'll have to build the tool from source. + +### JTAG Pin Mapping + +| Pin Name | Pin | Signal | AVR Dragon Pin | +|:----------|:------|:----------|:------------------| +| PC5 | 27 | TDI | JTAG-9 | +| PC4 | 26 | TDO | JTAG-3 | +| PC3 | 25 | TMS | JTAG-5 | +| PC2 | 24 | TCK | JTAG-1 | +| VCC | 10 | VTG | JTAG-4 | +| GND | 11 | GND | JTAG-2 | + +### Fuse Settings + +The `JTAGEN` fuse has to be set in order to use the JTAG interface. The JTAG +pins will no longer be available as GPIOs when this fuse is set. With the +default settings the MCUs are preprogrammed during manufacturing, the `JTAGEN` +fuse is already set. So with a new and unused package, you're ready directly +ready to go. + */ From 8a89918a73a5f34059200bfd68679f49fec9206c Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Sun, 17 Nov 2019 23:55:28 +0100 Subject: [PATCH 6/9] boards/atmega328p: Added doc on OCD Explained how to do On-Chip Debugging (OCD) with the ATmega328P on a breadboard. --- boards/arduino-uno/doc.txt | 2 +- boards/atmega328p/doc.txt | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/boards/arduino-uno/doc.txt b/boards/arduino-uno/doc.txt index 8d67e273aa..63d307b252 100644 --- a/boards/arduino-uno/doc.txt +++ b/boards/arduino-uno/doc.txt @@ -66,7 +66,7 @@ aWire. So at least can use it for just about every AVR device. #### Board Modifications On the Arduino Uno the RESET pin of the MCU is connected to a 100 nF capacitor, which in turn is connected to the ATmega16U2 (or an CH340 TTL Adapter in case of -most clones). This allows the device to be automatically reseted when you +most clones). This allows the device to be automatically reset when you connected to the board via a serial. This is particularly useful during programming via the bootloader (without external ISP programmer), as avrdude can trigger the reset and, thus, start the bootloader without the user having diff --git a/boards/atmega328p/doc.txt b/boards/atmega328p/doc.txt index f140872d79..2e2d61e982 100644 --- a/boards/atmega328p/doc.txt +++ b/boards/atmega328p/doc.txt @@ -109,6 +109,53 @@ Connect a TTL adapter with pins 2/RXD and 3/TXD an run Please note that the supply voltage should be compatible with the logic level of the TTL adapter. Usually everything between 3.3 V and 5 V should work. +## On-Chip Debugging (OCD) + +E.g. with the AVR Dragon and [AVaRICE](http://avarice.sourceforge.net/) you +can debug the ATmega328P using the debugWIRE interface. Compared to the ATmega +MCUs with JTAG interface the debug facilities are however significantly reduced: +Only a single hardware breakpoint and no watchpoints are supported. The +hardware breakpoint is used for single-stepping. If you set breakpoints, the +AVR Dragon will transparently replace the instruction to break upon with a +break instruction. Once the breakpoint is hit, the break instruction is +overwritten with the original instruction. Thus, every breakpoint hit cause two +flash cycles to be performed, which not only results in a slow debugging +experience, but also causes significant wear. + +In order to enable debugWIRE run (replace `` with the programmer you +use, e.g. with `dragon_isp` if you use the AVR Dragon): + + avrdude -c -p m328p -U hfuse:w:0x99:m + +You can disable it again via: + + avrdude -c -p m328p -U hfuse:w:0xd9:m + +@warning As the reset pin is repurposed for debugWIRE, a regular ISP will + not be able to disable the debugWIRE interface anymore. The AVR + Dragon can temporary disable the debugWIRE interface via a + debugWIRE command and avrdude will do so when debugWIRE is used. + So only enable debugWIRE if you have an AVR DRagon or other means + to disable debugWIRE later on again. + +For debugging, the ATmega328P needs to be connected to the AVR Dragon in the +very same way it needs to be connected for programming (see above). Once the +MCU is connected and debugWIRE is enabled via the fuse settings, you can start +debugging via: + + make debug + +If this fails after flashing the ATmega328P, it is like due to debugWIRE +being temporary disabled by avrdude in order to use the ISP feature. Perform a +cold boot and the ATmega328P will have debugWIRE enabled again. + +@note If you are using a different debugger than the AVR Dragon, you have + to export the `AVR_DEBUGDEVICE` environment variable to the required + flag to pass to AVaRICE, e.g. when using the Atmel-ICE you have to + export `AVR_DEBUGDEVICE=--edbg`. If the debug device is not + connected via USB, you also need to export `AVR_DEBUGINTERFACE` to + the correct value. + ## Caution Don't expect having a working network stack due to very limited resources ;-) */ From e97ae8ba6c76170fd1cc60843d3c306e712d6c14 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 4 Dec 2019 10:49:22 +0100 Subject: [PATCH 7/9] boards/arduino-nano: Added doc on debugging --- boards/arduino-nano/doc.txt | 98 +++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/boards/arduino-nano/doc.txt b/boards/arduino-nano/doc.txt index a1948ebe7d..ee69daa39f 100644 --- a/boards/arduino-nano/doc.txt +++ b/boards/arduino-nano/doc.txt @@ -59,6 +59,104 @@ If RIOT is stuck in a reboot loop e.g. after restarting the device with the [issue with the stock bootloader](https://forum.arduino.cc/index.php?topic=150419.0) that can be solved by using Optiboot as bootloader instead (see above). +## On-Chip Debugging +On-Chip Debugging on the Arduino Nano is not supported via the usual JTAG +interface used in ATmega MCUs with higher pin counts, but via debugWIRE. While +debugWIRE has the advantage of only using the RESET pin to transfer data, the +features provided are extremely limited. If the same issue can be reproduced on +an Arduino Mega2560, which supports JTAG, it will be much easier and more +productive to debug your code on the Arduino Mega2560. If the bug cannot be +reproduced, limited on chip debugging is possible on the Arduino Nano +nonetheless. + +### Prerequisites +#### Debugging Hardware +In order to be able to use On-Chip Debugging you will need the AVR Dragon, which +is the ~~cheapest~~ least expensive programmer and debugger available that +supports programming via SPI ("normal ISP"), High Voltage Serial Programming, +and Parallel Programming, as well as debugging via JTAG, debugWIRE, PDI and +aWire. So at least can use it for just about every AVR device. + +#### Board Modifications +On the Arduino Nano the RESET pin of the MCU is connected to a 100 nF capacitor, +which in turn is connected to the DTR pin of the FT232RL USB-UART bridge. This +allows the device to be automatically reset when you connected to the board +via a serial. This is particularly useful during programming via the bootloader +(without external ISP programmer), as avrdude can trigger the reset and, thus, +start the bootloader without the user having to press a button. + +In order to use on-chip debugging, the capacitor needs however to be +disconnected from the reset pin. You can either carefully de-solder it (which +allows you to solder it back in after debugging), or just break it off with +pinch-nose pliers (which usually destroys the capacitor, making the modification +permanent). After this modification, flashing via bootloader requires a manual +press on the reset button. + +#### Software +You need to have [AVaRICE](http://avarice.sourceforge.net/) installed. Some +distros have this packaged already. If you need to compile it by hand, go for +the latest SVN revision. The latest release cannot be compiled on anything but +historic platforms and contains bugs that prevent it from debugging the +ATmega328P anyway. + +#### Fuses +In order to use On-Chip Debugging, the `DWEN` bit in the high fuse needs to be +enabled (set to zero). The exact fuse settings for debugging and the default +fuse setting are these: + +| Fuse | Default Setting | Debug Setting | +|:------------- |:--------------- |:------------- | +| Low Fuse | `0xFF` | `0xFF` | +| High Fuse | `0xDA` | `0x9A` | +| Extended Fuse | `0xFD` | `0xFD` | + +You can enable debugWIRE debugging by running (replace `` by the +name of your programmer, e.g. `dragon_isp` in case of the AVR Dragon): + + avrdude -p m328p -c -U hfuse:w:0x9a:m + +And disable debugging via: + + avrdude -p m328p -c -U hfuse:w:0xda:m + + +@note You can use a different ISP to enable debugging, but disabling it + again will only work with the AVR Dragon: The ISP will require the RESET + pin to work, but the RESET pin is re-purposed for debugWIRE when + debugging is enabled. Recent versions of avrdude will use the debugWIRE + interface to temporarily disable debugWIRE and restore the RESET pin's + default behavior in order to use the ISP. But this requires a + programmer/debugger that can be used as both ISP and debugWIRE debugger + using the same connector. So don't enable debugging unless you have an + AVR Dragon or another plan on how to disable debugging again. + +### Debugging +With the AVR Dragon, debugging is as simple as running: + + make BOARD=arduino-nano debug + +@warning For flashing the device via ISP, avrdude will temporarily disable + debugWIRE. If AVaRICE complains that synchronization with the device + is not possible after having it flashed, the device might need a + cold boot to enable debugWIRE again. + +The memory map of the ELF file does not take the bootloader into account. The +author of this text used an ISP to program the Arduino Nano during debugging to +avoid any issues. You might want to do the same, e.g. via: + + make BOARD=arduino-nano PROGRAMMER=dragon_isp flash + +@warning Flashing via ISP overwrites the bootloader. But you can restore it + easily using the ISP. Consult the Arduino documentation on how to + restore the bootloader. + +@note If you are using a different debugger than the AVR Dragon, you have + to export the `AVR_DEBUGDEVICE` environment variable to the required + flag to pass to AVaRICE, e.g. when using the Atmel-ICE you have to + export `AVR_DEBUGDEVICE=--edbg`. If the debug device is not + connected via USB, you also need to export `AVR_DEBUGINTERFACE` to + the correct value. + ## Caution Don't expect having a working network stack due to very limited resources. */ From 793e1122ebf001f8aadac318272415c54aca85e1 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 4 Dec 2019 10:51:21 +0100 Subject: [PATCH 8/9] boards/arduino-mega2560: Updated documentaiton - Extended documentation regarding debugging - Removed outdated board state tracking list. (All periphs are now supported) - Made table code pretty --- boards/arduino-mega2560/doc.txt | 56 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/boards/arduino-mega2560/doc.txt b/boards/arduino-mega2560/doc.txt index b598da89c9..b28636c698 100644 --- a/boards/arduino-mega2560/doc.txt +++ b/boards/arduino-mega2560/doc.txt @@ -19,21 +19,22 @@ again. ![Arduino Mega2560](https://store-cdn.arduino.cc/uni/catalog/product/cache/1/image/500x375/f8876a31b63532bbba4e781c30024a0a/a/0/a000067_front_1_.jpg) ### MCU -| MCU | ATmega2560 | -|:------------- |:--------------------- | -| Family | AVR/ATmega | -| Vendor | Atmel | -| RAM | 8Kb | -| Flash | 256Kb | -| Frequency | 16MHz | -| Timers | 6 (2x 8bit, 4x 16bit) | -| ADCs | 14 analog input pins (10bit resolution| -| UARTs | 4 | -| SPIs | 1 | -| I2Cs | 1 (called TWI) | -| Vcc | 5.0V | -| Datasheet / Reference Manual | [Datasheet and Reference Manual](http://www.atmel.com/images/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf) | -| Board Manual | [Board Manual](http://arduino.cc/en/Main/arduinoBoardMega2560)| + +| MCU | ATmega2560 | +|:----------------------------- |:----------------------------------------- | +| Family | AVR/ATmega | +| Vendor | Atmel | +| RAM | 8 KiB | +| Flash | 256 KiB | +| Frequency | 16 MHz | +| Timers | 6 (2x 8bit, 4x 16bit) | +| ADCs | 14 analog input pins (10bit resolution) | +| UARTs | 4 | +| SPIs | 1 | +| I2Cs | 1 (called TWI) | +| Vcc | 5.0 V | +| Datasheet / Reference Manual | [Datasheet and Reference Manual](http://www.atmel.com/images/atmel-2549-8-bit-avr-microcontroller-atmega640-1280-1281-2560-2561_datasheet.pdf) | +| Board Manual | [Board Manual](http://arduino.cc/en/Main/arduinoBoardMega2560) | Flashing RIOT on the Arduino Mega2560 is quite straight forward, just connect your Arduino Mega2560 using the programming port to your host computer and type: @@ -50,23 +51,17 @@ flash More pins can be used for hardware interrupts using the Pin Change Interrupt feature. See @ref boards_common_atmega for details. -## State -While there is basic support in RIOT, there are still some parts missing: -* Timer implementation needs love (ideally simulate a 32bit timer by adding -an overflow counter to the implementation) -* LPM driver missing -* ~~SPI driver missing~~ (See https://github.com/RIOT-OS/RIOT/pull/4045) -* I2C/TWI driver missing -* ADC driver missing -* PWM driver missing - ## Debugging (WIP) The ATmega2560 MCU supports JTAG debugging. To use the JTAG debugging on the Arduino Mega 2560 an external JTAG debugger is required. There are several options for this MCU/board: + * [Atmel-ICE](https://www.microchip.com/DevelopmentTools/ProductDetails/atatmel-ice) + (Note: A version of the Atmel-ICE without case (just the naked but fully + assembled PCB) is currently the most affordable option. + * [AVR Dragon](http://www.atmel.com/tools/avrdragon.aspx) + (Note: This debugger is out of production.) * [AVR JTAGICE mkII](http://www.atmel.com/tools/avrjtagicemkii.aspx) * [JTAGICE3](http://www.atmel.com/tools/jtagice3.aspx) - * [AVR Dragon](http://www.atmel.com/tools/avrdragon.aspx) There may be other options as well, but I can't comment on how well they work. I tested debugging RIOT on the Arduino Mega 2560 using an AVR Dragon. @@ -142,8 +137,6 @@ calculator](http://www.engbedded.com/fusecalc/), which also works with other AVR MCUs. ### Debugging RIOT on the Arduino Mega 2560 -With PR [#1696](https://github.com/RIOT-OS/RIOT/pull/1696) merged the -following commands should work for debugging: `make BOARD=arduino-mega2560 debug-server`: starts an [avarice](http://avarice.sourceforge.net/) (avarice needs to be installed) @@ -158,6 +151,13 @@ For a full rebuild and debug cycle use the following command: `make BOARD=arduino-mega2560 PROGRAMMER=dragon_isp clean all flash debug` +@note If you are using a different debugger than the Atmel-ICE, you have + to export the `AVR_DEBUGDEVICE` environment variable to the required + flag to pass to AVaRICE, e.g. when using the AVR Dragon you have to + export `AVR_DEBUGDEVICE=--dragon`. If the debug device is not + connected via USB, you also need to export `AVR_DEBUGINTERFACE` to + the correct value. + # Mac OSX El Capitan users Mac users can flash this Arduino board by installing `avr-gcc` and `avrdude` from `brew`. From fa189c4c1dedeb284c5ad3e34655e2d805b02d05 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Wed, 11 Mar 2020 10:51:40 +0100 Subject: [PATCH 9/9] dist/tools/avarice: Detect GDB automatically While some users likely still use avr-gdb, more and more systems are starting to use gdb-multiarch. In order to work in both cases, the script now just checks which version is installed. (If both are installed, gdb-multiarch is preferred.) --- dist/tools/avarice/debug.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dist/tools/avarice/debug.sh b/dist/tools/avarice/debug.sh index d1fb3d67ea..888ca97020 100755 --- a/dist/tools/avarice/debug.sh +++ b/dist/tools/avarice/debug.sh @@ -3,9 +3,18 @@ # The setsid command is needed so that Ctrl+C in GDB doesn't kill avarice : ${SETSID:=setsid} +if gdb-multiarch -v > /dev/null; then + GDB=gdb-multiarch +elif avr-gdb -v > /dev/null; then + GDB=avr-gdb +else + echo "Couldn't find multiarch GDB or AVR GDB. Check \$PATH." + exit 1 +fi + sleep 2 ${SETSID} -w avarice $1 & -sleep 3 && avr-gdb -ex "target remote localhost:$3" $4 +sleep 3 && $GDB -ex "target remote localhost:$3" $4 # avarice exits with 1 if the connection is released, therefore we always exit with 0 exit 0