2.9. Nuclei Studio 调试运行工程

在进行工程调试前,可以先检验一下当前的硬件环境是否正确无误,可以参考 Nuclei Studio调试工程前的硬件检测

2.9.1. 调试模式管理

在NucleiStudio中,使用Launch Bar管理不同的调试器,默认情况下,NucleiStudio会为OpenOCD、Jlink、Qemu生成对应的 *.launch 调试文件,NucleiStudio识别到 *.launch 文件后,会将其加入到Launch Bar中进行管理,用户可以通过以下三种方式来使用指定的调试模式。

image1

通过点击工程中的 *.launch 文件切换不同的调试模式,当用户单击工程中的某一个 *.launch 文件时,NucleiStudio会将该文件设置为Launch Bar中的选中文件,然后就可以通过Launch Bar执行Run/Debug操作。

image2

在工程展开文件,找到 *.launch 文件并在 *.launch 文件上点击鼠标右键,在弹出菜单中选中 Debug As/Run As ,在下一级菜单中点对应的模式开始 Run/Debug 操作。

image3

用户可以通过Launch Bar中的下接框,来切换成不同的调试模式,在Launch Bar中点击展开按钮,然后选中对应的调试模式,并执行 Run/Debug 操作。

image4

2.9.2. 使用蜂鸟调试器结合OpenOCD调试运行项目

2.9.2.1. 安装蜂鸟调试器驱动

Note

Nuclei Studio自2021.02版本起openocd实现windows免驱功能,使用此版本及以上windows环境的用户可跳过此节,Linux环境仍需配置驱动。低于此版本的用户需按照以下方法安装驱动。

2.9.2.1.1. 在Windows系统中安装驱动

程序编译成功后,便可以将程序下载到FPGA原型开发板运行。首先将原型开发板与主机PC进行连接,步骤如下。

将蜂鸟调试器的一端插入主机PC的USB接口,另一端与原型开发板连接。由于蜂鸟调试器还包含了 将原型开发板输出的UART转换成USB 的功能,因此如果蜂鸟调试器被主机PC识别成功(且驱动安装成功),那么将能够被主机识别成为一个COM串口。在主机PC的设备管理器中的 端口(COM和LPT)栏目 中可以查询到该COM的串口号(譬如COM11)。此串口在后续的程序运行过程中将充当原型开发板运行程序的printf输出显示接口。

image5

Note

注意:如果使用蜂鸟调试器,主机PC的Windows系统不能够识别蜂鸟调试器的USB,需要安装驱动,可以在https://www.nucleisys.com/developboard.php#debuggerkit 下载驱动程序并安装。

Note

注意:在通过 蜂鸟调试器 下载之前,需要注意 蜂鸟调试器 被Windows正确识别,检验的标准即为本节中所述正确地安装了HBird-Driver.exe的驱动,且能够在设备管理器中查询到COM的串口号。

2.9.2.1.2. 在Linux系统中安装驱动

在Linux环境下安装驱动步骤如下:

  • 1:连接开发板到Linux中,确保USB被Linux识别出来。如果使用虚拟机,确保开发板连到了虚拟机当中。

    image6

  • 2:在控制台中使用lsusb指令查看信息,参考的打印信息如下:

Bus 001 Device 010: ID 0403:6010 Future Technology Devices International, Ltd FT2232xxxx
  • 3:控制台中输入sudo vi /etc/udev/rules.d/99-openocd.rules指令打开99-openocd.rules文件,输入如下内容,保存退出。

SUBSYSTEM=="usb", ATTR{idVendor}=="0403",

ATTR{idProduct}=="6010", MODE="664", GROUP="plugdev"

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403",

ATTRS{idProduct}=="6010", MODE="664", GROUP="plugdev"
  • 4:断开调试器再重新连接到Linux系统中。

  • 5:使用 ls /dev/ttyUSB* 命令查看 ttyUSB 信息,参考输出如下:

    /dev/ttyUSB0
    
    /dev/ttyUSB1
    
  • 6:使用ls -l /dev/ttyUSB1命令查看分组信息,参考输出如下:

    crw-rw-r-- 1 root plugdev 188, 1 Nov 28 12:53 /dev/ttyUSB1
    

