4.1. About OpenOCD

4.1.1. Repository and Doc

openocd

openflashloader

Note

OpenOCD Flashloader is developed to support various different customized flash programming without modify openocd and rebuilt it, please check the source code repo’s doc.

openocd doc path: openocd/doc/pdf/openocd.pdf

4.2. How to Use

4.2.1. How to determine the version of OpenOCD

  • start a cmd(Windows)/terminal(Linux)

  • run the openocd -v command

../_images/openocd-v.png

Note

git commit id: 787e48e66

compile date: (2022-12-29-08:49)

4.2.2. Start OpenOCD

Frequently used command line parameters

parameter

description

-v

display version info

-d

set debug level to 3

-d0

error messages only

-d1

error warning

-d2

error warning info (default)

-d3

error warning info debug

-d4

error warning info debug low-level-debug

-f file

use configuration file

-s dir

dir to search for config files

-l logfile

redirect log output to logfile

4.3. Nuclei Customized Features

Display CPU information

Usually we don’t know what instruction sets a CPU supports, what functional components it contains, and the various configurations of the components. The only way to get the desired information is to read the corresponding CSR registers and then do the math. It would be a pain in the ass to do this for every function point that needs to be known.

This command is designed to solve this problem by automatically reading the CSRs and doing the cpu feature probing, and then formatting the output.

nuclei cpuinfo

Nuspi(nuclei spi) driver

Nuclei’s SPI controller, used in Nuclei RISC-V fpga evaluation board and other boards.

flash bank name nuspi base size chip_width bus_width target spi_base [simulation]

Custom driver and open-flashloader

Custom exists for compatibility with any SPI controller and any Flash. It also needs to be used in conjunction with openflashloader to achieve the desired results.

flash bank name custom base size chip_width bus_width target spi_base flashloader_path [simulation] [sectorsize=]

Nuclei Customized CSRs

Nuclei released openocd supports a number of nuclei customized CSRs, please check here https://github.com/riscv-mcu/riscv-openocd/blob/nuclei/2024.06/src/target/riscv/encoding.h#L3109-L3223

Nuclei embedded trace

Note

Still in experiment stage, not for production usage.

Some Nuclei cpus are equipped with trace support, which permits examination of the instruction activity. Trace activity is controlled through an Embedded Trace(Etrace) Module on the core’s scan chains. The following commands are for etrace.

Currently, we only implemented RISC-V ETrace Instruction Trace in CPU, Data Trace not yet ready.

nuclei etrace config etrace-addr buffer-addr buffer-size wrap

This command is used to initialize Etrace and configure related parameters.

nuclei etrace enable

This command triggers the Etrace enable signal by setting the Core internal trigger.

nuclei etrace disable

This command triggers the Etrace disable signal by setting the Core internal trigger.

nuclei etrace start

This command is used to enable Etrace data collection.

nuclei etrace stop

This command is used to disable Etrace data collection.

nuclei etrace dump filename

This command is used to dump the data captured by Etrace.

nuclei etrace clear

This command is used to clear the read and write pointers for Etrace.

nuclei etrace info

This command displays the current Etrace status.

You can also use ETrace feature in Nuclei Studio IDE, please check its documentation for more details.

Nuclei Debug Map Feature

The debug map for each hart is automatically read and printed during OpenOCD startup, or you can read the debug map at runtime with the examine_cpu_core command.

About the detailed nuclei debug map feature, please contact with our AE for more documentation.

nuclei expose_cpu_core

Configure a list of index for nuclei_examine_cpu_core to expose in this must be executed before init.

nuclei examine_cpu_core

Return the 64-bit value read from dm-custom1 and dm-custom2 value = dm-custom2 << 32 + dm-custom1.

Init resethalt command

In practice, usually encountered due to software problems caused by the CPU stuck, then the debugger will not be connected to the development board, only to the development board power off. If your code is running in flash, powering down the board will not solve the problem. resethalt is designed to solve this problem.

init resethalt

FTDI nscan1_mode command

Enable or disable Nuclei CJTAG mode. Usage is the same as ftdi oscan1_mode.

ftdi nscan1_mode on|off

4.4. About the configuration file

The openocd configuration file is used to configure how to connect to the development board’s window through the Debug interface. nuclei provides an example of the openocd configuration file, which can be modified based on the example.

Here we take example using Nuclei HBird Debugger(FTDI based) as to explain this openocd configuration file.

Here is an working example for openocd configuration file https://github.com/Nuclei-Software/nuclei-sdk/blob/master/SoC/evalsoc/Board/nuclei_fpga_eval/openocd_evalsoc.cfg

Modify debugger rate

adapter_khz 1000 or adapter speed 1000

Select debugger interface

adapter driver ftdi
ftdi vid_pid 0x0403 0x6010

transport select jtag

