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

Subversion Repositories neorv32

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

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 72 zero_gravi
Windows and Linux (Ubuntu on Windows / WSL) in parallel running the upstream version of OpenOCD and the
8
RISC-V _GNU debugger_ `gdb`.
9 69 zero_gravi
 
10 72 zero_gravi
[NOTE]
11 69 zero_gravi
See datasheet section https://stnolting.github.io/neorv32/#_on_chip_debugger_ocd[On Chip Debugger (OCD)]
12 72 zero_gravi
for more information regarding the actual hardware.
13 69 zero_gravi
 
14
[NOTE]
15
The on-chip debugger is only implemented if the _ON_CHIP_DEBUGGER_EN_ generic is set _true_. Furthermore, it requires
16 72 zero_gravi
the `Zicsr` and `Zifencei` CPU extension to be implemented (top generics _CPU_EXTENSION_RISCV_Zicsr_ = _true_
17
and _CPU_EXTENSION_RISCV_Zifencei_ = _true_).
18 69 zero_gravi
 
19
 
20
:sectnums:
21
=== Hardware Requirements
22
 
23 72 zero_gravi
Make sure the on-chip debugger of your NEORV32 setup is implemented (_ON_CHIP_DEBUGGER_EN_ generic = true). This
24
tutorial uses `gdb` to **directly upload an executable** to the processor. If you are using the default
25
processor setup _with_ internal instruction memory (IMEM) make sure it is implemented as RAM
26
(_INT_BOOTLOADER_EN_ generic = true).
27
 
28 69 zero_gravi
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 72 zero_gravi
The low-active JTAG tap reset `jtag_trst_i` signals is _optional_ as a reset can also be triggered via the TAP controller
45
issuing special commands. If `jtag_trst_i` is not connected make sure to pull the signal _high_.
46 69 zero_gravi
 
47
 
48
:sectnums:
49
=== OpenOCD
50
 
51 72 zero_gravi
The NEORV32 on-chip debugger can be accessed using the upstream version of OpenOCD. A pre-configured OpenOCD configuration
52
file is provided (`sw/openocd/openocd_neorv32.cfg`) that allows an easy access to the NEORV32 CPU.
53 69 zero_gravi
 
54
[NOTE]
55 72 zero_gravi
You might need to adapt `ftdi vid_pid`, `ftdi channel` and `ftdi layout_init` in `sw/openocd/openocd_neorv32.cfg`
56 69 zero_gravi
according to your interface chip and your operating system.
57
 
58
[TIP]
59
If you want to modify the JTAG clock speed (via `adapter speed` in `sw/openocd/openocd_neorv32.cfg`) make sure to meet
60
the clock requirements noted in https://stnolting.github.io/neorv32/#_debug_module_dm[Documentation: Debug Transport Module (DTM)].
61
 
62
To access the processor using OpenOCD, open a terminal and start OpenOCD with the pre-configured configuration file.
63
 
