在前面的教程中,我们已成功完成了开发环境的配置,并在紫光 FPGA 平台上实现了 SparrowRV 软核底层架构的例化与管脚约束。
在 FPGA 的 SoC 开发流中,底层硬件逻辑的综合部署意味着物理平台已经就绪。今天,我们将正式切入“软硬协同设计”的核心环节:我将带大家在 MounRiver Studio 中编写第一个 RISC-V C 语言应用程序,并详细解析 BRAM 固化与 JTAG 烧录这两种工程中常用的程序部署方案,最终将机器码下发至紫光板卡,实现 RISC-V 处理器的完整启动与运行。
一、编写 RISC-V 应用程序
打开你下载好的 SparrowRV 源码包,在 /bsp/bsp_app/ 目录下找到咱们的软件工程文件 SparrowRV_APP.wvproj,双击使用 MounRiver Studio (MRS) 打开。
在这个默认的工程模板中,已经为大家准备好了一个基础程序。为了让大家能举一反三,先带你盘点一下 SparrowRV 提供的几个核心底层 API 函数:

1、核心外设与延时 API
init_uart0_printf(band, fpioa_port):
功能:初始化 UART0 串口并绑定到指定的 FPIOA 引脚,同时重定向 printf 函数。
参数:baud 是波特率(如 115200);fpioa_port 是你上一期在 .fdc 约束文件里分配的 FPIOA 端口号(例如映射到 fpioa[0] 则填 0)。
delay_mtime_us(uint32_t us):
功能:基于 RISC-V 内核机器定时器 (mtime) 的高精度微秒级硬件延时。
2、printf 打印模板
重定向完成后,你可以像在电脑上写 C 语言一样随心所欲地打印各种格式的数据,方便咱们后续做实验:
printf("%d", xxx);
printf("%ld", 12345678L);
printf("%llu", 0xA3);
printf("%s", "String");
printf("%c", 'a');
printf("%f", 10.0);
3、硬件系统信息自动获取
在 system.h 中,底层库为我们定义了一组极其方便的全局变量。这些变量不需要你手动赋值,系统启动时会自动从底层的硬件寄存器中实时读取:
system_cpu_freq:CPU 主频 (Hz)
system_cpu_freqM:CPU 主频 (MHz)
system_iram_size:指令存储器大小 (字节)
system_sram_size:数据存储器大小 (字节)
system_vendorid:Vendor ID
4、一键编译生成机器码
代码编写完成后,点击 MRS 顶部工具栏的 Build(编译)按钮。
编译成功后,工程的 obj/ 文件夹下会生成一个名为 SparrowRV_APP.bin 的固件文件。在微控制器的世界里,这个 .bin 文件就相当于纯粹的机器码指令流,接下来我们要做的就是把它塞进 FPGA 里!

二、 路线 A:无调试器(BRAM 固化烧录法)
如果你手头没有 J-Link 下载器,完全可以使用这套“FPGA 传统手艺”。核心思路是:将 .bin 转成十六进制文本,作为底层 BRAM (RAM IP 核) 的初始值,连同 Verilog 硬件逻辑一起重新综合进芯片。
1、格式转换:
-
方案一(官方工具):运行 SparrowRV 文件夹
/tb/工具箱.bat,根据指示操作,它会在当前目录自动生成一个inst.txt文件。 -
方案二(派大星推荐定制工具):使用我专门编写的小工具 fpga.gt.tc(如有需求可自行下载)。它支持可视化重命名和自定义保存路径,操作更直观。
2、底层重映射:
-
打开上一期咱们建好的 PDS 硬件工程,找到
config.v文件。 -
将初始化文本的路径指向你刚刚生成的
.txt文件。
3、重新综合:
点击 PDS 的 Generate Bitstream 重新生成 .sbit 比特流文件,用紫光官方下载器烧入板卡,即可看到程序运行!
三、 路线 B:有调试器(J-Link 命令行在线烧录)
对于有 J-Link 的同学,在线调试和烧录体验会好非常多,再也不用每次改行 C 代码都去苦等 FPGA 重新综合了。这里教大家如何使用终端命令行配合 OpenOCD 完成极速烧录。
请先打开终端(CMD/PowerShell),使用 cd 命令跳转到配置文件所在的目录(官方配置位于 /bsp/OpenOCD/ 下)。

