Files
skills-win/fpga_update/references/quickboot.md
T
2026-07-14 18:18:17 +08:00

78 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Flash 布局与 QuickBoot 兜底
板上 flash:Winbond **w25q128bv**,128 Mbit = 16 MB,SPIx1,**24-bit 地址**,64 KB sector / 4 KB subsector。
## 三个地址,一个都不能记错
来自 `my_exciter.srcs/sources_1/quickboot/SpiFlashProgrammer.vhd`(**RU_golden 和 my_exciter 引用的是同一份文件**,
见 `RU_golden.xpr` 里的 `$PPRDIR/../my_exciter/.../SpiFlashProgrammer.vhd`,所以两个工程的常数天然一致):
```vhdl
cAddrUpdateStart = X"00400000" -- update 镜像起点
cAddrUpdateEnd = X"00C00000" -- update 镜像终点+1 → 槽宽 8 MB
cAddrSwitchWordN25Q = X"00000FFC" -- 切换字
cAddrWidth = 24 -- 和 w25q128bv 匹配
```
flash 实际布局(从 `golden_design_initial.mcs` 解码得到,不是推测):
```
0x000000..0x000FFB FF FF ... 空
0x000FFC 00 99 55 66 切换字(AA 被写成 00 = 无效)
0x001000 20000000 NOOP
30020001 00400000 写 WBSTAR = 0x400000
30008001 0000000F 写 CMD = IPROG → 跳到 update 镜像
0x001050 AA995566 golden bitstream 自己的同步字
..0x3FFFFF golden bitstream(RU_golden_top.bit,3.4 MB)
0x400000..0xBFFFFF update 镜像(8 MB,日常远程升级写这里)
0xC00000..0xFFFFFF 未用
```
**兜底机制**:上电时 FPGA 从地址 0 扫描同步字。
- 切换字 = `AA995566` → 在 0xFFC 同步 → 执行 0x1000 处的 IPROG → 加载 update 镜像。
- 切换字 ≠ `AA995566`(擦除后是 `FFFFFFFF`)→ 0xFFC 不同步 → 继续扫 → 在 0x1050 撞上 golden 的同步字 → **加载 golden**。
远程升级一开始就把切换字所在的 subsector 擦掉(`sProgrammerEraseSwitchWord`,SSE 命令,
擦 `0x000000..0x000FFF`),写完校验通过后再把切换字写回去。所以**升级中途断电只会退回 golden,不会变砖**。
> subsector 是 4 KB,擦 0xFFC 只波及 `0x000000..0x000FFF`。IPROG 头在 `0x001000`,属于下一个
> subsector,**不会被擦到**。golden 是安全的 —— 如果怀疑"升级把 golden 弄坏了",可以排除这条。
## 为什么 `-imagesize 64`
perl 脚本的模型是"golden 和 update 一样大、update 紧跟 golden":
`imageSizeBytes = imagesize(Mbit) × 131072`,`updateStartAddr = imageSizeBytes`。
- **golden**(`MakeSpiFlashProgrammerOnlyInitMcs.pl -imagesize 32`)→ 4 MB → IPROG 里的
WBSTAR = `0x400000`,和 `cAddrUpdateStart` 对上。日志见 `RU_golden/bitstream/gen_initial.log`。
- **update**(`MakeSpiFlashProgrammerMcsFiles_backup.pl -imagesize 64`)→ 8 MB → 负载
`pad(bitstream, 0x7FFFFC) + crc32` 正好 8 MB,和槽宽 `0xC00000-0x400000` 对上。
两个 imagesize 不一样是**故意的**(VHDL 注释里的 "Plan B: golden enlarged to 4MB"),别去"统一"它们。
`_update.mcs` 里的 Intel-HEX 地址写的是 `0x800000`,看起来和 `cAddrUpdateStart=0x400000` 矛盾 ——
**它不矛盾,因为地址被忽略**。imx6 的 `recv_upgrade_data_parse()` 只从 `:10xxxx00<32 hex>` 记录里抠出
16 个数据字节,扩展线性地址记录 `:02000004` 直接当"中间控制字段"丢掉。FPGA 从 `cAddrUpdateStart`
顺序写。所以对远程升级而言,`_update.mcs` 只有**负载长度**和**CRC**是有意义的。
校验 `_update.mcs` 的起始地址是 `0x800000`,本质上是在校验"这个文件是用 `-imagesize 64` 生成的"。
## 两条烧写路径,别搞混
| | JTAG 直烧 | 网络远程升级 |
|---|---|---|
| 文件 | `RU_golden/bitstream/golden_design_initial.mcs` | `bitstream/<tag>_update.mcs` |
| 工具 | `/fpga_flash` skill(flash 型号 `w25q128bv`) | `scripts/fpga_ru.py` |
| 写到 | `0x000000..0x3FFFFF` | `0x400000..0xBFFFFF` |
| 何时用 | 首次装机、板子变砖、换打底镜像 | 日常迭代 |
`_update.mcs` **不能**拿去 JTAG 烧写:它只是 8 MB 裸数据 + CRC,没有 bitstream 头。
反过来 `_initial.mcs` 也不能拿去远程升级。
严守上电时序:断电 → 断 USB-Blast → 上电 → 连 USB-Blast → 烧写 → 断电 → 断 USB-Blast → 上电 → 连 USB-Blast。
## 调试期的第三条路
`program_device` 直接把 `.bit` 下到 FPGA,掉电即失,不碰 flash,配 `.ltx` 还能抓 ILA。
迭代验证用它最快,功能确认后再走远程升级固化。固化用的 bit 要**去掉 ILA 重新实现**。