可以看到ttyUSB1已经加入 plugdev 组,接下来我们要将自己添加到plugdev组(不同环境可能名字不同,请根据实际情况修改)。使用whoami命令查看当前用户名,我们将其记录为 < your_user_name >

  • 7:使用 sudo usermod -a -G plugdev <your_user_name> 命令将自己添加进plugdev组。加入以后一定要重启或者注销操作系统。

  • 8:再次确认当前用户名已属于 plugdev 组,使用 groups 命令,可以看到打印信息中有 plugdev 即成功将当前用户添加至plugdev组。如果没有可以尝试重启。

  • 9:查看gcc的依赖是否完整,如果有依赖需要安装,可以执行 sudo apt install libncursesw5libtinfo5 进行安装

cd Nuclei Studio/toolchain/gcc/bin/

# for gcc10, try command below
ldd ./riscv-nuclei-elf-gdb
# for >= gcc13/gcc14 and later version
ldd ./riscv64-unknown-elf-gdb

image7

2.9.2.2. Debug Configuration

2.9.2.2.1. 使用Nuclei Studio生成的Debug Configuration

为了方便用户调试,Nuclei Studio在创建工程时,会根据NPK的配置,默认的生成Debug Configurations的Launch文件。

image8

用户可以展开工程,选中对应的 test_debug_openocd.launch 文件,在右键菜单中,可以 Run as/Debug as->test_debug_openocd ,就可以按照对应的Debug Configurations操作工程程了。

image9

Note

注意:配图可能没有及时更新,导致图文不一致,以文字为准,结合对应版本进行使用。

具体的Debug Configurations的内容可以在Launch Bar中进行详情查看。

image10

image11

2.9.2.2.2. 新建并配置Debug Configuration

通过Nuclei Studio新建并配置Debug Configuration内容的步骤如下。

在Nuclei Studio的主菜单栏中选择 Run—>Debug Configurations

image12

在弹出的窗口中,如果没有当前工程的调试设置内容,右键单击 GDB OpenOCD Debugging ,选择 New ,将会为本项目新建出一个调试项目 hello_world_demo Debug

image13

确保 Project 是当前需要调试的工程, C/C++ Application 中选择了正确的需要调试的ELF文件。

image14

选择调试项目 hello_world_demo Debug 的Debugger菜单,在Config options栏目中填入 -f "nuclei_sdk/SoC/evalsoc/Board/nuclei_fpga_eval/openocd_evalsoc.cfg" ,以确保OpenOCD使用正确的配置文件。这里的配置文件(nuclei_sdk/SoC/evalsoc/Board/nuclei_fpga_eval/openocd_evalsoc.cfg)根据实际工程中openocd的配置文件路径而定。例如:如果使用makefile方式导入工程,修改此处的内容为 -f "SoC/evalsoc/Board/nuclei_fpga_eval/openocd_evalsoc.cfg"

如果当前内核是RISC-V 32位内核,请确保Commands内容包含 set arch riscv:rv32

如果当前内核为64位,应确保替换为 set arch riscv:rv64

Note

Launch Timeout 为Nuclei Studio 2025.10版中新增配置选项。 在实际生产中使用时发现在某些特定场景下 OpenOCD 启动很慢, Nuclei Studio 中默认的 10s 时间以内没有探测到 OpenOCD 启动,就会超时处理。因此,用户可以通过 Launch Timeout 来设置超时时间。

image15

选择调试项目 hello_world_demo Debug 的Startup菜单,确保 Debug in RAM , Pre-run/Restart reset , Set Breakpoint at MainContinue 被勾选。

image16

完成配置后点击右下方 Apply 保存设置。

关于Debug Configuration 中Startup各项设置的具体含义,详细说明如下。这里的设定内容最终将以GDB命令的方式实现,所以在执行GDB命令时也是按此顺序来执行。

