openwifi IQ 采样捕获实战指南:触发条件、AGC/RSSI 状态解析、频率偏移估计与 SNR 分析 通信网络硬件开发嵌入式【免费下载链接】openwifiopen-source IEEE 802.11 WiFi baseband FPGA (chip) design: driver, software项目地址https://gitcode.com/gh_mirrors/op/openwifi点击查看免费下载openwifi 是基于 FPGA 的开源 IEEE 802.11 WiFi 基带芯片级设计其IQ 采样捕获IQ sample capture功能通过 side channel 基础设施把 SDR 板卡射频前端收到的原始 I/Q 样本、AD9361 AGC 增益/锁定状态、未校准 RSSI、TSF 时间戳以及 FPGA 频率偏移估计等一并传送到主机供实时显示与离线分析。本文以 IQ 捕获应用笔记 为主体结合 side_ch 驱动、side_ch_ctl 用户态工具 与 Python/Matlab 配套脚本源码完整讲解从快速上手指引、触发条件配置、数据格式解析到频率偏移 FPGA 与浮点算法对照、基于 IQ 的 SNR 计算与 WiFi 报文映射的实战方案读完后你可以独立部署、按需裁剪并深度分析 openwifi 的空中接口波形。Quick start一条龙跑通 IQ 捕获假设你已经按 buildroot 镜像构建说明 烧写好 SDR 板卡系统镜像并完成openwifi目录的部署可参考 populate_driver_userspace.sh 与 transfer_driver_userspace_to_board.sh。以下是监控模式下最短的端到端流程给 SDR 板卡上电。用网线连接主机与板卡主机配置静态 IP192.168.10.1然后 SSH 登入板卡ssh root192.168.10.122 (password: openwifi) cd openwifi ./wgd.sh (等待脚本执行完成) ./monitor_ch.sh sdr0 11 (在信道 11 上进入监控模式可把 11 换成其它繁忙信道) insmod side_ch.ko iq_len_init8187 (对于小规模 FPGA7Z020iq_len_init 应小于 4096例如 4095而不是 8187) ./side_ch_ctl wh3h01 (开启 IQ 捕获并配置 IQ 数据源) ./side_ch_ctl wh11d4094 (仅在使用 zed、adrv9364z7020、zc702 板卡时需要执行) ./side_ch_ctl g板卡终端会持续输出类似loop 64 side info count 61 loop 128 side info count 99 ...当第二个数字side info count 61、99、…持续增长说明触发条件被不断满足、IQ 样本正顺畅地传往主机。在主机上另开一个终端执行cd openwifi/user_space/side_ch_ctl_src python3 iq_capture.py (对于 zed、adrv9364z7020、zc702 板卡需要传入与 iq_len_init 相等的参数例如 4095)运行前可能需要先安装依赖sudo apt install python3-numpy python3-matplotlib python3-tk。此时会弹出 3 幅实时图IQ 样本、AGC 增益与锁定状态、未校准 RSSI同时脚本在终端打印时间戳timestamp。运行期间所有信息还会同步写入主机端的文件iq.txt。配套的 Matlab 脚本 test_iq_file_display.m 可对 IQ 信息做离线分析对于 zed、adrv9364z7020、zc702 板卡记得把脚本中的iq_len改为 4095。理解 IQ 捕获功能side channel 架构与 64bit 数据格式IQ 信息通过 openwifi 的side channel基础设施提取。下图说明了相关模块含对应源码文件名以及信息从 SDR 板卡到主机的完整通路这条数据链路可以在源码中逐级印证FPGA 侧寄存器硬件寄存器映射定义在 side_ch.h从SIDE_CH_REG_MULTI_RST_ADDR0、SIDE_CH_REG_CONFIG_ADDR1、SIDE_CH_REG_IQ_CAPTURE_ADDR3、SIDE_CH_REG_FC_TARGET_ADDR5、SIDE_CH_REG_ADDR1/ADDR2_TARGET_ADDR6/7、SIDE_CH_REG_IQ_TRIGGER_ADDR8、SIDE_CH_REG_RSSI_TH_ADDR9、SIDE_CH_REG_GAIN_TH_ADDR10、SIDE_CH_REG_PRE_TRIGGER_LEN_ADDR11、SIDE_CH_REG_IQ_LEN_ADDR12到SIDE_CH_REG_M_AXIS_DATA_COUNT_ADDR20。这正是side_ch_ctl各条whX…命令所写的寄存器编号来源。DMA 搬运side_ch.c 的get_side_info()在收到 Netlink “取数据”请求后通过tx_dma_s2mm通道把 FPGA 侧 side_ch 模块的 DMA 符号一次性读入内核缓冲区再经 Netlink 单播回传给用户态。用户态转发side_ch_ctl.c 的主循环以interval_ms为周期向内核发ACTION_SIDE_INFO_GET并把收到的数据通过 UDP 发往192.168.10.1:4000默认值可用-s指定对端 IP。主机接收iq_capture.py 在192.168.10.1:4000上监听 UDP按1 iq_len个 DMA 符号重组每次传输并调用parse_iq()解析出各字段。IQ 信息格式如下图所示每次捕获以时间戳 若干 DMA 符号构成其中每个 DMA 符号固定 64bit对于每个元素实际位宽为 64bittimestamp触发捕获时刻的 64bit TSF 定时器值。IQ 样本前两个 16bit 存放当前使用天线对应的 I/Q 样本第 3 个 16bit 为 AD9361 AGC 增益bit7 —— lock/unlock 锁定状态bit6~0 —— 增益值第 4 个 16bit 为 RSSI单位半 dB未校准。关于原始 RSSI 值最终如何被校准并上报给 Linux mac80211可查阅 FPGA 侧xpu.v与 sdr.c 的实现。Python 端的解析逻辑与上述格式一一对应见 iq_capture.pytimestamp由 4 个 16bit 拼接为 64bitiq_capture iq[:,4::4] iq[:,5::4]*1j取每符号的第 4、5 个 16bit 组成复样本agc_gain取第 6 个 16bit 的低 8 位0xFFrssi_half_db取第 7 个 16bit 的低 11 位0x7FF。除此之外第 6 个 16bit 的最高位0x8000是ch_idle信道空闲标志第 7 个 16bit 的高位还携带demod0x8000、tx_rf0x4000、fcs_ok0x2000等运行状态位这些标志在实时图中被叠加显示方便你判断某段 IQ 波形对应的是接收解调、发射还是校验成功/失败。Matlab 侧 test_iq_file_display.m 读取 iq.txt 后同样按1 iq_len个 DMA 符号切分并解出iq_capture、timestamp、agc_gain、rssi_half_db、ch_idle_final、demod_is_ongoing、tx_rf_is_ongoing等矩阵供离线深入分析。配置 IQ 捕获与捕获间隔快速上手章节的默认行为是每当 WiFi 接收机对报文做 FCS 校验无论通过与否时捕获一段历史 IQ。要使用不同的触发条件与捕获长度必须在执行 side_ch_ctl g 之前下发配置命令。所有配置命令都是向side_ch_ctl传入不同的参数串实现的核心可配置参数见下图iq_len表示每次触发条件满足时捕获的 IQ 样本个数捕获从触发时刻之前的pre_trigger_len个 IQ 样本处开始。iq_len 仅在插入 side_ch.ko 时设置一次详见后文 配置 iq_len 一节本节介绍 pre_trigger_len 与触发条件的设置。设置 pre_trigger_len./side_ch_ctl wh11dY参数Y指定 pre_trigger_len。有效范围 0 ~ 8190受 FPGA FIFO 容量限制对于小规模 FPGAzed_fmcs2、adrv9364z7020、zc702有效范围为 0 ~4094。该值写入硬件寄存器 11SIDE_CH_REG_PRE_TRIGGER_LEN_ADDR。从驱动初始化代码可见默认值为 8190小 FPGA 需手动下调这正是 Quick start 中wh11d4094的用途side_ch.c。设置触发条件./side_ch_ctl wh8dY参数Y指定触发条件有效范围 0 ~ 31含义如下表。该值写入硬件寄存器 8SIDE_CH_REG_IQ_TRIGGER_ADDRvalue含义0接收机给出 FCS 校验结果无论通过/失败或自由运行1接收机给出 FCS 校验结果通过2接收机给出 FCS 校验结果失败3tx_intf_iq0 变为非零第 1 个 I/Q 输出4接收机给出 SIGNAL 字段校验结果通过5接收机给出 SIGNAL 字段校验结果失败6接收机给出 SIGNAL 字段校验结果无论通过/失败HT 报文7接收机给出 SIGNAL 字段校验结果无论通过/失败非 HT 报文8接收机检测到长前导long preamble9接收机检测到短前导short preamble10RSSI半 dB未校准超过阈值11RSSI半 dB未校准低于阈值12AD9361 AGC 从锁定变为解锁13AD9361 AGC 从解锁变为锁定14AD9361 AGC 增益超过阈值15AD9361 AGC 增益低于阈值16当 xpu 的 tx_control_state 命中指定值由 side_ch_ctl wh5 设置时 tx_control_state_hit17openofdm tx 核给出的 phy_tx_done 信号18xpu 核 tx_bb_is_ongoing 上升沿19xpu 核 tx_bb_is_ongoing 下降沿20xpu 核 tx_rf_is_ongoing 上升沿21xpu 核 tx_rf_is_ongoing 下降沿22phy_tx_started 且该发送报文需要 ACK23phy_tx_done 且该发送报文需要 ACK24tx_control_state 与 phy_type0 Legacy1 HT2 HE同时命中由 side_ch_ctl wh5 设置25addr1 和/或 addr2 匹配addr1/2 匹配配置参见 CSI 应用笔记26tx_rf_is_ongoing 上升沿且该发送报文需要 ACK27tx_rf_is_ongoing 下降沿且该发送报文需要 ACK28tx_bb_is_ongoing 且来自另一天线的 I/Q 幅度高于 rssi_or_iq_th29tx_rf_is_ongoing 且来自另一天线的 I/Q 幅度高于 rssi_or_iq_th30开始发送同时来自另一天线的 I/Q 幅度高于 rssi_or_iq_th31开始发送且需要 ACK同时来自另一天线的 I/Q 幅度高于 rssi_or_iq_th硬件寄存器 5 的多用途字段硬件寄存器 5SIDE_CH_REG_FC_TARGET_ADDR是复用字段bit0 用于自由运行模式bit7~4 为 tx_control_state 目标值bit9~8 为 phy_type。例如把目标 tx_control_state 设为 SEND_BLK_ACK3且 phy_type 设为 HE2./side_ch_ctl wh5h230若希望自由运行始终触发请同时使用下面两条命令./side_ch_ctl wh8d0 ./side_ch_ctl wh5d1设置 RSSI 阈值./side_ch_ctl wh9dY参数Y指定 RSSI 阈值有效范围 0 ~ 2047。该值写入硬件寄存器 9SIDE_CH_REG_RSSI_TH_ADDR对应触发条件 10/11 的判定门限。设置 AGC 增益阈值./side_ch_ctl wh10dY参数Y指定 AGC 增益阈值有效范围 0 ~ 127。该值写入硬件寄存器 10SIDE_CH_REG_GAIN_TH_ADDR对应触发条件 14/15 的判定门限。捕获间隔命令 side_ch_ctl g 会每 100ms 执行一次 IQ 捕获直到按下 ctrlC。要改变捕获间隔side_ch_ctl gN间隔变为 N*1ms。从 side_ch_ctl.c 源码可见g后无参数时默认取 100ms非法输入也回退到 100ms且每个周期结束后usleep(interval_ms*1000)。side_ch_ctl 参数语法速查side_ch_ctl的参数串解析规则定义在 side_ch_ctl.c格式为wh寄存器号d十进制值写硬件寄存器wwritehhardwareddecimal例如wh8d25写寄存器 8 为 25wh寄存器号h十六进制值写硬件寄存器十六进制例如wh3h01、wh5h230ws寄存器号h值写软件寄存器ssoftwarerh寄存器号/rs寄存器号读硬件/软件寄存器g/g毫秒获取 side infoCSI 或 IQ 数据可指定周期。寄存器号范围 0~31寄存器号与值的进制标志d/h为必填。默认发送目标是192.168.10.1可用-s指定其它主机 IP。配置 iq_leniq_len每次捕获的 IQ 样本数可配置当你想在一次特定分析周期内触发更多次捕获、从而减少每次捕获的样本数时很有用。有效值 1 ~8187对于小规模 FPGAzed_fmcs2、adrv9364z7020、zc702有效范围 0 ~4095。它与 pre_trigger_len 相互独立也可以小于 pre_trigger_len。请务必让 side_ch.ko、iq_capture.py、test_iq_file_display.m 三处的iq_len值保持一致。插入内核模块时insmod side_ch.ko iq_len_init3000这里 3000 只是示例。注意必须显式指定 iq_len_init 才能开启 IQ 捕获模式此时默认的 CSI 模式会被关闭。不带任何参数插入 side_ch.ko 则运行默认 CSI 模式。驱动源码印证了这一点side_ch.c 中iq_len_init默认值为 0在 dev_probe() 中当iq_len_init0时才会写SIDE_CH_REG_IQ_CAPTURE_write(1)开启捕获、把 pre_trigger_len 初始化为 8190、把触发条件初始化为 0FCS 通过/失败都触发并做了 8187 上限截断而get_side_info()中每传输的 DMA 符号数也据此从HEADER_LENCSI_LENnum_eq*EQUALIZER_LENCSI 模式切换到1iq_lenIQ 模式。启动 Python 脚本时python3 iq_capture.py 3000iq_capture.py 同样会对 8187 做上限截断。8187 这个上限的来源是 UDP 单包最大 65507 字节(65507/8)-1 8187即 1 个时间戳符号 8187 个 IQ 符号每符号 8 字节。使用 Matlab 脚本时请把 test_iq_file_display.m 中的iq_len变量改为 3000。频率偏移估计FPGA 硬件 vs Python 浮点算法脚本iq_capture_freq_offset.py可以同时显示 FPGA 估计的频率偏移以及基于 IQ 用 Python 浮点算法算出的实际频率偏移。若两者差异很大可尝试用 Python 算法的结果通过 user_space/receiver_phase_offset_override.sh 覆盖 FPGA 的频率估计模块。千万别忘了如果测试 80211ax必须修改iq_capture_freq_offset.py中的LUT_SIZE默认512.0对应 11a/g/n 主链路80211ax 应改为4096.0。该常数由 FPGA 侧ATAN_LUT_SCALE_SHIFTcommon_defs.v决定与主链路和 80211ax 的处理不同见 iq_capture_freq_offset.py。使用iq_capture_freq_offset.py的示例命令序列也写在该脚本头部注释中板卡端插入 iq 长度为 1500 的模块并设置 pre_trigger_len1497、对端 MAC、本机 MAC、使能 MAC 地址匹配、触发条件 25addr1 与 addr2 同时匹配然后开始捕获insmod side_ch.ko iq_len_init1500 ./side_ch_ctl wh11d1497 ./side_ch_ctl wh7h635c982f ./side_ch_ctl wh6h44332236 ./side_ch_ctl wh1h6001 ./side_ch_ctl wh8d25 ./side_ch_ctl g0其中wh7h635c982f/wh6h44332236分别写寄存器 7/6SIDE_CH_REG_ADDR2/ADDR1_TARGET_ADDR的 MAC 目标地址wh1h6001写寄存器 1SIDE_CH_REG_CONFIG_ADDR使能地址匹配等条件。在完全干净/非标准信道上也可以改用长前导检测作为触发条件insmod side_ch.ko iq_len_init1500 ./side_ch_ctl wh11d1497 ./side_ch_ctl wh8d8 ./side_ch_ctl g0主机端python3 iq_capture_freq_offset.py 1500脚本会在 shell 中打印相位偏移值FPGA vs Python并实时绘制曲线。脚本的相位偏移换算逻辑位于phase_offset_to_freq_offset()freq_offset (20.0e6*phase_offset/LUT_SIZE)/(2*π)即把相位偏移按 LUT 规模折算到 20MHz 采样率下的频率偏移。parse_iq()中把 FPGA 报告的高 2 位 低 7 位相位偏移拼接为有符号 16bit 值Python 侧 LTF 估计则通过 64 样本延迟相关的滑动窗峰值定位前导位置后取相位角两者画在同一坐标中对照iq_capture_freq_offset.py。覆盖命令 receiver_phase_offset_override.sh 的用法不带参数运行把 rx 寄存器 19 的 bit31 置 0即取消相位偏移覆盖带参数运行例如./receiver_phase_offset_override.sh -8把相位偏移值低 16bit与 bit31 使能位拼成 32bit 写入./sdrctl dev sdr0 set reg rx 19。基于 IQ 计算 SNRIQ 捕获并用test_iq_file_display.m生成 .mat 文件后可用show_iq_snr.m在 Matlab 中基于 .mat 文件计算 SNR信号噪声比。建议在非常干净的环境中例如非标准信道下的线缆测试用单一信号/报文源做这种 SNR 检查否则在链路状态波动下得到的 SNR 统计意义不大。第 1 步在 Matlab 中以 .mat 文件为唯一参数运行show_iq_snr(mat_file_name)它会显示相对 RSSI 变化dB的曲线你需要确定一个中间值——大致是高 RSSI信号与低 RSSI噪声的中点。第 2 步在 Matlab 中以 .mat 文件和中间值为参数运行show_iq_snr(mat_file_name, middle_value)它会在 Matlab 命令行打印 SNR并画出标出信号区与噪声区的图。从 show_iq_snr.m 源码可以看到具体算法把 IQ 模平方后做 80 点滑动平均换算 dB与阈值比较得到信号/噪声掩码再用 160 点卷积做形态学平滑来划分信号区与噪声区最终snr 10*log10((signal_plus_noise_power - noise_power) / noise_power)即先扣掉噪声功率再求比值。编译 side channel 驱动与用户态程序side_ch.ko 内核模块$OPENWIFI_DIR/driver/side_ch/make_driver.sh $OPENWIFI_DIR $XILINX_DIR ARCH_BIT (Zynq 7000 的 ARCH_BIT 应为 32Zynq MPSoC 的 ARCH_BIT 应为 64)脚本内容见 make_driver.sh。side_ch_ctl 用户态工具请在板卡上就地编译 side_ch_ctl.cgcc -o side_ch_ctl side_ch_ctl.cside_ch_ctl 通过 NetlinkNETLINK_USERSOCK与内核驱动通信编译依赖内核头文件提供的 netlink 相关定义因此在目标板卡环境编译最稳妥。在非 monitor 模式下运行 IQ 捕获openwifi 的 IQ 捕获功能不只适用于 monitor 模式也可用于 AP-Client 或 ad-hoc 等其它模式。当这些模式的通信功能完全建立起来之后即可照前述章节从 insmod side_ch.ko 和 ./side_ch_ctl g 开始在板卡上启动 IQ 捕获把 IQ 信息提取到主机。也就是说IQ 捕获与上层网络工作模式相互解耦只要 side channel 链路和触发条件配置得当即可运行。将 IQ 信息映射到 WiFi 报文如果想建立 IQ 信息与具体 WiFi 报文的对应关系需要在捕获 IQ 的同时抓取 WiFi 报文tcpdump/wireshark 等再通过时间戳把两者关联起来。请注意IQ 信息里的时间戳是捕获被触发的时刻可能与抓包程序里报告的时间戳不同但由于它们共用同一时间基准TSF 定时器通过分析 WiFi 报文与 IQ 样本序列可以方便地建立对应关系。更细粒度的按次捕获 IQ 信息提取请研读 test_iq_file_display.m、iq_capture.py 与 iq_capture_2ant.py 等脚本按你的需求自行裁剪。小结与进阶阅读本文围绕 openwifi 的 IQ 采样捕获功能给出了从监控模式快速上手、触发条件与阈值配置、64bit 数据格式解析、频率偏移 FPGA/Python 对照、SNR 计算到 WiFi 报文映射的完整闭环并逐一对应到 side_ch.h、side_ch.c、side_ch_ctl.c 及 Python/Matlab 脚本源码。IQ 捕获的触发条件0~31覆盖了接收 FCS/SIGNAL 校验、前导检测、RSSI/AGC 事件、发射过程事件、地址匹配与双天线幅度门限等几乎所有可观测事件是调试基带时序、评估链路质量与做信号分析的一把通用钥匙。若需要进一步延伸可参考仓库中与 IQ/CSI 相关的姊妹文档CSI 应用笔记、CSI fuzzer 笔记、IQ 双天线捕获笔记、IQ ACK 时序笔记、雷达自 CSI 笔记 以及 802.11n 笔记它们与本文共享同一套 side channel 与捕获/分析基础设施。赞分享通信网络硬件开发嵌入式【免费下载链接】openwifiopen-source IEEE 802.11 WiFi baseband FPGA (chip) design: driver, software项目地址https://gitcode.com/gh_mirrors/op/openwifi点击查看免费下载相关推荐OpenWifi IQ捕获技术详解实时AGC、RSSI与双天线系统实现终极指南OpenWifi IQ捕获技术详解实时AGC、RSSI与双天线系统实现终极指南 在无线通信领域OpenWifi IQ捕获技术是一项革命性的创新它通过FPG通信网络硬件开发嵌入式Open-SDR/openwifi项目中的IQ采样捕获功能详解Open SDR/openwifi项目中的IQ采样捕获功能详解 概述 在无线通信系统中IQIn phase/Quadrature采样数据是理解信号特性的关通信网络硬件开发嵌入式Prisma API 查询指南从对象查询到 Connection 分页与过滤Queries 全解析Prisma API 查询指南从对象查询到 Connection 分页与过滤Queries 全解析 本篇技术指南完整讲解 Prisma1.x即本仓库通信网络硬件开发嵌入式上一篇FastGPT 权限系统核心概念位字段权限、角色映射与协作者模型全解析下一篇Deep Agents 多文件上下文检索评测深入解析 context-retrieval-evals 数据集的设计、生成与校准创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考