跳到主要内容
320 Msps 很唬人,但我盯的是那两行 restore

320 Msps 很唬人,但我盯的是那两行 restore

阿舟
阿舟

· 阅读约 8 分钟

打开 w1700k-sdr,我没看首页那张瀑布图,直接滚到 install 那节。

画外音:这毛病是以前刷坏过东西落下的。看任何一个要动固件的项目,先找退路,再看功能。

退路在。init/install 干的第一件事,是先把整片 NAND 备份到主机,init/restore 能写回备份、把原厂固件恢复回去。就这两行,让我愿意把后面的数字当回事。

先把账算一遍,性能那块才看得懂。

320 Msps,14 位复数 IQ:

320e6 sample/s × (14 + 14) bit = 8.96 Gbit/s
10GbE 线速 10 Gbit/s,扣掉前导码/帧间隙/IP/UDP 头 ≈ 9.4 Gbit/s

余量五个点。这不是"能跑",是贴着墙跑。

所以项目里有这么一条:320 Msps 下,大约一半的数据切片会先按每对样本 28 位在射频芯片端打包一遍,才往 10GbE 上发。我盯着这条看了一会儿才反应过来,为什么它必须在芯片端做——到主机再压已经晚了,瓶颈就是那条链路。你不能先花 8.96 Gbit/s 把数据运过来,再在主机上说"我压一下"。

然后是那个我觉得最值得玩味的数字:SoC 里那块环形缓冲区,1 GiB。

1 GiB 听着很大。算一下:

复数 int16 = 4 B/sample
320 Msps × 4 B = 1.28 GB/s
1 GiB ÷ 1.28 GB/s ≈ 0.84 s

连一秒都存不下。

这块缓冲区的职责从来不是"缓存数据等你来取",它就是给调度抖动留的减震器——网卡那边卡一下、内核那边排个队,这点余量够顶住。超过一秒的停顿,数据就没了,而且没有重传:8 KiB 一个切片,UDP,零拷贝发出去,丢了就是丢了。

我觉得这个取舍是对的。要可靠传输就得加确认、加重传、加重排序,实时流背不起这个。宁可丢,不可堵。

主机端 w1700k-spectrum 那边,262,144 点 FFT,目标 100 帧每秒。这个数跟 320 Msps 摆一起,你得愣一下:

262144 × 100 ≈ 26.2 Msample/s
320 ÷ 26.2 ≈ 12

差了十二倍。你在浏览器里看到的那张实时瀑布图,跟天线那头实际收到的信号之间,隔着一次十几倍的抽取。这东西不是示波器,它是一台扫得很快的频谱仪,而且扫的还不是全带宽。

我不是说这是缺点——100 fps 已经是眼睛跟得上的上限,再快人也看不清。只是别拿它当"320 MHz 实时全带宽观测"用,那是两回事。

顺带一句,w1700k-stream 里有个可选开关,校正抽取滤波器的滚降。这个细节见功力——抽取滤波器的通带边缘不是平的,你在频谱上看到的那个斜面,有一部分是滤波器给你的,不是信号本身。愿意为这个挂一个开关的人,是真拿它当过仪器,不是做个 demo 就跑。

调谐那块我得多说两句,这是这台机器手感所在。

它不走传统信道划分,本地振荡器能设到频段合成器锁得住的任意赫兹值。2.4 GHz 频段步进 2.98 Hz,其他频段 11.9 到 14.3 Hz,流式传输中间重调谐大概 1 ms。频段切换更干脆,2.4 GHz(MT7976)、5 GHz 和 6 GHz(两个 MT7977),持续数据流里切频段就是写寄存器,不断流。

2.98 Hz。这个数字比 320 Msps 更让我觉得"哦,这玩意儿真能当仪器用"。你要找一个很窄的信号,能 3 Hz 一步挪过去,和只能按 20 MHz 信道跳,完全是两码事。

还有一点:采样率、LO 频率、模拟滤波器带宽,这三样各调各的,不联动。40、80、160、320 Msps 随便选,滤波器 20–320 MHz 自己设。灵活性是有了,代价是你得自己想清楚组合——采样率低、滤波器开得宽,混叠就来了,这个没人替你兜底。

还有个 640/2 模式:取 640 Msps 的每隔一个样本,输出 320 Msps,平坦覆盖大约 ±155 MHz。代价是 160–320 MHz 以外的信号会折叠进来。

这个 trade-off 得说清楚:宽了,但脏了。你要是确定带外没强信号,这模式很香;你要是在一个什么都有环境里,折叠进来的东西会伪装成带内信号,而且你还看不出来——它在频谱上长得就是正常的。这种坑最难查,因为你根本不会去怀疑一幅看起来正常的频谱。

