本文档记录 RA6W1 / EK-RA6W1 板卡上 Zephyr 工程的完整流程:编译 → 打包 DA16 镜像 → 通过 J-Link + Renesas Flash Programmer 烧录 → 串口查看输出。
所有命令均在 west 工作区根目录 D:/luglZephyrproject 下执行(这样 west 才能找到 .west/)。
1. 依赖与路径
| west 工作区根目录 | D:/luglZephyrproject |
| Zephyr 源码树(本地 fork) | D:/luglZephyrproject/zephyr |
| Zephyr SDK | D:/luglZephyrproject/zephyr-sdk-1.0.1/zephyr-sdk-1.0.1 |
| 应用仓库(本 repo) | D:/luglZephyrproject/app |
| 镜像打包脚本 | D:/RA/RRQ61051/tools/rafw-fsp-packs/v2.2.1/Renesas.rafw_mcu_ra6w1.2.2.1/scripts/gen_rrq61_flash_image.py |
| Renesas Flash Programmer | C:/Program Files (x86)/Renesas Electronics/Programming Tools/Renesas Flash Programmer V3.24/rfp-cli.exe |
| 一条龙打包+烧录脚本 | D:/RA/RRQ61051/tools/flash_ra6w1.sh |
| 串口抓取工具 | D:/RA/RRQ61051/tools/uart_capture.py |
| 板卡 | EK-RA6W1,SoC 型号 r7sa6w1ce,J-Link 序列号 1100011279 |
2. 设置环境变量(每次新开终端都要执行)
shell 默认没有 Zephyr 环境变量,必须先导出:
export ZEPHYR_SDK_INSTALL_DIR=D:/luglZephyrproject/zephyr-sdk-1.0.1/zephyr-sdk-1.0.1
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
3. 编译
3.1 全量编译(清空构建目录重来)
cd /d/luglZephyrproject
west build -b ek_ra6w1 -d build_shell_led app/shell_led -p always -- -DCONFIG_ARM_MPU=n -DCONFIG_FPU=n
-b ek_ra6w1 — 板卡名,qualifier 为 r7sa6w1ce
-d build_shell_led — 构建目录放在工作区根目录,不要放在 app/ 里;构建目录不进 git
-p always — 先删除并重建构建目录(全新编译用这个)
-- -D... — 传给 Kconfig 的额外选项
3.2 增量编译(改完代码重新编译)
去掉 -p always,其它参数保持一致:
cd /d/luglZephyrproject
west build -b ek_ra6w1 -d build_shell_led app/shell_led -- -DCONFIG_ARM_MPU=n -DCONFIG_FPU=n
3.3 编译其它工程
把应用目录和构建目录名换掉即可,其余完全一样:
west build -b ek_ra6w1 -d build_uart0_test app/uart0_test -p always
west build -b ek_ra6w1 -d build_wifi_scanmin app/wifi_zephyr -p always
3.4 编译成功的标志
Linking C executable zephyr\zephyr.elf
Memory region Used Size Region Size %age Used
FLASH: 47884 B 8 MB 0.57%
RAM: 9696 B 256 KB 3.70%
...
Generating files from .../zephyr.elf for board: ek_ra6w1/r7sa6w1ce
产物:build_shell_led/zephyr/zephyr.bin(纯 bin,47884 字节)。
4. 打包成 DA16 烧录镜像
RA6W1 的 boot ROM 认的是 DA16 格式,不能直接把 zephyr.bin 烧进去,必须先包一层:
cd /d/luglZephyrproject
python "D:/RA/RRQ61051/tools/rafw-fsp-packs/v2.2.1/Renesas.rafw_mcu_ra6w1.2.2.1/scripts/gen_rrq61_flash_image.py" \
build_shell_led/zephyr/zephyr.bin \
build_shell_led/zephyr/zephyr.img \
RA6W1-RRQ61001
产物:build_shell_led/zephyr/zephyr.img(57100 字节 = 0x2000 + 0x400 + 47884)。
脚本可能打印 rafw_gen/hal_data.c is not exist. / common_data.c is not exist. / configuration.xml file not found, skipping OTA image generation. —— 这些是 FSP 配置生成相关的 非致命提示,不影响镜像生成。
镜像布局
| 0x0000 | Product Header(4 KB)+ 0x1000 处备份 |
| 0x2000 | DA16 头(0x400 字节) |
| 0x2400 | zephyr.bin 起始 —— 同时是 CPU 0x0 处的 IVT(VTOR=0) |
因为 boot ROM 会把镜像 IVT 映射到 CPU 0x0,所以板级 defconfig 里是 CONFIG_FLASH_LOAD_OFFSET=0(Zephyr 的向量表必须链在 CPU 0x0)。
5. 烧录
5.1 一条龙(推荐:打包 + 烧录一步完成)
flash_ra6w1.sh 内部做的就是「打包 → 调 rfp-cli 烧录」两件事:
cd /d/luglZephyrproject
bash /d/RA/RRQ61051/tools/flash_ra6w1.sh build_shell_led/zephyr/zephyr.bin
5.2 分步烧录(镜像已经打包好时)
cd /d/luglZephyrproject
"/c/Program Files (x86)/Renesas Electronics/Programming Tools/Renesas Flash Programmer V3.24/rfp-cli.exe" \
-d RA6W1 -t "jlink:1100011279" -if swd -a -run \
-bin 0x0 build_shell_led/zephyr/zephyr.img -noprogress -noquery
参数说明:
-d RA6W1 — 器件型号
-t "jlink:1100011279" — J-Link 及其序列号(换板子要改成实际序列号)
-if swd — SWD 接口
-a — 擦除 + 写入 + 校验
-run — 烧完复位并运行
-bin 0x0 — 从地址 0 开始写(DA16 头里的 0x2000 偏移由镜像自己描述)
5.3 备选路线:J-Link Commander 直接烧录
实测发现(2026-10,SEGGER J-Link V9.88 / 内置 DLL V9.78):
J-Link 器件库已支持 RA6W1,设备名就是 R7SA6W1CE(即板的实际型号 R7SA6W1CEDZDD)。CLAUDE.md 里"device name 仍未知"的说法已过期。
J-Link 自带这颗外部 xSPI flash 的 loader:Erase 命令能真正擦除整片 (实测 0.763 s),说明它能驱动 OQSPI 控制器。
命令行有这些坑:
loadfile / loadbin 都按扩展名判断格式,.img 一律报 File is of unknown / unsupported format —— 必须先把 DA16 镜像改名成 .bin。
ShowFlashInfo 在 V9.88 里不存在。
VerifyBin 读的是 CPU 内存映射(不是 flash 芯片原始偏移),不能用来判断编程偏移。
仓库里放了现成脚本 app/tools/flash_ra6w1_jlink.sh(打包 + Commander 脚本 + 烧录 + 读向量表校验):
cd /d/luglZephyrproject
bash app/tools/flash_ra6w1_jlink.sh build_shell_led/zephyr/zephyr.bin
地址映射模型(已用逐字节比对实测确认):
boot ROM 复位后处于 ROM 区(CPU 0x0 是 ROM 代码),启动完成后把 sflash 0x2400 重映射到 CPU 0x0;
换算关系:CPU 地址 + 0x2400 = sflash 片内偏移 (读 CPU 0x2400 得到 68A0FDBF FEE4F004…,与镜像文件 offset 0x4800 逐字节一致);
运行态读 CPU 0x0 得到向量表 200021E0 00003545 0000818F 00003531, 与镜像文件 offset 0x2400 完全一致。
注意:J-Link 的 flash bank 到底把 CPU 0x0 当作 chip offset 0 还是 0x2400, 这一点尚未验证(loadbin 实写那一步当时被环境的安全策略拦下,未能执行)。 两种可能的结果:
| 地址模型正确 | 烧完板子正常启动,J-Link 读 CPU 0x0 = 向量表,不进 HardFault |
| 地址模型不对 | 板子停在 HardFault(PC=EFFFFFFE),用 RFP 一条龙脚本恢复即可 |
所以:日常烧录仍建议用第 5.1 节的 RFP 一条龙脚本,J-Link 路线作为备选, 首次使用前请确保手边有 RFP 恢复手段。
5.4 烧录成功的标志
Loading flash configurations file... (Resources\RA6W1\flash_configurations)
Completed.
Loading bootloader binary... (Resources\RA6W1\uartboot.bin)
Completed. 49.4 K
Read xSPI flash device informations...
Completed.
Connected to RA
Erasing the target device
[External Flash 1] 00000000 - 007FFFFF
[External Flash 1] 00000000 - 0000DFFF
Writing data to the target device
[External Flash 1] 00000000 - 0000DF7F
Verifying data on the target device
[External Flash 1] 00000000 - 0000DF7F
Disconnecting the tool
Operation successful
Operation successful 即烧录+校验+运行全部成功。写入范围 0x0000 - 0xDF7F 对应 0x2000(偏移)+ 0x400(DA16 头)+ 47884(bin)= 57100 字节。
5.5 烧录时串口上会刷的东西(不是应用输出)
用 RFP 烧录的同时盯着 COM58,你会看到这样一串:
*** Booting Zephyr OS build v4.4.0-34-g57cd83209aa1 *** ← 旧镜像先启动
shell_led ready, try: led on | off | toggle | blink 200
uart:~$ ← Zephyr shell 提示符
RRQ61000 uartBoot Feb 17 2026 11:01:56 ← uartboot 接管
flash id is 0x1f 0x68 0x01 ← 读 QSPI flash ID
CMD Done
cmd_erase_qspi / CMD Done × 2062 ← 反复擦除
这是烧录流程本身的日志,不是应用的打印,也说明不了"用了哪种下载方式"以外的任何问题。 机制是这样的:
RFP 通过 SWD 把 uartboot.bin(约 49 KB)灌进目标 RAM;
RFP 主控与 uartboot 之间是 UART 上的文本协议(走 COM58 这条 J-Link CDC 通道);
RFP 下发 cmd_erase_qspi 等命令,由 uartboot 去驱动 OQSPI 控制器真正擦写 QSPI flash;
cmd_erase_qspi / CMD Done 重复上千次,是 RFP 在轮询擦除进度(8 MB 擦一遍要时间)。
所以:RFP 才是真正执行擦写的角色,J-Link 只是搬运 uartboot 的载体(走 SWD)。 这也解释了为什么 flash id is ... 只打印一次(uartboot 只在启动时识别一次 flash)。
6. 串口实战
控制台:UART0,P0_00(RX) / P0_01(TX),115200 8N1(板上 J201 的 pin 2/4)
串口号:COM58(J-Link 自带的 CDC UART Port) ← 实测确认 给 COM58 发 led on,板子回 LED on 并重绘 uart:~$ 提示符。
shell_led 启动后(串口会打印 shell_led ready, try: led on | off | toggle | blink 200) 可以通过 shell 下发命令:
led on
led off
led toggle
led blink 200 # 周期 200 ms
led stop # 停止闪烁

