OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [docs/] [userguide/] [debugging_with_ocd.adoc] - Blame information for rev 69

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 69 zero_gravi
<<<
2
:sectnums:
3
== Debugging using the On-Chip Debugger
4
 
5
The NEORV32 on-chip debugger allows _online_ in-system debugging via an external JTAG access port from a
6
host machine. The general flow is independent of the host machine's operating system. However, this tutorial uses
7
Windows and Linux (Ubuntu on Windows) in parallel.
8
 
9
[TIP]
10
See datasheet section https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd[On Chip Debugger (OCD)]
11
for more information.
12
 
13
[NOTE]
14
This tutorial uses `gdb` to **directly upload an executable** to the processor. If you are using the default
15
processor setup _with_ internal instruction memory (IMEM) make sure it is implemented as RAM
16
(_INT_BOOTLOADER_EN_ generic = true).
17
 
18
[IMPORTANT]
19
The on-chip debugger is only implemented if the _ON_CHIP_DEBUGGER_EN_ generic is set _true_. Furthermore, it requires
20
the `Zicsr` and `Zifencei` CPU extension to be implemented (top generics _CPU_EXTENSION_RISCV_Zicsr_
21
and _CPU_EXTENSION_RISCV_Zifencei_ = true).
22
 
23
 
24
:sectnums:
25
=== Hardware Requirements
26
 
27
Make sure the on-chip debugger of your NEORV32 setups is implemented (_ON_CHIP_DEBUGGER_EN_ generic = true).
28
Connect a JTAG adapter to the NEORV32 `jtag_*` interface signals. If you do not have a full-scale JTAG adapter, you can
29
also use a FTDI-based adapter like the "FT2232H-56Q Mini Module", which is a simple and inexpensive FTDI breakout board.
30
 
31
.JTAG pin mapping
32
[cols="^3,^2,^2"]
33
[options="header",grid="rows"]
34
|=======================
35
| NEORV32 top signal | JTAG signal | FTDI port
36
| `jtag_tck_i`       | TCK         | D0
37
| `jtag_tdi_i`       | TDI         | D1
38
| `jtag_tdo_o`       | TDO         | D2
39
| `jtag_tms_i`       | TMS         | D3
40
| `jtag_trst_i`      | TRST        | D4
41
|=======================
42
 
43
[TIP]
44
The low-active JTAG _test reset_ (TRST) signals is _optional_ as a reset can also be triggered via the TAP controller.
45
If TRST is not used make sure to pull the signal _high_.
46
 
47
 
48
:sectnums:
49
=== OpenOCD
50
 
51
The NEORV32 on-chip debugger can be accessed using the https://github.com/riscv/riscv-openocd[RISC-V port of OpenOCD].
52
Prebuilt binaries can be obtained - for example - from https://www.sifive.com/software[SiFive]. A pre-configured
53
OpenOCD configuration file (`sw/openocd/openocd_neorv32.cfg`) is available that allows easy access to the NEORV32 CPU.
54
 
55
[NOTE]
56
You might need to adapt `ftdi_vid_pid`, `ftdi_channel` and `ftdi_layout_init` in `sw/openocd/openocd_neorv32.cfg`
57
according to your interface chip and your operating system.
58
 
59
[TIP]
60
If you want to modify the JTAG clock speed (via `adapter speed` in `sw/openocd/openocd_neorv32.cfg`) make sure to meet
61
the clock requirements noted in https://stnolting.github.io/neorv32/#_debug_module_dm[Documentation: Debug Transport Module (DTM)].
62
 
63
To access the processor using OpenOCD, open a terminal and start OpenOCD with the pre-configured configuration file.
64
 
65
.Connecting via OpenOCD (on Windows)
66
[source, bash]
67
--------------------------
68
N:\Projects\neorv32\sw\openocd>openocd -f openocd_neorv32.cfg
69
Open On-Chip Debugger 0.11.0-rc1+dev (SiFive OpenOCD 0.10.0-2020.12.1)
70
Licensed under GNU GPL v2
71
For bug reports:
72
        https://github.com/sifive/freedom-tools/issues
73
1
74
Info : Listening on port 6666 for tcl connections
75
Info : Listening on port 4444 for telnet connections
76
Info : clock speed 1000 kHz
77
Info : JTAG tap: neorv32.cpu tap/device found: 0x0cafe001 (mfg: 0x000 (), part: 0xcafe, ver: 0x0)
78
Info : datacount=1 progbufsize=2
79
Info : Disabling abstract command reads from CSRs.
80
Info : Examined RISC-V core; found 1 harts
81
Info :  hart 0: XLEN=32, misa=0x40801105
82
Info : starting gdb server for neorv32.cpu.0 on 3333
83
Info : Listening on port 3333 for gdb connections
84
--------------------------
85
 
86
OpenOCD has successfully connected to the NEORV32 on-chip debugger and has examined the CPU (showing the content of
87
the `misa` CSRs). Now you can use `gdb` to connect via port 3333.
88
 
89
 
90
:sectnums:
91
=== Debugging with GDB
92
 
93
This guide uses the simple "blink example" from `sw/example/blink_led` as simplified test application to
94
show the basics of in-system debugging.
95
 
96
At first, the application needs to be compiled. We will use the minimal machine architecture configuration
97
(`rv32i`) here to be independent of the actual processor/CPU configuration.
98
Navigate to `sw/example/blink_led` and compile the application:
99
 
100
.Compile the test application
101
[source, bash]
102
--------------------------
103
.../neorv32/sw/example/blink_led$ make MARCH=rv32i USER_FLAGS+=-g clean_all all
104
--------------------------
105
 