方法一:官方标准两步走
使用官方的 SparrowRV_jlink.cfg 文件,过程稍微有一点仪式感。
第一步:启动 GDB Server
在当前目录终端输入以下命令:
openocd -f SparrowRV_jlink.cfg
如果你看到终端弹出了如下信息,恭喜你,J-Link 已经成功连接上了紫光芯片内部的 RISC-V 软核:
Info : [riscv.cpu] Examination succeed
Info : [riscv.cpu] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
第二步:Telnet 交互烧录
注意!不要关闭刚才的终端窗口。重新打开一个全新的终端管理员窗口,通过 Telnet 连入本机的 4444 端口:
telnet localhost 4444
会进入如下界面:

进入交互界面后,依次输入以下这些命令:
# 1. 暂停 CPU
halt
# 2. 烧录你的 .bin 文件(路径换成你自己的)
load_image "d:/MRS_prj/obj/SparrowRV_APP.bin"
# 3. 恢复 CPU 运行,程序就开始跑啦!
resume
方法二:定制自动化一键烧录
如果你嫌每次都要输入这三行命令太麻烦,可以下载使用我定制的 .cfg 脚本文件(获取地址:fpga.gt.tc)。
-
先用文本编辑器打开这个定制的
.cfg文件,在文件内部将.bin的路径修改为你自己的绝对路径并保存。

- 在终端中直接运行:
openocd -f SparrowRV_jlink.cfg
当终端打印出下面这段霸气的提示时,说明脚本已经自动帮你完成了暂停、烧录、复位重启的全套动作,程序已经无缝跑起来了:
==========================================
Download complete! Starting program...
==========================================
方法三:基于 MounRiver Studio 的 IDE 一键烧录
对于追求极致开发效率的工程师来说,脱离繁琐的命令行,直接在 IDE 内部完成“编译-下载-运行”的闭环是最佳选择。借助 MounRiver Studio 强大的外部工具集成功能,我们可以轻松实现这一点。
配置与操作步骤:
-
进入下载配置: 在 MounRiver Studio 顶部菜单栏中,依次点击 “闪存 (Flash)” -> “下载配置 (Download Configuration)”,打开外部下载工具设置界面。

-
指定下载引擎: 在弹出的窗口中,找到 “命令 (Command)” 输入框,将其路径修改为你电脑中 OpenOCD 可执行文件的绝对路径(即我们在第一章
-
环境配置时安装的路径,例如
C:\openocd\bin\openocd.exe)。 -
调用定制烧录脚本: 在 “参数 (Arguments)” 输入框中,填写调用配置文件的执行指令。

⚠️ 核心重点: 为了无缝适配 MRS IDE 的自动化下载逻辑,这里必须且仅能使用我为大家专门编写的定制版
.cfg文件(下载地址:fpga.gt.tc),官方自带的 cfg 脚本在此处无法直接串行执行。填写格式为:
-f "你的存放路径/SparrowRV_jlink.cfg"(请根据实际情况替换路径,注意路径中尽量使用正斜杠/)。 -
全自动烧录: 配置完成后点击“Apply”并关闭窗口。至此,IDE 已经与底层 J-Link 打通。后续每次修改完 C 语言代码并 Build 之后,你只需点击软件界面上的“下载”图标,底层固件就会全自动烧入紫光 FPGA 并在软核上欢快地跑起来了!

本教程使用的板卡j-link连线如下:

到这里,咱们从零开始配置环境、搭建硬件、写代码到最终烧录跑通的全链路,就已经彻底打通了!

收评,集成Risc-v还是挺实用的应用,期待更新