ftdi layout_init 0x0008 0x001b
ftdi layout_signal nSRST -oe 0x0020 -data 0x0020
ftdi layout_signal TCK -data 0x0001
ftdi layout_signal TDI -data 0x0002
ftdi layout_signal TDO -input 0x0004
ftdi layout_signal TMS -data 0x0008
ftdi layout_signal JTAG_SEL -data 0x0100 -oe 0x0100

The above code are used to select fdti debugger, the ftdi chip pid/vid must match selected id, transport is selected as JTAG, and ftdi layout is setup to match HBird Debugger hardware settings.

Modify debugger mode

There are two debugging modes JTAG and cJTAG.

  • JTAG <-> ftdi nscan1_mode off

  • cJTAG <-> ftdi nscan1_mode on

Describe the JTAG link

  • single core

set _CHIPNAME0 riscv0
jtag newtap $_CHIPNAME0 cpu -irlen 5 -expected-id 0x10900a6d

set _TARGETNAME0 $_CHIPNAME0.cpu
target create $_TARGETNAME0 riscv -chain-position $_TARGETNAME0 -coreid 0
  • smp system

set _CHIPNAME0 riscv0
jtag newtap $_CHIPNAME0 cpu -irlen 5 -expected-id 0x10900a6d

set _TARGETNAME0 $_CHIPNAME0.cpu
target create $_TARGETNAME0.0 riscv -chain-position $_TARGETNAME0 -coreid 0 -rtos hwthread
target create $_TARGETNAME0.1 riscv -chain-position $_TARGETNAME0 -coreid 1
target create $_TARGETNAME0.2 riscv -chain-position $_TARGETNAME0 -coreid 2
target smp $_TARGETNAME0.0 $_TARGETNAME0.1 $_TARGETNAME0.2
  • amp system

set _CHIPNAME0 riscv0
jtag newtap $_CHIPNAME0 cpu -irlen 5 -expected-id 0x10900a6d

set _CHIPNAME1 riscv1
jtag newtap $_CHIPNAME1 cpu -irlen 5 -expected-id 0x10300a6d

set _TARGETNAME0 $_CHIPNAME0.cpu
target create $_TARGETNAME0 riscv -chain-position $_TARGETNAME0 -coreid 0

set _TARGETNAME1 $_CHIPNAME1.cpu
target create $_TARGETNAME1.0 riscv -chain-position $_TARGETNAME0 -coreid 0 -rtos hwthread
target create $_TARGETNAME1.1 riscv -chain-position $_TARGETNAME0 -coreid 1
target smp $_TARGETNAME1.0 $_TARGETNAME1.1

Note

  • -rtos hwthread

OpenOCD includes a pseudo RTOS called hwthread that presents CPU cores (“hardware threads”) in an SMP system as threads to GDB. With this extension, GDB can be used to inspect the state of an SMP system in a natural way. After halting the system, using the GDB command info threads will list the context of each active CPU core in the system. GDB’s thread command can be used to switch the view to a different CPU core. The step and stepi commands can be used to step a specific core while other cores are free-running or remain halted, depending on the scheduler-locking mode configured in GDB.

Describe the workarea

workarea is mainly used to speed up certain operations, such as reading and writing large chunks of memory, running small program fragments, reading and writing flash, and so on.

$_TARGETNAME0 configure -work-area-phys 0x08000000 -work-area-size 0x10000 -work-area-backup 1

Note

The workarea should be a readable, writable, and executable area of memory.

0x08000000 workarea base address, modified according to the actual situation.

0x10000 workarea size of byte, modified according to the actual situation.

Describe the nor flash

set _FLASHNAME0 $_CHIPNAME0.flash
flash bank $_FLASHNAME0 nuspi 0x20000000 0 0 0 $_TARGETNAME0.0 0x10180000

Note

nuspi openocd flash drivers type, modified according to the actual situation.

0x20000000 qspi-xip address, modified according to the actual situation.

0x10180000 qspi controller base address, modified according to the actual situation.

Connect to the specified debugger

When there is more than one debugger in a debugging environment, we need to connect to specify the debugger, in this case you can use the following command to specify.

ftdi_serial FT4YR31I

How to set up gdb/telnet/tcl ports

openocd provides three kinds of debugging service ports are gdb/telnet/tcl, choose the appropriate service according to the situation, and set the port number of the corresponding service by the following command.

gdb_port 3333
telnet_port 4444
tcl_port 6666

Note

The above shows the default port number, you are free to change the port number if it is free. Of course we can also disable the port numbers we don’t need, it’s easy just change the port number to disable.

semihosting

OpenOCD also supports the ARM semihosting feature, use the following command to enable it.

arm semihosting enable

For more detailed information about how to use openocd, please check the openocd.pdf distributed in openocd release.

4.5. Frequently asked questions

There are a few more FAQs please see:

4.6. Low-cost debugger solution

We also provided a low cost mcu solution to debug RISC-V CPU, which support JTAG and cJTAG, please check the following repo to learn more about it, and it is also supported in Nuclei Studio.

Nuclei Dlink: https://github.com/Nuclei-Software/nuclei-dlink