Update FPGA and Vivado skills

This commit is contained in:
Myfro9
2026-07-14 18:18:17 +08:00
parent d20ec12fee
commit bceafcd58c
14 changed files with 1707 additions and 14 deletions
+119
View File
@@ -0,0 +1,119 @@
---
name: fpga_update
description: 通过网络远程升级 SMOD 板(192.168.1.143)上 ATSC 激励器工程的 FPGA 镜像——先用 Vivado + perl 生成 quickboot 的 _update.mcs,再用 TCP 1234 的私有协议把它流式烧进 SPI flash 的 update 槽。只要用户提到"远程升级"、"升级 mcs"、"把新 bit 升上去"、"update mcs"、"远程更新 FPGA"、"Xfpga_ru"、"生成 quickboot mcs"、"quickboot"、"RU_golden 之后怎么升级"、"192.168.1.143 升级",或者在 my_exciter 工程里跑完综合实现后想把结果固化到板子上,就必须用这个 skill——哪怕他们没说"skill"、没提 mcs,只说了"升上去"、"更新一下 FPGA"、"重新出个 mcs"。注意:这条路和网页上的 Remote Update 完全无关(那个只认 imx6 的 tar.gz 固件包)。JTAG 直烧打底镜像请改用 fpga_flash skill。
---
# SMOD FPGA 远程升级
把 `my_exciter` 工程实现出的 `.bit` 变成 quickboot 更新镜像,再通过网络烧进板子的 SPI flash。
板子必须**事先用 JTAG 烧过 `RU_golden`** 才支持远程升级 —— golden 提供上电时的兜底镜像和
IPROG 跳转头。没烧过 golden 就先走 `/fpga_flash`。
## 先搞清楚你在走哪条路
这是最容易出错的地方,两条路互不相干:
| | 这个 skill | 网页 Remote Update |
|---|---|---|
| 升什么 | **FPGA 镜像**(`.mcs`) | **imx6 固件包**(`.tar.gz`) |
| 走哪 | TCP **1234**,私有帧协议 | HTTP `upload.cgi` → `check_package.sh` |
把 `.mcs` 传到网页上不会报错,但 `check_package.sh` 找不到 `*.tar.gz` 就会
`rm -rf /aw/upgrade/*` 把它删掉,什么都不会发生。原厂的 GUI 工具是 `tools/Xfpga_ru.exe`,
没有命令行接口;`scripts/fpga_ru.py` 是它的等价替代,而且会告诉你失败在第几帧。
## 流程
### 1. 生成 `_update.mcs`
```bash
python scripts/gen_update_mcs.py # → bitstream/atsc_exciter_update.mcs
python scripts/gen_update_mcs.py --tag smod_dpd # → bitstream/smod_dpd_update.mcs
```
脚本按顺序跑项目里一直在用的那三个脚本(`post_bitstream.tcl` → `runScript_GenRu.tcl` →
`MakeSpiFlashProgrammerMcsFiles_backup.pl -imagesize 64`),然后校验产物的起始地址是
`0x800000`(这等价于"确实是用 `-imagesize 64` 生成的")。
它还替你挡了一个坑:`runScript_GenRu.tcl` 里是 `glob *.bit`,而 `bitstream/` 目录里躺着二十几个
历史 `.bit`。脚本会把旧的临时挪走、跑完再放回去。**别绕过它去手动跑 tcl**,除非你已经清空了目录。
`-imagesize 64` 不要改。它和 `SpiFlashProgrammer.vhd` 里的 `cAddrUpdateStart/End` 是一对,
理由见 `references/quickboot.md`。
### 2. 确认 ADPC 为 OFF(保险起见)
DPD 的 sample&load 和升级数据流共用同一条 SPI1,而 FPGA 在升级期间会把 SPI1 上任何字都当成镜像数据。
这条路径没被验证过(三次连续升级成功那次 `adpc=0`),所以稳妥起见先关掉:
```bash
# 登录后读 sys_cfg,第 3 个字段就是 adpc(0=OFF)
curl -s -b "session=$SESS" "http://192.168.1.143/atsc_status_cfg.cgi?sys_cfg=&"
```
网页账号是 **`anywavecom` / `anywavecom`**(不是 `root`;`root/anywavecom` 是 SSH 的)。
### 3. 烧进去
```bash
python scripts/fpga_ru.py --mcs bitstream/atsc_exciter_update.mcs
python scripts/fpga_ru.py --mcs ... --dry-run # 只校验文件,不碰硬件
```
先跑 `--dry-run`。它会检查行长、整行切分、EOF 记录、起始地址 —— 这些错误在真机上要等几分钟
才会以一个没有上下文的 `ABORT_ERROR` 暴露出来。
烧写要几分钟(8 MB,约 47600 帧)。**中途不要断电、不要重试。** 真断了也不会变砖:升级一开始就把
切换字擦掉了,冷启动会退回 golden。
成功后 app 会自动重启 imx6、复位 FPGA。然后**冷启动板子**(遵守 SMOD 上电时序)让 FPGA 从 flash
重新加载新镜像。
### 4. 验证
抓 ILA、看 app 日志(`/var/module_log/imx_atsc_app.log`)、或者看频谱。
闭环调试交给 `fpga-imx6-flow` skill。
## 排错
`fpga_ru.py` 会打印失败在哪一步、哪一帧、收到什么 ack。对着这张表看:
- **擦除永不结束**(最容易误判的一个)→ 十有八九 programmer 已经报错退出了。
imx6 的 `POLL_ERASER` **不看 ERROR 位**,把"已失败"当成"还在擦",所以客户端只会一直等。
别信进度条,直接读设备日志:
```bash
ssh -o HostKeyAlgorithms=+ssh-rsa root@192.168.1.143 \
"grep 'ing|end' /var/module_log/imx_atsc_app.log | tail -3"
```
`rstate=0x7`(ERROR=1, DONE=1, EraseOK=0)= programmer 中止;`rstate=0x0` 才是真的在擦,
擦完会看到 `rstate=0xc` + `UPSTATE_EARSE_END`。
历史上这里的元凶是 `smod_top.v` 没把 flash 的 SPI 引脚接出去,见 `references/protocol.md`。
- **`ABORT_ERROR` 出现在第一帧** → mcs 格式不对,先跑 `--dry-run`。
- **`ABORT_ERROR` 出现在数据流中后段** → 怀疑 SPI1 上有别人(DPD)在写,把 ADPC 关掉重试。
- **没有应答 / 超时** → app 的 `sys_ready` 还是 0,或者 app 没在跑。
`ssh root@192.168.1.143 'ps | grep atsc'`(SSH 密码 `anywavecom`,dropbear 老得很,
命令行 ssh 要加 `-o HostKeyAlgorithms=+ssh-rsa`)。
> 别用 `python ssh.py "tail -f ..."` 之类一次性读到 EOF 的封装去跟日志 —— 它永远不返回,
> 什么也抓不到。升级完再 grep 日志文件即可,`log_printf` 已经落盘。
## 不碰硬件地改协议客户端
`scripts/mock_device.py` 是照着 `tcp_task.c` 的状态机实现的假设备,包括那三个硬限制和
`':'` 重切分行为。改完 `fpga_ru.py` 先拿它跑一遍:
```bash
python scripts/mock_device.py --port 12340 &
python scripts/fpga_ru.py --mcs <某个>_update.mcs --host 127.0.0.1 --port 12340 --yes
```
正确的一次会让 mock 收到**恰好 8388608 字节(8.000 MiB)**—— 正是 `cAddrUpdateEnd - cAddrUpdateStart`。
对不上就是客户端的分帧错了。`--not-ready-every N` / `--abort-at-frame N` 可以逼出重传和中止路径。
## 参考
- `references/protocol.md` —— TCP 1234 帧格式、时序、三个硬限制、DPD 污染缺陷的完整证据链
- `references/quickboot.md` —— flash 布局、切换字兜底、为什么是 `-imagesize 64`、两条烧写路径的区别