6.3 KiB
name, description
| name | description |
|---|---|
| fpga_update | 通过网络远程升级 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
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),所以稳妥起见先关掉:
# 登录后读 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. 烧进去
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 位,把"已失败"当成"还在擦",所以客户端只会一直等。 别信进度条,直接读设备日志: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 先拿它跑一遍:
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、两条烧写路径的区别