7. 常见问题
7.1 west flash 不能用
boards/renesas/ek_ra6w1/board.cmake 里的 J-Link runner 是占位实现,west flash 基本必然失败。请一律使用第 5 节的 RFP 方式。
更新:J-Link 的 device name 其实已经确定了 —— 是 R7SA6W1CE(SEGGER V9.78 器件库 已支持,见 5.3 节)。west flash 失败的原因不是设备名未知,而是 board.cmake 里没接 外部 QSPI flash 的烧录逻辑。
7.2 gen_rrq61_flash_image.py: can't open '.../zephyr.bin'
说明上一步编译失败了,镜像根本没生成。回到第 3 步看编译错误。
7.3 编译报 implicit declaration of function 'chunk_trailer'
Zephyr fork 的 lib/heap/heap.c 在 sys_heap_free() 里引用了 chunk_trailer(), 而它只在 CONFIG_SYS_HEAP_CANARIES 打开时才存在(由 CONFIG_SYS_HEAP_HARDENING_FULL/ EXTREME 选中)。已在 fork 中修复:这些 RA6W1 调试钩子统一由 CONFIG_SYS_HEAP_APP_HOOKS 开关控制(默认 n),wifi_zephyr 在 prj.conf 里显式打开。若仍报此错,说明 fork 版本偏旧, 需要更新到包含 heap: gate RA6W1 debug hooks behind CONFIG_SYS_HEAP_APP_HOOKS 的版本。
7.4 warning: FPU ... was assigned the value 'n' but got the value 'y'
只是警告,不影响构建。 soc/renesas/ra/ra6w1/Kconfig 里是 select FPU, FPU 被 SoC 强制选中,命令行传 -DCONFIG_FPU=n 无效,最终仍按 hard-float 编译 (-mfpu=fpv5-sp-d16 -mfloat-abi=hard)。想真正关掉 FPU 只能改 Kconfig,没有必要。
7.5 -p always 会删掉整个构建目录
-p always = pristine build,会先删除 -d 指定的目录。日常改代码用增量编译(3.2 节), 不要每次都 -p always。
我要赚赏金
