The VMware segment changed, so the VM moved from 192.168.223.128 to 192.168.154.128 and every hardcoded reference was stale. A freshly-installed VM also has neither sshd nor the toolchain, which previously only surfaced half-way through a modify_imx6 iteration. - fpga-imx6-flow: new "VM prerequisite check" section -- how to detect a missing sshd (Connection refused) and reach the guest over vmrun/VMware Tools when SSH is impossible, plus the Yocto SDK install + ARM-ELF verification step. Records the real gotchas hit during install: unattended-upgrades holding the dpkg lock, EOL xenial repos, and CRLF breaking scripts pushed into the guest. - smod_atsc_dev SKILL/imx6.md: refer to CROSS_VM_HOST/USER/PASS, no literal IP. - imx6_app.py: drop the stale 192.168.223.128 default so a missing CROSS_VM_HOST fails loudly instead of dialing the wrong host. Machine-local values (IP, credentials, vmx/vmrun paths, toolchain prefix) live in ~/skills_env.md, which stays out of git. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
152 lines
9.3 KiB
Markdown
152 lines
9.3 KiB
Markdown
---
|
||
name: smod_atsc_dev
|
||
description: >
|
||
在 SMOD 硬件平台(Artix-7 xc7a200t + i.MX6 + ADRV9009)上开发、调试、固化 ATSC 激励器:
|
||
改 RTL 并用 vivado-mcp 综合实现、在 Ubuntu VM 上交叉编译 imx6 的 atsc_app 并部署、
|
||
用 ILA/串口/频谱做闭环验证。(生成 quickboot .mcs 和远程升级 FPGA 转交 fpga_update skill。)
|
||
|
||
只要用户提到 SMOD、my_exciter、RU_golden、smod_top、atsc_app、ATSC 激励器、8VSB 调制、
|
||
ADRV9009/ORx/DPD/TxAGC、tuner(Sony CXD2878)、TSoIP、quickboot、远程升级 mcs、192.168.1.143、
|
||
或在 E:\Xilinx_design\smod\SMOD_ATSC 下做任何 FPGA / imx6 改动,就必须使用这个 skill —— 即便
|
||
他们没点名 "skill",也没说 "SMOD",只是说 "把新 bit 升上去"、"改一下激励器的 RTL"、
|
||
"imx6 app 编译部署一下"、"抓个 ILA 看看"、"重新出个 mcs"。这个 skill 给出平台事实、
|
||
两条烧写路径的选择、上电时序铁律,并把闭环调试转交给 fpga-imx6-flow。
|
||
---
|
||
|
||
# SMOD ATSC 激励器开发
|
||
|
||
SMOD 是一块 **Artix-7 (xc7a200tfbg676-2) + i.MX6 + ADRV9009** 的 ATSC 激励器板。
|
||
FPGA 做 8VSB 调制 / DPD / AGC / TS 前处理,imx6 跑 `atsc_app`(配置 ADRV9009、tuner、
|
||
网页、SNMP),两者通过一个 I2C/寄存器桥通信。
|
||
|
||
这个 skill 是**总入口**:它告诉你平台的硬事实、该走哪条烧写路径、以及什么时候把活
|
||
交给别的 skill。具体细节在 `references/`,可直接运行的脚本在 `scripts/`。
|
||
|
||
## 平台事实速查
|
||
|
||
| 项 | 值 |
|
||
|---|---|
|
||
| 激励器 Vivado 工程 | `E:\Xilinx_design\smod\SMOD_ATSC\my_exciter\my_exciter.xpr`(top = `smod_top`,也是 **git 仓库根**) |
|
||
| 打底 golden 工程 | `E:\Xilinx_design\smod\SMOD_ATSC\RU_golden\RU_golden.xpr`(top = `RU_golden_top`) |
|
||
| FPGA / Flash | `xc7a200tfbg676-2` / Winbond **w25q128bv**(128 Mbit = 16 MB,SPIx1) |
|
||
| Vivado | 见 `~\skills_env.md` 的 `VIVADO_ROOT`(其下 `bin\vivado.bat`)——路径因机器而异,不要写死盘符 |
|
||
| imx6 源码 | `my_exciter\imx6\src\atsc_app`(Makefile 在该目录根) |
|
||
| imx6 设备 | `192.168.1.143`,用户 `root`,密码见 `~\skills_env.md` 的 `SMOD_SSH_PASS`(网页 + SSH;Windows 主机 `192.168.1.125` 同网段) |
|
||
| 交叉编译 VM | 主机/用户/密码见 `~\skills_env.md` 的 `CROSS_VM_HOST` / `CROSS_VM_USER` / `CROSS_VM_PASS`(IP 会变,不要写死),构建目录 `~/atsc_head_build` |
|
||
| 工具链 | `/opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi` |
|
||
| app 部署路径 | `/aw/anywave/app/imx_atsc_app`(先写 `imx_atsc_app_head`,再 `cp -a` 覆盖 active) |
|
||
| app 日志 | `/var/module_log/imx_atsc_app.log` |
|
||
| 串口 | COM 号**逐机而异,两处配置都在 `~` 下、都不入库**:两个继电器(电源 / USB-Blast)看 `~/vivado_mcp_usb.conf`(缺了就跑 vivado-mcp 的 `detect_serial_relays` 自动探测生成);imx6 控制台看 `~/fpga_imx6_flow.json` 的 `ports.imx6`。**任何地方都不要写死 COM 号。** |
|
||
| 原理图 | `my_exciter\Notes\SMOD_V1.0_SCH251010.PDF` |
|
||
| 构建产物约定 | `my_exciter\bitstream\<tag>.{bit,ltx,mcs,prm}`,一次迭代一个 tag(`smod_p1`、`smod_dpd`…) |
|
||
|
||
## ⚠️ 硬件铁律:上电时序
|
||
|
||
**给 SMOD 上电/断电之前,USB-Blast 必须先断开。** 绝不在 USB-Blast 连接状态下切换板卡电源
|
||
——这会打坏 JTAG 适配器和板卡。
|
||
|
||
```
|
||
断电(power_off) → 断开 USB-Blast(USB_Blast_off) → 上电(power_on) → 连接 USB-Blast(USB_Blast_on) → JTAG/ILA
|
||
```
|
||
|
||
用 vivado-mcp 的 `power_on` / `power_off` / `USB_Blast_on` / `USB_Blast_off` 工具执行。
|
||
上电后要**等 imx6 串口控制台打印 `sys init over` 再连 JTAG**,否则 TX 链路会挂掉。
|
||
|
||
## 两条烧写路径 —— 先选对,再动手
|
||
|
||
这是本平台最容易搞错的地方。板上 flash 是 **quickboot 双镜像**布局:golden 镜像在
|
||
`0x000000..0x3FFFFF`,update 镜像在 `0x400000..0xBFFFFF`,切换字 `0xAA995566` 在 `0x000FFC`。
|
||
|
||
| | **A. JTAG 直烧** | **B. 网络远程升级**(PR07 主线) |
|
||
|---|---|---|
|
||
| 何时用 | 板子是砖 / 首次装机 / 要换 golden | 日常迭代,板子已有 golden 且网络能通 |
|
||
| 烧什么 | `RU_golden\bitstream\golden_design_initial.mcs` | `my_exciter\bitstream\<tag>_update.mcs` |
|
||
| 怎么做 | `/fpga_flash` skill(flash 型号 `w25q128bv`) | **`/fpga_update` skill** |
|
||
| 需要 | USB-Blast + 上电时序 | 只要 `192.168.1.143` 能访问 |
|
||
| 风险 | 高(要动电源和 JTAG) | 低(写坏了 golden 会兜底) |
|
||
|
||
**调试期**还有第三种:`program_device` 直接把 `.bit` 下到 FPGA(掉电即失),配合 `.ltx` 抓 ILA。
|
||
迭代阶段用它最快,验证通过后再走 A 或 B 固化。
|
||
|
||
### B 走 `/fpga_update`
|
||
|
||
**远程升级不走网页。** 网页的 Remote Update 只认 imx6 的 `*.tar.gz` 固件包,`.mcs` 传上去会被
|
||
`check_package.sh` 删掉。FPGA 走的是 TCP **1234** 上的私有协议。生成 mcs、烧写、排错的完整流程
|
||
都在 `fpga_update` skill 里,包括两个必须知道的事实:
|
||
|
||
- **擦除卡住 ≠ 还在擦。** imx6 的 `POLL_ERASER` 不看 ERROR 位,programmer 报错和正常忙碌
|
||
返回同一个 `ERASER_ING`。读设备日志的 `rstate` 才知道真相(`0x7`=已中止,`0x0`=真在擦)。
|
||
- `-imagesize 64` 和 `SpiFlashProgrammer.vhd` 里的 `cAddrUpdateStart/End` 是一对,别改。
|
||
|
||
升级完成后**断电冷启动**,让 FPGA 从 flash 重新加载,再验证。
|
||
|
||
## 三条典型工作流
|
||
|
||
**只改 RTL** → 编辑 `my_exciter.srcs/sources_1/**` → vivado-mcp `run_synthesis` +
|
||
`run_implementation` + `generate_bitstream` → `program_device` 下 bit → 抓 ILA 验证 →
|
||
满意后走 `/fpga_update` 固化。
|
||
|
||
**只改 imx6** → 编辑 `imx6/src/atsc_app/**` → 提交到 git(脚本默认打包 `HEAD`)→
|
||
|
||
```bash
|
||
python .../scripts/imx6_app.py build-deploy --tag mychange
|
||
```
|
||
|
||
→ 冷启动让 `rc.local` 拉起新 app → `imx6_app.py log` 看日志。
|
||
|
||
**FPGA + imx6 联调** → 交给 **`/fpga-imx6-flow`**。那个 skill 驱动一张 LangGraph 图,
|
||
把上电/JTAG/烧写/重启做成确定性节点,把「分析 → 判断是否达标 → 提方案 → 改 FPGA / 改 imx6」
|
||
这四步作为中断交回当前会话执行,一轮一轮迭代。PR07 明确要求走这条路做联合调试。
|
||
|
||
## 什么时候调别的 skill
|
||
|
||
| 场景 | 用 |
|
||
|---|---|
|
||
| 上电 / JTAG / 综合实现 / 抓 ILA / 下 bit | **vivado-mcp** 工具(`power_on`、`program_device`、`run_tcl`…) |
|
||
| 闭环设计-调试迭代(本 skill 的主推荐) | **`/fpga-imx6-flow`** |
|
||
| JTAG 烧 flash(golden 或砖机恢复) | **`/fpga_flash`**(flash 型号选 `w25q128bv`) |
|
||
| 单模块 RTL 仿真 / 出 testbench | **`/vivado-sim`** |
|
||
| ILA 抓出来的 IQ CSV 做频谱 / OBW / 带肩 | **`/fft-analyse`** |
|
||
| 网页操作(登录、升级、看频谱页) | **claude-in-chrome** |
|
||
| 实测频谱(N9320B 频谱仪) | `mcp__mcp_n9320b__*` 工具 |
|
||
|
||
## scripts/
|
||
|
||
| 脚本 | 用途 |
|
||
|---|---|
|
||
| `imx6_app.py` | `build` / `deploy` / `build-deploy` / `log` —— VM 交叉编译 + 推到 imx6 + 读日志 |
|
||
|
||
出 `.mcs` 和远程升级的脚本在 `/fpga_update` skill 里(`gen_update_mcs.py`、`fpga_ru.py`)。
|
||
|
||
两个脚本都 `--help` 可查。`imx6_app.py deploy` 会自动装 paramiko 2.12 到缓存目录并 re-exec
|
||
(imx6 的 dropbear 太老,paramiko 5 连不上,见下)。
|
||
|
||
## references/
|
||
|
||
按需读,别一次全读进来:
|
||
|
||
- `references/fpga.md` —— RTL 目录结构、XDC、vivado-mcp 用法、ILA/ltx 约定、已知时序告警的性质
|
||
- `references/imx6.md` —— app 源码结构、交叉编译细节、部署/日志/寄存器访问、网页
|
||
- `references/upgrade.md` —— quickboot 双镜像布局、mcs 生成的确切参数、golden 恢复
|
||
- `references/history.md` —— 历史 PR/Task 笔记索引(tuner、TSoIP、ORx、DPD、AGC 各自踩过什么坑)
|
||
|
||
## 常见坑
|
||
|
||
| 症状 | 原因 / 处理 |
|
||
|---|---|
|
||
| 远程升级后重新上电 FPGA 不跑 | 传错了文件 —— 必须是 `_update.mcs`(起始 `0x800000`),不是 `write_cfgmem` 出的基础 mcs |
|
||
| 远程升级卡在 "erasing" 不动 | programmer 已报错退出(`rstate=0x7`),imx6 的轮询不看 ERROR 位。见 `/fpga_update` |
|
||
| imx6 SSH 报 `unknown cipher` / `no acceptable host key` | dropbear 太老。用 paramiko **2.12**(`imx6_app.py` 已处理);命令行 ssh 加 `-o HostKeyAlgorithms=+ssh-rsa` |
|
||
| imx6 `open_sftp()` → `EOF during negotiation` | 设备没有 SFTP 子系统。用 `cat > file` 走 exec channel 传文件 |
|
||
| VM SSH `kex_exchange_identification: Connection closed` | VM 的 sshd 挂了,请用户 `sudo systemctl restart sshd` |
|
||
| 上电后 TX 链路死掉 | 上电后没等 `sys init over` 就连了 JTAG |
|
||
| `power_off` 卡在循环里 | 先 `USB_Blast_off` 再 `power_off`,顺序反了 |
|
||
| WNS ≈ -9 ~ -13 ns | JESD204 `init_seq_data` 的既有 false path,与功能无关,不要为它改设计 |
|
||
| `i2cget` 读 FPGA 寄存器时好时坏 | 带调试 ILA 的 bit 时序更差;且会和 app 抢总线。以生产 bit 为准,或从 app 日志读 |
|
||
|
||
## 写笔记
|
||
|
||
这个工程的约定是 `my_exciter\Notes\PRxx.md` 记**需求**,`Taskxx.md` 记**方案与实现总结**
|
||
(含验证数据和踩过的坑)。做完一轮有结论的工作,补一份 `Taskxx.md` —— 后来的人(和后来的你)
|
||
靠它避免重复踩坑。`references/history.md` 是已有笔记的索引。
|