Eclipse embedded CDT官方文档中对Startup中的参数也做了一些基本介绍,具体参见:https://eclipse-embed-cdt.github.io/debug/openocd/riscv/

Initial Reset

可以设定一些让GDB做init的命令,具体可以参考GDB init command的一些用法,一般不需勾选。

Enable semithost

如果勾选此项,工程必须支持 semihosting 功能。在使用 RISC-V OpenOCD 时,需要在配置文件中添加``arm semihosting enable`` 来启用该功能,并且在创建 Nuclei SDK工程时也需要开启semihost支持。J-Link 和 GDB J-Link 调试方式也可以实现 semihost 功能,具体请参考 使用J-Link调试运行项目 。默认情况下,无需勾选此选项。

image62

image63

Load symbols

使用GDB的 file 命令,通过GDB读取elf的debug information信息,使GDB能方便且正确的进行Debug操作, 默认需勾选。

Load executable

使用GDB的 load 命令,让GDB下载程序到target端(GDB执行load命令,下载elf内容到target端,并将target端CPU的PC改成当前elf的entry位置),如果调试RAM(比如LM)中的程序,默认勾选;如果调试Flash中的程序,需确认openocd是否支持Flash的烧写以及当前调试是否要重新做Flash烧写,如果支持且需要重新烧写,则此项需勾选,否则不勾选;如果是ROM的代码,则不需要勾选。

Debug in Ram

如果GDB在 load excutable 后有reset等动作,避免CPU的启动地址和elf文件的启动地址不一样;或者RAM中的程序因为reset后被清掉。故每次在GDB reset后需重新load elf文件。如果是调试RAM里的程序,必需勾选此项。

Pre-run/Reset

使用GDB的 monitor reset 命令,它给openocd发 reset 命令,openocd会按RISC-V Debug Spec去驱动 nReset 信号,这个信号会让 coreperipheralsreset (这里也要看具体实现,不过RISC-V Dedbug Spec 推荐如此,且如果是Nuclei做的example SoC 或者FPGA ,都是follow 这个Spec ),执行 reset 后,CPU的PC就是 reset_vector 地址,因为外设都reset,所以RAM的内容也都会被清掉。如果是在RAM里debug,且勾选了此项,那么必须要勾选 Debug in RAM 项。

下图是RISC-V Debug Spec 中关于 nRESET 的说明。

image61

Halt

使用GDB的 monitor halt 命令,它实现就是通过OpenOCD 发 reset 命令后发 halt 命令,让CPU reset完后能马上halt住。

Set Program counter at

使用GDB的 set $pc 命令,可以再次修改target端CPU的PC地址。

Set breakpoint at

使用GDB的 break 命令,默认是main方法,如果是初次调试或者调试启动代码 ,建议修改为其他,如_start, 或者某一个绝对的地址。

Continue

使用GDB的 continue 命令。

2.9.2.3. 在原型开发板上调试程序

在开发板上调试之前,需要打开串口以便观察Printf函数打印信息。

使用Windows系统打开串口的方法如下:

打开Nuclei Studio自带的串口打印通道,选择 Window>Show View>Terminal ,如图 7‑13所示,点击显示器图标打开串口设置选项。

image17

在其窗口中设置Choose terminal(选择串口,即Serial Terminal)、 串口号 (这里以COM11为例)、 波特率(设置为115200) 等参数后,单击 OK 按钮。

image18

使用Linux系统打开串口方法如下:

打开Nuclei Studio自带的Terminal终端,选择 Window>Show View>Terminal ,点击显示器图标打开串口设置选项。choose terminal选择 Local Terminal ,点击OK打开Terminal终端。

image19

在框口中输入 minicom /dev/ttyUSB1 115200 打开串口,即可在Nuclei Studio中查看串口打印信息。

image20

如果程序员希望能够调试运行于原型开发板中程序,可以使用Nuclei Studio IDE进行调试。由于IDE运行于主机PC端,而程序运行于原型开发板上,因此这种调试也称为 在线调试 或者 远程调试

这里以1_helloworld为例,使用Nuclei Studio IDE对evalsoc原型开发板进行在线调试的步骤如下:

Note

注意demosoc在Nuclei SDK 5.0中被移除,请使用evalsoc作为替代。

确保Debug设置内容正确,可以打开Debug设置选项确认。在1_helloworld工程处右击,选择 Debug As –>Debug Configuration 打开Debug设置页面选择之前新建的设置进行检查。

image21

确定设置无误后,在下拉框选中Debug,之后左侧图标会变为甲虫图标,单击即可进入调试模式并下载程序进入开发板中。

image22

切换至Debug模式,如果下载成功,则会启动调试界面。

  • 如图1号标注位置,这里功能包括单步,运行,汇编级调试等。

  • 如图2号标注位置,这个箭头表示当前程序运行位置。

  • 如图3号标注位置,在代码的左侧双击即可在该行设置断点,再次双击可以取消断点。

  • 如图4号标注位置,这里可以切换编辑模式和调试模式。

  • 如图5号标注位置,这里是函数内变量显示的位置。

  • 如图6号标注位置,这里是查看寄存器数值的位置。图中显示的是PC寄存器当前的数值。

  • 如图7号标注位置,点击这里红色按钮可以退出调试模式。

  • 如图8号标注位置的下方,这里可以使用GDB控制台指令进行调试。

image23

2.9.2.4. 下载运行程序

调试程序没有出现问题后,可以将程序下载进开发板。点击下拉框切换至运行模式,此时左侧图标会切换为绿色运行按键,单击即可将程序下载至开发板并运行。由于调试和下载运行使用相同的设置文件,所以不需要再次设置。

image24

程序正常运行后,可以看到串口正确打印出helloworld等信息。

image25

如果想要结束程序运行并需要断开连接,在console栏目下点击红色按钮断开连接。

image26

2.9.5. Connect to Running Target

为了满足用户直接连接到开发板的需求,Nuclei Studio 新增了 Connect to Running Target 功能。该功能支持直接连接正在运行的硬件目标板,用户可以进行如读取开发板相关信息等操作,极大方便了开发的效率。

在Nuclei Studio中 Connect to Running Target 仅支持OpenOCD和Jlink两种方式。下面以OpenOCD的方式来展示 Connect to Running Target 的使用。

使用 Connect to Running Target 功能非常简单。连接好开发板,并创建一个demo工程,当工程编译好后选中工程,在鼠标右键弹出的菜单,或者在IDE的工具菜单中找到 Connect to Running Target 菜单并点击。

image75

在console窗口中可以看到,gdb尝试连接到开发板中。

image76

当IDE连接上开发板后,用户可以通过IDE的 Debugger Console 工具来发送gdb命令来查看开发板当前的一些信息。

image77

2.9.5.1. 查看Nuclei CPU Information

Connect to Running Target 后,用户可以通过IDE的 Debugger Console 工具来发送命令 info reg misa 来查看当前 CPU 的 misa 信息。misa 会直接在 Debugger Console 中显示。

image78

用户也可以通过IDE的 Debugger Console 工具来发送命令 monitor nuclei cpuinfo 查看当前 Nuclei CPU Information ,因为 eclipse 的机制,Nuclei CPU Information 可能不会在 Debugger Console 中显示,但可以在 gdb trace 中查看到。

首先,打开 gdb trace 功能。在Nuclei Studio 中打开菜单 Windows -> Preferences

image79

搜索 gdb,在 gdb 配置页中找到并勾选 Show the GDB trace console with character limit

image80

通过IDE的 Debugger Console 工具来发送命令 monitor nuclei cpuinfo

image81

然后在 Console 窗口中找到 gdb trace 视图并打开。

image82

gdb trace 视图中可以查看到 Nuclei CPU Information。

image83

2.9.6. Flash Programming

为了满足用户将编译好的二进制文件直接下载到硬件开发板的需求,Nuclei Studio 新增了 Flash Programming 功能。该功能允许用户快速、便捷地将编译好的二进制文件直接下载到硬件开发板中,极大提升了开发和调试的效率;简化操作流程,用户只需点击一次即可完成二进制文件的下载。工程编译好后,找到Flash Programming,并点击,即可完成二进制文件的下载。