64 72 zero_gravi
.Connecting via OpenOCD (on Windows) using the default `openocd_neorv32.cfg` script
65 69 zero_gravi
[source, bash]
66
--------------------------
67
N:\Projects\neorv32\sw\openocd>openocd -f openocd_neorv32.cfg
68 72 zero_gravi
Open On-Chip Debugger 0.11.0 (2021-11-18) [https://github.com/sysprogs/openocd]
69 69 zero_gravi
Licensed under GNU GPL v2
70 72 zero_gravi
libusb1 09e75e98b4d9ea7909e8837b7a3f00dda4589dc3
71
For bug reports, read
72
        http://openocd.org/doc/doxygen/bugs.html
73 69 zero_gravi
Info : clock speed 1000 kHz
74
Info : JTAG tap: neorv32.cpu tap/device found: 0x0cafe001 (mfg: 0x000 (), part: 0xcafe, ver: 0x0)
75
Info : datacount=1 progbufsize=2
76
Info : Disabling abstract command reads from CSRs.
77
Info : Examined RISC-V core; found 1 harts
78 72 zero_gravi
Info :  hart 0: XLEN=32, misa=0x40901107
79 69 zero_gravi
Info : starting gdb server for neorv32.cpu.0 on 3333
80
Info : Listening on port 3333 for gdb connections
81 72 zero_gravi
Target HALTED.
82
Ready for remote connections.
83
Info : Listening on port 6666 for tcl connections
84
Info : Listening on port 4444 for telnet connections
85 69 zero_gravi
--------------------------
86
 
87
OpenOCD has successfully connected to the NEORV32 on-chip debugger and has examined the CPU (showing the content of
88 72 zero_gravi
the `misa` CSRs). The processor is halted and OpenOCD waits fot `gdb` to connect via port 3333.
89 69 zero_gravi
 
90
 
91
:sectnums:
92
=== Debugging with GDB
93
 
94
This guide uses the simple "blink example" from `sw/example/blink_led` as simplified test application to
95
show the basics of in-system debugging.
96
 
97
At first, the application needs to be compiled. We will use the minimal machine architecture configuration
98
(`rv32i`) here to be independent of the actual processor/CPU configuration.
99
Navigate to `sw/example/blink_led` and compile the application:
100
 
101
.Compile the test application
102
[source, bash]
103
--------------------------
104
.../neorv32/sw/example/blink_led$ make MARCH=rv32i USER_FLAGS+=-g clean_all all
105
--------------------------
106
 
107
.Adding debug symbols to the executable
108
[NOTE]
109
`USER_FLAGS+=-g` passes the `-g` flag to the compiler so it adds debug information/symbols
110 72 zero_gravi
to the generated ELF file. This is optional but will provide more sophisticated debugging information
111 69 zero_gravi
(like source file line numbers).
112
 
113
This will generate an ELF file `main.elf` that contains all the symbols required for debugging.
114
Furthermore, an assembly listing file `main.asm` is generated that we will use to define breakpoints.
115
 
116
Open another terminal in `sw/example/blink_led` and start `gdb`.
117
The GNU debugger is part of the toolchain (see <<_software_toolchain_setup>>).
118
 
119
.Starting GDB (on Linux (Ubuntu on Windows))
120
[source, bash]
121
--------------------------
122
.../neorv32/sw/example/blink_led$ riscv32-unknown-elf-gdb
123
GNU gdb (GDB) 10.1
124
Copyright (C) 2020 Free Software Foundation, Inc.
125
License GPLv3+: GNU GPL version 3 or later 
126
This is free software: you are free to change and redistribute it.
127
There is NO WARRANTY, to the extent permitted by law.
128
Type "show copying" and "show warranty" for details.
129
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv32-unknown-elf".
130
Type "show configuration" for configuration details.
131
For bug reporting instructions, please see:
132
.
133
Find the GDB manual and other documentation resources online at:
134
    .
135
 
136
For help, type "help".
137
Type "apropos word" to search for commands related to "word".
138
(gdb)
139
--------------------------
140
 
141
Now connect to OpenOCD using the default port 3333 on your machine.
142
We will use the previously generated ELF file `main.elf` from the `blink_led` example.
143
Finally, upload the program to the processor and start debugging.
144
 
145
[NOTE]
146
The executable that is uploaded to the processor is **not** the default NEORV32 executable (`neorv32_exe.bin`) that
147
is used for uploading via the bootloader. Instead, all the required sections (like `.text`) are extracted from `mail.elf`
148
by GDB and uploaded via the debugger's indirect memory access.
149
 
150
.Running GDB
151
[source, bash]
152
--------------------------
153
(gdb) target extended-remote localhost:3333 <1>
154
Remote debugging using localhost:3333
155
warning: No executable has been specified and target does not support
156
determining executable automatically.  Try using the "file" command.
157
0xffff0c94 in ?? () <2>
158
(gdb) file main.elf <3>
159
A program is being debugged already.
160
Are you sure you want to change the file? (y or n) y
161
Reading symbols from main.elf...
162
(gdb) load <4>
163
Loading section .text, size 0xd0c lma 0x0
164
Loading section .rodata, size 0x39c lma 0xd0c
165
Start address 0x00000000, load size 4264
166
Transfer rate: 43 KB/sec, 2132 bytes/write.
167
(gdb)
168
--------------------------
169
<1> Connect to OpenOCD
170
<2> The CPU was still executing code from the bootloader ROM - but that does not matter here
171
<3> Select `mail.elf` from the `blink_led` example
172
<4> Upload the executable
173
 
174
After the upload, GDB will make the processor jump to the beginning of the uploaded executable
175
(by default, this is the beginning of the instruction memory at `0x00000000`) skipping the bootloader
176
and halting the CPU right before executing the `blink_led` application.
177
 
178 74 zero_gravi
[IMPORTANT]
179
After gdb has connected to the CPU, it is recommended to disable the CPU's global interrupt flag
180
(`mstatus.mie`, = bit #3) to prevent unintended calls of potentially outdated trap handlers. The global
181
interrupt flag can be cleared using the following gdb command:
182
`set $mstatus = ($mstatus & ~(1<<3))`. Interrupts can be enabled globally again by the following command:
183
`set $mstatus = ($mstatus | (1<<3))`.
184 69 zero_gravi
 
185 74 zero_gravi
 
186 69 zero_gravi
:sectnums:
187 72 zero_gravi
==== Software Breakpoints
188 69 zero_gravi
 
189
The following steps are just a small showcase that illustrate a simple debugging scheme.
190
 
191
While compiling `blink_led`, an assembly listing file `main.asm` was generated.
192
Open this file with a text editor to check out what the CPU is going to do when resumed.
193
 
194
The `blink_led` example implements a simple counter on the 8 lowest GPIO output ports. The program uses
195
"busy wait" to have a visible delay between increments. This waiting is done by calling the `neorv32_cpu_delay_ms`
196
function. We will add a _breakpoint_ right at the end of this wait function so we can step through the iterations
197
of the counter.
198
 
199
.Cut-out from `main.asm` generated from the `blink_led` example
200
[source, assembly]
201
--------------------------
202
00000688 <__neorv32_cpu_delay_ms_end>:
203
 688:   01c12083                lw      ra,28(sp)
204
 68c:   02010113                addi    sp,sp,32
205
 690:   00008067                ret
206
--------------------------
207
 
208
The very last instruction of the `neorv32_cpu_delay_ms` function is `ret` (= return)
209
at hexadecimal `690` in this example. Add this address as _breakpoint_ to GDB.
210
 
211
[NOTE]
212
The address might be different if you use a different version of the software framework or
213
if different ISA options are configured.
214
 
215 72 zero_gravi
.Adding a GDB software breakpoint
216 69 zero_gravi
[source, bash]
217
--------------------------
218 72 zero_gravi
(gdb) b * 0x690 <1>
219 69 zero_gravi
Breakpoint 1 at 0x690
220
--------------------------
221 72 zero_gravi
<1> `b` is an alias for `break`, which adds a _software_ breakpoint.
222 69 zero_gravi
 
223 72 zero_gravi
.How do _software_ breakpoints work?
224 69 zero_gravi
[TIP]
225 72 zero_gravi
Software breakpoints are used for debugging programs that are accessed from read/write memory (RAM) like IMEM. The debugger
226
temporarily replaces the instruction word of the instruction, where the breakpoint shall be inserted, by a `ebreak` / `c.ebreak`
227
instruction. Whenever execution reaches this instruction, debug mode is entered and the debugger restores the original
228
instruction at this address to maintain original program behavior. +
229
 +
230
When debugging programs executed from ROM _hardware-assisted_ breakpoints using the core's trigger module have to be used.
231
See section <<_hardware_breakpoints>> for more information.
232 69 zero_gravi
 
233
Now execute `c` (= continue). The CPU will resume operation until it hits the break-point.
234 72 zero_gravi
By this we can move from one counter increment to another.
235 69 zero_gravi
 
236
.Iterating from breakpoint to breakpoint
237
[source, bash]
238
--------------------------
239
Breakpoint 1 at 0x690
240
(gdb) c
241
Continuing.
242
 
243
Breakpoint 1, 0x00000690 in neorv32_cpu_delay_ms ()
244
(gdb) c
245
Continuing.
246
 
247
Breakpoint 1, 0x00000690 in neorv32_cpu_delay_ms ()
248
(gdb) c
249
Continuing.
250
--------------------------
251 72 zero_gravi
 
252
.BREAK instructions in your program code
253
[TIP]
254
If your original application code uses the BREAK instruction (for example for some OS calls/signaling) this
255
instruction will cause an enter to debug mode when executed. These situation cannot be continued using gdb's
256
`c` command and have to be "stepped-over" using the single-step command `s`.
257
 
258
 
259
:sectnums:
260
==== Hardware Breakpoints
261
 
262
Hardware-assisted breakpoints using the CPU's trigger module are required when debugging code that is executed from
263
read-only memory (ROM) as GDB cannot temporarily replace instructions by BREAK instructions.
264
 
265
From a user point of view hardware breakpoints behave like software breakpoints. GDB provides a command to setup
266
a hardware-assisted breakpoint:
267
 
268
.Adding a GDB hardware breakpoint
269
[source, bash]
270
--------------------------
271
(gdb) hb * 0x690 <1>
272
Breakpoint 1 at 0x690
273
--------------------------
274
<1> `hb` is an alias for `hbreak`, which adds a _hardware_ breakpoint.
275
 
276
[NOTE]
277
The CPU's trigger module only provides a single _instruction address match_ type trigger. Hence, only
278
a single `hb` hardware-assisted breakpoint can be used.

powered by: WebSVN 2.1.0

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