1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-25 20:02:37 +03:00
Earle F. Philhower, III bff3a6d963 GDB support w/new toolchain and UART driver (#5559)
* Add full gdb support with uart/Serial integration

* Fix GDB merge errors

* Update to unpatched GDB protocol specification

It appears that Espressif patched the open source xtensa GDB port in
order to build their old GDB executable and their old gdbstub (basically
removing any register in a generic xtensa and only leaving those
present in the chip they synthesized).  Their GDBStub also assumed this
behavior.

Unpatched upstream GNU GDB now expects all the registers in
xtensa-config.c to be sent/read on a 'g' command.  Change the GDB stub
to send "xxxxxxxx"s (legal per the spec) for unimplemented registers.
This makes the 'g' response much longer, but it's results are cached
and in an interactive debugger it isn't noticeable.

* Fix .iram.literal to come before .iram.text for GDB

* Move functions to flash, call using wrappers

All functions which are not interrupt or exception called are now in
flash. A small IRAM wrapper enables flash when processing main GDB ops
by calling Cache_Read_Enable_New() and then jumping to the main flash
code.  This seems to work for catching exceptions, data and code breaks,
and Ctrl-C.

The UART ISR handler and exception handler register-saving bits of
code in ASM are still in IRAM.

GDB IRAM usage is now about 670 bytes.

* Remove LWIP2 builder commit

* Add documentation and gdbstub_init header

Add some simple GDB documentation to the main tree showing a worked
example.

Adds the definition of `void gdbstub_init()` to <GDBStub.h>

* Clean up GDB include and library dir

Replace GDBstub.h with the version in the internal/ directory, and
adjust stub code accordingly.  This way, only one copy of a file called
"GDBstub.h" will exist.

Update the gdbcommands and replace the obsolete ESPRESSIF readme with
@kylefleming's version since we're mainly doing serial, not TCP,
connected debugging.

Bump the library rev. number since this is a pretty big functionality
change.

Minor documentation tweak.

* Undo much of UART refactoring, set fifo IRQ to 16

Remove the refactoring of pin control and other little things not directly
related to GDB processing.  Should greatly reduce the diff size in uart.c.
Should also remove any register value changes (intended or otherwise)
introduced in the original PR from @kylefleming.

Set the FIFO interrupt to 16 chars when in GDB mode, matching the latest
UART configuration for highest speed.

* Add architecture comments, cleanup uart.c code

Comments added to UART.c trying to explain (as best as I understand it)
the changes done to support GDB and how they interact with standard
operation.

Fix the uart_uninit to stop the ISR and then free appropriately.

Fix uart_isr_handle_data (GDB's shim for sending chars to the 8266 app)
to do the exact same thing as the standard UART handler including set
the overflow properly and either discard or overwrite in that case.

Fix serial reception when GDB enabled by enabling the user recv ISR.

Remove commented attributes from gdbstub, leftover from the move to
flash.

General logic cleanup per comments in the PR.

* Also set the UART flags for HW error in GDB

Ensure we also check the UART flags and set the uart status
appropriately when in GDB mode.
2019-01-23 17:51:35 -03:00

70 lines
4.3 KiB
Markdown

GDBSTUB
=======
Intro
-----
While the ESP8266 supports the standard Gnu set of C programming utilities, for now the choice of debuggers
has been limited: there is an attempt at [OpenOCD support](https://github.com/projectgus/openocd), but at
the time of writing, it doesn't support hardware watchpoints and breakpoints yet, and it needs a separate
JTAG adapter connecting to the ESP8266s JTAG pins. As an alternative, [Cesanta](https://www.cesanta.com/)
has implemented a barebones[GDB stub](https://blog.cesanta.com/esp8266-gdb) in their Smart.js solution -
unfortunately, this only supports exception catching and needs some work before you can use it outside of
the Smart.js platform. Moreover, it also does not work with FreeRTOS.
For internal use, we at Espressif desired a GDB stub that works with FreeRTOS and is a bit more capable,
so we designed our own implementation of it. This stub works both under FreeRTOS as well as the OS-less
SDK and is able to catch exceptions and do backtraces on them, read and write memory, forward [os_]printf
statements to gdb, single-step instructions and set hardware break- and watchpoints. It connects to the
host machine (which runs gdb) using the standard serial connection that's also used for programming.
In order to be useful the gdbstub has to be used in conjunction with an xtensa-lx106-elf-gdb, for example
as generated by the [esp-open-sdk](https://github.com/pfalcon/esp-open-sdk) project.
Usage
-----
* Grab the gdbstub project and put the files in a directory called 'gdbstub' in your project. You can do this
either by checking out the Git repo, or adding the Git repo as a submodule to your project if it's already
in Git.
* Modify your Makefile. You'll need to include the gdbstub sources: if your Makefile is structured like the
ones in the Espressif examples, you can add `gdbstub` to the `SUBDIRS` define and `gdbstub/libgdbstub.a` to the
`COMPONENTS_eagle.app.v6` define. Also, you probably want to add `-ggdb` to your compiler flags (`TARGET_LDFLAGS`)
and, if you are debugging, change any optimation flags (-Os, -O2 etc) into `-Og`. Finally, make sure your Makefile
also compiles .S files.
* Configure gdbstub by editting `gdbstub-cfg.h`. There are a bunch of options you can tweak: FreeRTOS or bare SDK,
private exception/breakpoint stack, console redirection to GDB, wait till debugger attachment etc. You can also
configure the options by including the proper -Dwhatever gcc flags in your Makefiles.
* In your user_main.c, add an `#include <../gdbstub/gdbstub.h>` and call `gdbstub_init();` somewhere in user_main.
* Compile and flash your board.
* Run gdb, depending on your configuration immediately after resetting the board or after it has run into
an exception. The easiest way to do it is to use the provided script: xtensa-lx106-elf-gdb -x gdbcmds -b 38400
Change the '38400' into the baud rate your code uses. You may need to change the gdbcmds script to fit the
configuration of your hardware and build environment.
Notes
-----
* Using software breakpoints ('br') only works on code that's in RAM. Code in flash can only have a hardware
breakpoint ('hbr').
* Due to hardware limitations, only one hardware breakpount and one hardware watchpoint are available.
* Pressing control-C to interrupt the running program depends on gdbstub hooking the UART interrupt.
If some code re-hooks this afterwards, gdbstub won't be able to receive characters. If gdbstub handles
the interrupt, the user code will not receive any characters.
* Continuing from an exception is not (yet) supported in FreeRTOS mode.
* The WiFi hardware is designed to be serviced by software periodically. It has some buffers so it
will behave OK when some data comes in while the processor is busy, but these buffers are not infinite.
If the WiFi hardware receives lots of data while the debugger has stopped the CPU, it is bound
to crash. This will happen mostly when working with UDP and/or ICMP; TCP-connections in general will
not send much more data when the other side doesn't send any ACKs.
License
-------
This gdbstub is licensed under the Espressif MIT license, as described in the License file.
Thanks
------
* Cesanta, for their initial ESP8266 exception handling only gdbstub,
* jcmvbkbc, for providing an incompatible but interesting gdbstub for other Xtensa CPUs,
* Sysprogs (makers of VisualGDB), for their suggestions and bugreports.