image64

用户也可以修改其相关的配置信息,在Launch Bar中点击配置按钮,打开配置页面,然后选中Flash Programming选项卡。

image65

Load Program Image

Load的文件,默认的elf格式的文件,也可以支持 *.bin、*.hex、*.s19、*.srec、*.symbolsrec 等各种格式

image66

Flash Programming Options

Flash Programming的选项有以下三个

  • Verify Image:在烧录完成后,会校验烧录的镜像文件与当前连接的目标设备上下载进去的文件是否一致,确保烧录成功。

  • Reset and Run:烧录完成后,让CPU复位并运行,需要注意如果勾选了 Load in RAM, 则只会运行不会复位(如程序烧录在RAM中,复位将会使程序丢失)。

  • Load in Ram:勾选这个表示固件需要下载到内存中,而不是Flash等非易失性存储器上,选中后,必须指定Program Address。

Note

Load in Ram勾选和不勾选固件下载方式不一样,所使用的OpenOCD命令也不同,后续文档中有详细介绍,请仔细阅读并根据实际情况准确选择。

上述参数的使用,与工程的Download模式匹配,Nuclei Studio中默认支持 DDR/ILM/SRAM/FLASH/FLASHXIP

当工程Download模式是 DDR/ILM/SRAM 时,Load in Ram 必须选中,同时 Program Address 地址也不能为空,这里的 Program Address 地址是程序烧写入Ram时的第一个地址。

一般 Program Address 可以在 *.map 文件中找到,或者执行 riscv64-unknown-elf-readelf -h /path/to/your.elf后查看Entry point address,本文档仅介绍从 *.map 文件中查找 Program Address

打开 *.map 文件,搜索 Linker script and memory map ,然后找到 .init 后面的这个地址就是 Program Address

image72

当选中 Load in Ram 时, 同时选中 Verify Image ,命令行中将多一行命令 -c "verify_image Debug/test.elf" ,此时是通过 verify_image 命令来实现镜像文件的检查。

当选中 Load in Ram 时, 同时选中 Reset and Run 、命令行中将多一行命令 -c "resume 0x80000000; shutdown" ,此时是通过 resume 命令来实现load后可能强制系统复位。

-c "set BOOT_HARTID 0;"
-f "nuclei_sdk/SoC/evalsoc/Board/nuclei_fpga_eval/openocd_evalsoc.cfg"
-c 'echo "Start to program Debug/test.elf to 0x80000000"'
-c "load_image Debug/test.elf"
-c "verify_image Debug/test.elf"
-c "resume 0x80000000; shutdown"

image73

当工程Download模式是 FLASH/FLASHXIP 时,则不勾选 Load in Ram,并且 Program Address 为必须为空。

当选中 Verify Image ,命令行中将多一行命令 verify ,此时是通过 verify 命令来实现镜像文件的检查。

当选中 Reset and Run ,命令行中将多一行命令 reset ,此时是通过 reset 命令来实现load后可能强制系统复位。

-c "set BOOT_HARTID 0;"
-f "nuclei_sdk/SoC/evalsoc/Board/nuclei_fpga_eval/openocd_evalsoc.cfg"
-c 'echo "Start to program Debug/test.elf"'
-c "program Debug/test.elf verify reset exit"

image74

OpenOCD Flash Programming Command line

Flash Programming中的参数最终将通过OpenOCD执行。默认情况下, Customize openocd flash programming command line 选项是未选中的。当您勾选 Customize openocd flash programming command line 时,所有其他相关选项将失效。此时,您可以直接在下方的输入框中输入自定义命令。

如果您对OpenOCD命令有足够的了解,可以尝试自定义命令以满足特定需求。然而,如果您不熟悉OpenOCD命令行操作,建议不要勾选此选项,以免导致配置错误。

image70

根据需求配置好参数后,点击Flash Programming就可以下载二进制代码到硬件中,下载成功的结果如下图。

image71