106
.Adding debug symbols to the executable
107
[NOTE]
108
`USER_FLAGS+=-g` passes the `-g` flag to the compiler so it adds debug information/symbols
109
to the generated ELF file. This is optional but will provide more sophisticated information for debugging
110
(like source file line numbers).
111
 
112
This will generate an ELF file `main.elf` that contains all the symbols required for debugging.
113
Furthermore, an assembly listing file `main.asm` is generated that we will use to define breakpoints.
114
 
115
Open another terminal in `sw/example/blink_led` and start `gdb`.
116
The GNU debugger is part of the toolchain (see <<_software_toolchain_setup>>).
117
 
118
.Starting GDB (on Linux (Ubuntu on Windows))
119
[source, bash]
120
--------------------------
121
.../neorv32/sw/example/blink_led$ riscv32-unknown-elf-gdb
122
GNU gdb (GDB) 10.1
123
Copyright (C) 2020 Free Software Foundation, Inc.
124
License GPLv3+: GNU GPL version 3 or later 
125
This is free software: you are free to change and redistribute it.
126
There is NO WARRANTY, to the extent permitted by law.
127
Type "show copying" and "show warranty" for details.
128
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv32-unknown-elf".
129
Type "show configuration" for configuration details.
130
For bug reporting instructions, please see:
131
.
132
Find the GDB manual and other documentation resources online at:
133
    .
134
 
135
For help, type "help".
136
Type "apropos word" to search for commands related to "word".
137
(gdb)
138
--------------------------
139
 
140
Now connect to OpenOCD using the default port 3333 on your machine.
141
We will use the previously generated ELF file `main.elf` from the `blink_led` example.
142
Finally, upload the program to the processor and start debugging.
143
 
144
[NOTE]
145
The executable that is uploaded to the processor is **not** the default NEORV32 executable (`neorv32_exe.bin`) that
146
is used for uploading via the bootloader. Instead, all the required sections (like `.text`) are extracted from `mail.elf`
147
by GDB and uploaded via the debugger's indirect memory access.
148
 
149
.Running GDB
150
[source, bash]
151
--------------------------
152
(gdb) target extended-remote localhost:3333 <1>
153
Remote debugging using localhost:3333
154
warning: No executable has been specified and target does not support
155
determining executable automatically.  Try using the "file" command.
156
0xffff0c94 in ?? () <2>
157
(gdb) file main.elf <3>
158
A program is being debugged already.
159
Are you sure you want to change the file? (y or n) y
160
Reading symbols from main.elf...
161
(gdb) load <4>
162
Loading section .text, size 0xd0c lma 0x0
163
Loading section .rodata, size 0x39c lma 0xd0c
164
Start address 0x00000000, load size 4264
165
Transfer rate: 43 KB/sec, 2132 bytes/write.
166
(gdb)
167
--------------------------
168
<1> Connect to OpenOCD
169
<2> The CPU was still executing code from the bootloader ROM - but that does not matter here
170
<3> Select `mail.elf` from the `blink_led` example
171
<4> Upload the executable
172
 
173
After the upload, GDB will make the processor jump to the beginning of the uploaded executable
174
(by default, this is the beginning of the instruction memory at `0x00000000`) skipping the bootloader
175
and halting the CPU right before executing the `blink_led` application.
176
 
177
 
178
:sectnums:
179
==== Breakpoint Example
180
 
181
The following steps are just a small showcase that illustrate a simple debugging scheme.
182
 
183
While compiling `blink_led`, an assembly listing file `main.asm` was generated.
184
Open this file with a text editor to check out what the CPU is going to do when resumed.
185
 
186
The `blink_led` example implements a simple counter on the 8 lowest GPIO output ports. The program uses
187
"busy wait" to have a visible delay between increments. This waiting is done by calling the `neorv32_cpu_delay_ms`
188
function. We will add a _breakpoint_ right at the end of this wait function so we can step through the iterations
189
of the counter.
190
 
191
.Cut-out from `main.asm` generated from the `blink_led` example
192
[source, assembly]
193
--------------------------
194
00000688 <__neorv32_cpu_delay_ms_end>:
195
 688:   01c12083                lw      ra,28(sp)
196
 68c:   02010113                addi    sp,sp,32
197
 690:   00008067                ret
198
--------------------------
199
 
200
The very last instruction of the `neorv32_cpu_delay_ms` function is `ret` (= return)
201
at hexadecimal `690` in this example. Add this address as _breakpoint_ to GDB.
202
 
203
[NOTE]
204
The address might be different if you use a different version of the software framework or
205
if different ISA options are configured.
206
 
207
.Adding a GDB breakpoint
208
[source, bash]
209
--------------------------
210
(gdb) b * 0x690
211
Breakpoint 1 at 0x690
212
--------------------------
213
 
214
.How do breakpoints work?
215
[TIP]
216
The NEORV32 on-chip debugger does not provide any hardware breakpoints (RISC-V "trigger modules") that compare an address like the PC
217
with a predefined value. Instead, gdb will modify the actual executable in IMEM: the actual instruction at the address
218
of the specified breakpoint is replaced by a `break` / `c.break` instruction. Whenever execution reaches this instruction, debug mode is
219
re-entered and the debugger restores the original instruction at this address to maintain original program behavior.
220
 
221
Now execute `c` (= continue). The CPU will resume operation until it hits the break-point.
222
By this we can "step" from increment to increment.
223
 
224
.Iterating from breakpoint to breakpoint
225
[source, bash]
226
--------------------------
227
Breakpoint 1 at 0x690
228
(gdb) c
229
Continuing.
230
 
231
Breakpoint 1, 0x00000690 in neorv32_cpu_delay_ms ()
232
(gdb) c
233
Continuing.
234
 
235
Breakpoint 1, 0x00000690 in neorv32_cpu_delay_ms ()
236
(gdb) c
237
Continuing.
238
--------------------------

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.