想动手的人先看清楚门槛:W1700K(HW 1.x)或者 W1700K2(HW 2.1),3.3 V USB 串口,一根网线接 lan3,主机上一块 10GbE 网卡接 wan 口,作者说 X710 配铜缆 SFP+ 模块能用。

串口 3.3V → 调试口
lan3  ← 网线 → 主机(管理)
wan   ← 10GbE → 主机(数据)

管理走千兆,数据走万兆,两条线。我第一次看以为一条线能全干完,不行——10GbE 那个口的带宽全得让给 IQ 流,一点管理流量都塞不进去。文档里画了图,但我猜还是有人只插一根线,然后来问为什么连不上。

许可结构挺实在:主体 MIT,但 Linux 驱动和内核补丁、U-Boot 补丁、驱动头文件、以及从 MediaTek mt76 派生的那些文件,各自是 GPL 或者 BSD。这种混杂不是懒,是没办法,你不可能把内核补丁按 MIT 发出去。看到这种结构我反而放心,说明作者清楚自己在动谁的地盘。

插一段不太相干的。这仓库 9 次提交,821 个 star,83 个 fork。

9 次。

我不觉得这有什么问题,历史可能在别的分支,也可能被 squash 过。但这个比例本身说明一件事:大家 star 的是那个念头,"路由器当 SDR"这念头太性感了。真会去执行 init/install 的,是 fork 里那一小撮。这不是批评谁,我收藏夹里也一堆只 star 不动的仓库 😅。

扯远了,回正题。

真正让我坐直的是固件那一段。

这项目自带 MT7996 固件,但里面不包含 MediaTek 的固件代码。ROM 补丁、WM、WA 全是自己写的,设备能从冷启动自己把射频初始化起来。

这话说起来轻。做起来是什么量级,碰过这层的同行心里有数。

其中有一句,我建议所有想动这块的人抄下来贴墙上:这个项目的 ROM 补丁不写 eFuse。而 MediaTek 自己从 2025 年起的 ROM 补丁,首次运行会永久写入一个 eFuse 门控位。

eFuse 是什么不用我解释。一次性的,写下去就回不来。也就是说,同样一块芯片,走官方路径跑一次,和你自己写补丁跑一次,物理上就不是同一块芯片了。这个差别通常藏在文档第七页的脚注里,但它决定了你这块板子还能不能拿去做别的事。

固件还明确只收不发:没跑 MediaTek 的发射校准,MAC 的发射路径保持关着。作者仍然加了一句提醒,说别在没有衰减器的情况下把天线口直接怼到敏感仪器上——我看到这句笑了一下,典型的"我知道你不会听,但我还是要说"。发射校准没做,功率标定大概率是飘的,你以为 -20 dBm,实际差个十几 dB 很正常。这种时候前端烧了,只能怪自己。

安装流程里还有一处,我觉得比上面所有性能数字都值得学:NAND 型号。

多数机器上是 W25N04KV。部分 W1700K2 用的是 W25N04LV,ID 是 ef 8b 23。后者代码里支持了,但没在实机上跑过——所以安装脚本走到这儿会停下来,要你给一个特定参数,或者贴一份原始转储,才继续。

NAND id ef 8b 23
→ 代码支持,无实机验证
→ 安装暂停,等显式参数或 raw dump

这个"停"字很贵。写代码的人都知道,让程序在不确定的时候停下来,等于给自己找麻烦——用户会来问,会骂,会说"你就不能自动判断吗"。但 NAND 型号不对、时序不对,写进去就是砖。宁可让你骂一句,不能让你砖一块。

写到这里我得推翻一下开头那个念头。我本来想把这文章写成"开源硬件就该这么做",写到这儿觉得这话太大,也太便宜。它不是什么范式,就是一个具体的人,把每个不确定的地方都当成"可能砖"来处理了。真要概括,就一句:他把失败模式想在了成功路径前面。

所以我从这项目里抄什么?不是 320 Msps,也不是那块 1 GiB 的环。

我抄它的顺序:先写 restore,再写 install;先让程序在不确定的地方停下来,再谈自动化;先把 eFuse 那条线划清楚,再谈功能。

本期缴税:以前我以为刷机翻车是手气问题。后来发现不是,是没写退路就往前冲的问题。

阿舟
阿舟

写代码写到一半开始怀疑人生,靠 AI 工具续命,顺手把踩过的坑都记下来。

查看主页 →