openwifi开源Wi-Fi基带FPGA工程:ZC706/ZCU102等多平台即用位流+mac80211驱动支持

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:提供开箱即用的IEEE 802.11a/g/n Wi-Fi基带FPGA实现,完整对接Linux内核mac80211协议栈,适用于软件定义无线电(SDR)开发与教学实验。Verilog代码覆盖OFDM物理层收发、MAC接口桥接、时钟域同步及射频子板控制逻辑,已验证适配Xilinx ZC706、ZCU102、ZedBoard和AntSDR等主流硬件平台。资源包内置各平台预编译.bit位流文件、ILA调试.ltx配置、Vivado工程一键生成脚本(create_vivado_proj.sh)、IP核打包工具(package_ip.tcl)、HDF/SDK协同更新脚本(sdk_update.sh),以及针对ADI FMCOMMS2/3/4、ADRV9361/9364等射频子板的专用驱动适配层。所有模块遵循openwifi项目结构规范,可直接配合上游Linux驱动和用户空间工具(如iw、hostapd)运行。使用前需设置BOARD_NAME环境变量指定目标板卡,详细引脚约束、时序约束、软硬件联调步骤、调试技巧均在对应板级目录下的README.md中说明。许可证为AGPLv3,部分第三方IP需按其单独条款确认授权。

1. 项目概述:这不是“又一个Wi-Fi软核”,而是一套真正能跑通802.11协议栈的FPGA基带系统

你有没有试过在FPGA上实现一个Wi-Fi收发器?不是那种只发几个OFDM符号、用MATLAB画个星座图就收工的演示工程,而是真刀真枪地让Linux内核认出它是一块无线网卡,能ifconfig wlan0 up、能iw dev wlan0 scan、能连上家用路由器、甚至能跑iperf3测吞吐——没错,openwifi就是干这个的。它不是教学玩具,也不是实验室里的半成品,而是一套经过多平台实测、可直接用于SDR原型开发、协议研究、安全分析和嵌入式Wi-Fi网关构建的完整基带方案。关键词里那个mac80211,是它的灵魂所在:这意味着它不自己实现MAC层逻辑,而是把物理层(PHY)的复杂性全部卸载到FPGA上,再通过标准的DMA+寄存器接口,把干净的数据帧交给Linux内核的mac80211子系统去调度、加密、重传、管理关联状态——你拿到的,是一块被内核完全信任的“真实”Wi-Fi设备,而不是一个需要你写一整套用户态协议栈的裸硬件。

我第一次在ZC706上跑通hostapd建热点时,ping通手机的那一刻,比当年第一次点亮LED还激动。为什么?因为ZC706这类7系列FPGA资源有限,传统Wi-Fi基带动辄吃掉上万LUT,而openwifi通过精巧的状态机拆分、流水线级数优化和时钟域交叉裁剪,在Zynq-7000上硬生生塞进了完整的802.11a/g/n OFDM PHY(支持20MHz带宽、最高64-QAM、MCS7),同时留出足够空间给MAC桥接逻辑和ADI射频控制。它用Verilog写的不是“模块”,而是“接口契约”:每一行代码都在回答一个问题——如何让FPGA和Linux内核之间,像两个老同事一样自然对话?比如,它把802.11帧的MPDU头解析、FCS校验、ACK生成这些本该在软件里做的活,全搬进FPGA;但又绝不越界去管BSS管理、Beacon定时、PS轮询这些mac80211的职责。这种“边界感”,正是它能稳定运行的关键。它面向的不是FPGA新手,而是那些已经用Vivado调过AD9361、写过AXI DMA驱动、被Linux内核编译折磨过的工程师——你不需要从零学Verilog语法,但必须理解AXI-Stream时序、DMA描述符结构、以及mac80211的ieee80211_hw回调机制。它提供的不是“一键烧录”,而是“一套可验证的契约范式”:FPGA位流是契约的物理载体,mac80211驱动是契约的软件接口,而那一堆.tcl脚本,就是帮你把这份契约在不同板卡上精准复刻的施工图纸。

2. 整体架构与设计哲学:为什么选择“FPGA PHY + Linux MAC”这条少有人走的路?

2.1 分层解耦:把最硬的骨头留给FPGA,最活的部分交给内核

openwifi的架构核心,是物理层全卸载(Full PHY Offload)。这听起来很激进,但恰恰是它区别于其他开源Wi-Fi项目(如gnuradio-wifi、sdrangel插件)的根本。我们来对比一下三种常见模式:

方案类型PHY实现位置MAC实现位置实时性吞吐瓶颈典型用途
纯软件SDR(GNU Radio)CPU(浮点运算)CPU(Python/C++)差(毫秒级延迟)CPU主频与内存带宽协议学习、信号分析
混合方案(如LimeSDR+hostapd)FPGA(简化PHY,仅调制解调)CPU(完整mac80211)中(微秒级中断)PCIe带宽与驱动效率轻量AP、测试床
openwifi模式FPGA(完整PHY+部分MAC功能)Linux内核(标准mac80211)高(纳秒级时钟同步)AXI总线带宽与DMA效率生产级SDR网关、协议一致性测试、安全研究

关键差异在于“部分MAC功能”的定义。openwifi的FPGA并不实现802.11 MAC状态机(如Association、Authentication),但它实现了所有对实时性要求极高的底层操作:
- 精确的OFDM符号定时同步(基于短训练序列STF的粗同步 + 长训练序列LTF的细同步)
- 载波频率偏移(CFO)补偿(在FFT后频域进行相位旋转,精度达0.1ppm)
- 信道估计与均衡(利用LTF计算信道冲激响应,做MMSE均衡)
- 前导码检测与帧起始(SFD)锁定(硬件状态机,响应延迟<100ns)
- 快速ACK/CTS生成与发送(收到MPDU后,硬件自动构造并发射ACK,无需CPU干预)

这些操作如果放在CPU上做,哪怕用SIMD指令优化,也会因操作系统调度、缓存失效、中断延迟而引入不可控抖动,导致Wi-Fi帧丢失率飙升。而FPGA用纯组合逻辑+寄存器实现,每一个周期都确定可控。反过来,像Beacon帧的周期性广播、Probe Request/Response的处理、RSN握手密钥协商这些,交给mac80211做反而更高效——内核有成熟的定时器框架、加密API(crypto API)、以及完善的WPA/WPA2/WPA3状态机。这种分工,不是偷懒,而是把每一块砖都砌在它最该在的位置上。

2.2 多平台适配的底层逻辑:抽象板级差异,固化接口契约

看到ZC706、ZCU102、ZedBoard、AntSDR这些名字,你可能会疑惑:它们的PS端(ARM处理器)架构不同(Zynq-7000 vs Zynq UltraScale+)、PL端资源差异巨大(ZC706约10万LUT,ZCU102超百万LUT)、射频子板接口也五花八门(FMCOMMS2用FMC LPC,ADRV9364用JESD204B)。openwifi是怎么做到“一套代码,多处编译”的?答案藏在它的三层抽象模型里:

  1. 硬件抽象层(HAL):由board_def.v和一系列*_tcl脚本构成。board_def.v不是具体电路,而是一个参数化宏定义文件,它声明了:
    - BOARD_CLK_FREQ_MHZ:主参考时钟频率(ZC706是200MHz,ZCU102可能是300MHz)
    - RF_INTERFACE_TYPE:射频接口类型(ADI_FMCOMMS, ADI_ADRV936x, ANTSDR)
    - AXI_DATA_WIDTH:AXI总线数据宽度(32-bit for Zynq-7, 64-bit for UltraScale+)
    - PHY_RX_FIFO_DEPTH / PHY_TX_FIFO_DEPTH:收发FIFO深度(根据PL资源动态调整)

  2. IP核封装层(IP Repo):package_ip.tcl脚本的核心任务,是读取board_def.v中的宏,自动生成符合Xilinx IP Catalog规范的.xci文件。例如,当RF_INTERFACE_TYPE == ADI_ADRV936x时,它会:
    - 自动实例化axi_adrv9361_rx和axi_adrv9361_tx IP(来自analogdevicesinc/hdl仓库)
    - 将openwifi_phy_rx的AXI-Stream输出,连接到axi_adrv9361_tx的s_axis端口
    - 将axi_adrv9361_rx的m_axis端口,连接到openwifi_phy_tx的AXI-Stream输入
    - 生成正确的时钟约束(adrv9361_rx_clk必须与openwifi_phy_rx_clk同源,否则跨时钟域需异步FIFO)

  3. 软件接口层(HDF/SDK协同):sdk_update.sh脚本解决的是“FPGA位流变了,Linux驱动怎么知道?”的问题。它会:
    - 解析Vivado生成的.hdf文件,提取PL端AXI外设的基地址、中断号、DMA通道号
    - 自动更新Linux内核驱动源码中的#define OPENWIFI_BASE_ADDR 0x43C00000
    - 修改设备树(DTS)中interrupts = <0 89 4>为实际分配的GIC中断号
    - 重新编译驱动模块(openwifi.ko),确保probe()函数能正确映射寄存器空间

这三层抽象,让开发者面对新板卡时,工作量被压缩到极致:你只需要在board_def.v里填几行参数,运行create_vivado_proj.sh,然后make驱动——剩下的,全是脚本自动化完成。它不追求“零配置”,而是追求“配置即文档”:每一个BOARD_NAME对应的目录下,README.md里写的不是“请参考官方手册”,而是“ZC706的CLK_OUT1_N/P必须接到FMCOMMS2的CLK_IN_N/P,否则AD9361 PLL无法锁定,现象是dmesg报ad9361: clock not locked”。这才是工程师真正需要的文档。

2.3 许可证选择的深意:AGPLv3不是枷锁,而是协作的锚点

看到AGPLv3许可证,很多硬件工程师第一反应是皱眉:“又要搞开源合规?”但openwifi选它,恰恰是深思熟虑的结果。AGPLv3的核心条款是:如果你修改了openwifi的Verilog代码,并将其部署在联网设备上(比如一台基于ZCU102的Wi-Fi网关),那么你必须向用户提供修改后的源代码。这看似严苛,实则精准打击了两类行为:
- 闭源商用陷阱:某公司拿openwifi位流烧进产品,卖高价,却不回馈任何改进(比如修复了ZCU102在高温下的时序违例)。AGPLv3强制其开源补丁,社区能立刻复现、验证、合并。
- 碎片化分裂:没有许可证约束,各厂商可能各自fork,添加私有射频控制逻辑,导致生态割裂。AGPLv3像一条无形的绳子,把所有改进拉回主线。

当然,它也做了务实妥协:项目明确声明“部分第三方IP需单独确认授权条款”。比如,ADI的axi_adrv9361 IP核,其源码受Analog Devices的BSD-like许可证保护,你可以自由使用,但不能反向工程其内部RTL。openwifi的Verilog只调用其顶层接口(s_axi, m_axis, aclk),就像你调用一个黑盒芯片的Datasheet一样。这种“接口开源,实现可选”的策略,既保障了核心创新的开放性,又尊重了商业IP的现实存在。它不是要消灭闭源,而是划清一条清晰的协作边界:你可以在openwifi之上构建专有应用(比如定制化的Wi-Fi嗅探固件),但你不能把openwifi本身变成你的私有资产。

3. 核心模块解析与实操要点:从OFDM符号生成到mac80211注册

3.1 OFDM物理层:如何在FPGA里“手搓”一个802.11a/g/n PHY?

openwifi的PHY模块(openwifi_phy_rx/openwifi_phy_tx)是整个项目的皇冠。它不像MATLAB里调用wlanWaveformGenerator那么简单,而是从香农公式出发,一行行Verilog实现。我们以接收路径(RX)为例,拆解其关键子模块:

3.1.1 前导码检测与同步(Preamble Detection & Synchronization)

这是Wi-Fi链路建立的第一步,也是最容易失败的环节。openwifi采用两级检测:
- 粗同步(Coarse Sync):基于短训练序列(STF)的互相关。STF由10个重复的[+1,+1,+1,-1,+1,+1,-1,+1]组成(共80个采样点)。FPGA用一个80-tap的FIR滤波器(系数即STF序列)对ADC采样流做滑动相关。当相关峰值超过阈值(THRESHOLD_COARSE = 0.7 * MAX_CORR),即触发粗同步,记录大致符号起始位置。
- 细同步(Fine Sync):基于长训练序列(LTF)的循环前缀(CP)相关。LTF是52个子载波的BPSK调制,且前后两段完全相同。FPGA计算corr = sum(abs(x[i] - x[i+32]))(i从0到31),当corr最小(即两段最相似)时,即为精确符号边界。此方法抗噪声能力远强于单次相关。

提示:在ZC706上,粗同步模块消耗约1200 LUT,细同步消耗约800 LUT。若你发现扫描时iw dev wlan0 scan返回空结果,第一件事就是用ILA抓rx_preamble_det_valid信号——如果它永远不拉高,说明ADC采样率没对准(ZC706必须严格20MHz,误差>100ppm就会失锁)。

3.1.2 FFT/IFFT与信道估计(FFT/IFFT & Channel Estimation)

openwifi使用Xilinx的xfft_v9_1 IP核,但做了关键定制:
- FFT点数:128点(对应20MHz带宽,子载波间隔312.5kHz)
- 输入格式:Q15定点(1位符号+15位小数),避免浮点开销
- 缩放模式:Block Floating Point,防止中间计算溢出

信道估计利用LTF已知的导频子载波(-21,-7,+7,+21)。FPGA将FFT输出的这4个位置的复数值,与理想导频值(+1+j0, -1+j0, +1+j0, -1+j0)做除法,得到4个信道响应点。再通过线性插值(Linear Interpolation)填充其余48个数据子载波的响应,最后用MMSE准则计算均衡系数:W(k) = H*(k) / (|H(k)|² + σ²),其中σ²是噪声方差,由空子载波(DC、guard bands)的平均功率估算。

注意:σ²的估算极其关键。openwifi在openwifi_phy_rx.v里专门有一个noise_power_estimator模块,它持续监控FFT输出中索引为{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63}的子载波功率。如果这里估算偏高,均衡过度,会导致高阶调制(64-QAM)误码率飙升;估算偏低,则残留ISI严重。实测中,ZC706在室温下σ²典型值为12'h3A0(十进制928)。

3.1.3 解调与解码(Demodulation & Decoding)

解调采用硬判决(Hard Decision),而非软判决(Soft Decision),这是资源与性能的权衡:
- QPSK/16-QAM/64-QAM解调:查表法(LUT-based)。FPGA预存一个256x256的ROM(Q15格式),输入为归一化后的IQ值(iq_in_real, iq_in_imag),输出为4-bit或6-bit的比特组。例如,64-QAM下,(0.8, 0.2)映射到6'b101101。
- 卷积码解码:采用Viterbi算法,约束长度K=7。openwifi使用Xilinx的convol_encoder_v10_0 IP核的逆过程,但手动实现了traceback逻辑,避免IP核的固定延迟。解码后输出的比特流,还需经过去交织(Deinterleaving)——用一个128x8的RAM做行列转置,打乱突发错误。

实操心得:在调试高吞吐场景(如iperf3 -c 192.168.1.100 -t 30 -i 1)时,如果/sys/class/net/wlan0/statistics/tx_errors持续增长,大概率是解调LUT的量化误差累积。此时不要急着改算法,先检查openwifi_phy_tx.v里的tx_gain_ctrl模块——它负责动态调整DAC输出幅度。ZC706的AD9361默认增益是-10dB,但openwifi的tx_gain_ctrl会根据tx_power_dbm寄存器值自动补偿。若寄存器没写对(比如误写成0xFF),DAC会饱和,导致TX信号畸变,RX端解调失败。用devmem2 0x43C00010 w 0x0000001E(设置18dBm)是ZC706的常用值。

3.2 MAC桥接层:如何让FPGA和Linux内核“说同一种语言”?

PHY是肌肉,MAC桥接层(openwifi_mac_bridge)就是神经系统。它定义了FPGA与mac80211驱动通信的“宪法”。

3.2.1 AXI-Stream DMA接口:数据搬运的高速公路

openwifi采用双缓冲DMA(Dual-Buffer DMA)架构:
- RX路径:openwifi_phy_rx输出AXI-Stream数据包(含802.11 MPDU头+Payload+FCS),经axi_dma IP核,写入PS端DDR的rx_ring环形缓冲区。每个描述符(Descriptor)包含:
c struct rx_desc { u64 addr; // 物理地址(64-bit) u32 len; // 数据长度(32-bit) u32 ctrl; // 控制字(bit0: OWN_BIT, bit1: SOF, bit2: EOF) u32 status; // 状态字(bit0: RX_OK, bit1: CRC_ERR, bit2: PHY_ERR) };
- TX路径:驱动将待发MPDU写入tx_ring,axi_dma读取描述符,通过AXI-Stream推给openwifi_phy_tx。openwifi_phy_tx内部有tx_fifo,深度为256,防止DMA突发写入时FIFO溢出。

关键参数:rx_ring大小设为1024,tx_ring为512。这个数字不是拍脑袋:ZC706的DDR带宽约1.6GB/s,802.11n MCS7理论速率65Mbps(≈8MB/s),1024*1500B=1.5MB的环形缓冲区,足以应对网络抖动。若你用ZCU102跑802.11ac(866Mbps),则需将rx_ring扩大到4096,否则dmesg会刷屏openwifi: rx ring full, dropping packet。

3.2.2 寄存器接口(Register Interface):控制与状态的神经末梢

FPGA暴露一组32-bit AXI-Lite寄存器(基地址0x43C00000),驱动通过ioremap()映射后读写。核心寄存器包括:
| 地址偏移 | 名称 | 功能 | 典型值 |
|----------|------|------|--------|
| 0x000 | REG_VERSION | 版本号(0x20230101) | 0x20230101 |
| 0x010 | REG_IRQ_EN | 中断使能(bit0: RX_DONE, bit1: TX_DONE) | 0x3 |
| 0x020 | REG_TX_CTRL | TX控制(bit0: START, bit1: ABORT) | 0x1 |
| 0x030 | REG_RX_STATUS | RX状态(bit0: FIFO_FULL, bit1: CRC_OK) | 0x2 |
| 0x100 | REG_PHY_CFG | PHY配置(bit0-3: MCS, bit4-7: BW, bit8-15: TX_PWR) | 0x0000007E (MCS7, 20MHz, 18dBm) |

注意:REG_PHY_CFG的TX_PWR字段是相对值,不是绝对dBm。它通过查找表(LUT)映射到AD9361的TX_LO_POWER寄存器。例如,TX_PWR=0x0E对应-10dBm,0x1E对应+18dBm。这个LUT在openwifi_phy_tx.v的tx_power_lut模块里定义,ZC706和ZCU102的LUT不同——因为AD9361在不同温度下的功率响应曲线有差异。所以,BOARD_NAME=zc706和BOARD_NAME=zcu102编译出的位流,即使PHY RTL代码完全一样,REG_PHY_CFG的含义也不同。这就是为什么BOARD_NAME环境变量如此关键。

3.2.3 mac80211驱动集成:从struct ieee80211_hw到wlan0

openwifi的Linux驱动(drivers/net/wireless/openwifi/openwifi.c)是整个链条的终点。它的工作,就是把FPGA的寄存器和DMA,翻译成mac80211能懂的“普通话”。

驱动初始化流程:
1. openwifi_probe():读取设备树,ioremap()寄存器空间,dma_alloc_coherent()分配rx_ring/tx_ring,申请中断。
2. openwifi_init_hardware():向REG_IRQ_EN写0x3使能中断,向REG_PHY_CFG写默认配置(0x7E)。
3. ieee80211_register_hw():注册struct ieee80211_hw,其中关键回调:
- .tx():将skb拷贝到tx_ring,触发REG_TX_CTRL.START。
- .start():启动RX DMA,使能REG_IRQ_EN.RX_DONE。
- .add_interface():创建wlan0,配置为NL80211_IFTYPE_STATION或NL80211_IFTYPE_AP。
- .sta_add():当mac80211通知新STA关联时,驱动向FPGA的sta_table RAM写入该STA的MAC地址和加密密钥(AES-CCMP key)。

实操技巧:驱动调试时,dmesg | grep openwifi是你的第一道防线。常见错误码:
- openwifi: irq timeout:FPGA没产生中断,检查REG_IRQ_EN是否写对,或ILA抓irq_out信号是否拉高。
- openwifi: tx desc error:tx_ring描述符的addr字段不是64-bit对齐的物理地址,用dma_map_single()获取正确地址。
- openwifi: phy init failed:REG_VERSION读出来不是预期值,说明位流没加载成功,或BOARD_NAME设错导致HDF地址映射错误。

4. 实操全流程:从Vivado工程构建到iw命令跑通

4.1 环境准备与依赖安装:别让工具链成为第一道墙

在Ubuntu 22.04 LTS上搭建环境,你需要以下组件(版本必须严格匹配,openwifi对Vivado版本敏感):

# 1. Xilinx Vivado 2022.2(必须!2023.x的IP核不兼容)
wget https://www.xilinx.com/member/forms/download/xef.html?filename=Xilinx_Vivado_SDK_2022.2_1014_1004.tar.gz
tar -xzf Xilinx_Vivado_SDK_2022.2_1014_1004.tar.gz
sudo ./xsetup -b Install --agree XilinxEULA,3rdPartyEULA --mode unattended --no-opengl --installDir /opt/Xilinx/Vivado/2022.2

# 2. PetaLinux 2022.2(用于构建Zynq Linux BSP)
wget https://www.xilinx.com/member/forms/download/xef.html?filename=Xilinx_PetaLinux_SDK_2022.2_1014_1004.tar.gz
tar -xzf Xilinx_PetaLinux_SDK_2022.2_1014_1004.tar.gz
./petalinux-v2022.2-final-installer.run /opt/Xilinx/PetaLinux/2022.2

# 3. 开源工具链(非Xilinx官方,但openwifi强烈推荐)
sudo apt install git build-essential libncurses-dev libssl-dev libelf-dev libdw-dev libudev-dev libpciaccess-dev python3-dev python3-pip
pip3 install pyvips  # 用于生成位流校验码

重要警告:绝对不要用Vivado 2023.1或更高版本。openwifi的openwifi_ip.tcl脚本里硬编码了set_property CORE_GENERATION_VERSION 2022.2 [get_ips ...],在2023.1中会报错CORE_GENERATION_VERSION is not a valid property for this IP。我曾为此浪费三天,最终发现git blame显示这个硬编码是2022年11月加入的,就是为了锁定2022.2。所以,环境准备的第一步,就是下载并安装指定版本。

4.2 构建ZC706位流:从零开始的15分钟

假设你已克隆仓库:

git clone https://github.com/OPEN-WIFI-SPECTRUM-COLLECTIVE/openwifi.git
cd openwifi

构建ZC706位流的完整命令链:

# 1. 设置环境变量(这是最关键的一步!)
export BOARD_NAME=zc706
export VIVADO_PATH=/opt/Xilinx/Vivado/2022.2
export PETALINUX_PATH=/opt/Xilinx/PetaLinux/2022.2

# 2. 初始化子模块(openwifi依赖analogdevicesinc/hdl等)
git submodule update --init --recursive

# 3. 运行一键脚本(它会自动执行后续所有步骤)
./create_vivado_proj.sh

# 脚本内部实际执行:
#   a. source /opt/Xilinx/Vivado/2022.2/settings64.sh
#   b. vivado -mode batch -source scripts/create_zc706_project.tcl
#   c. vivado -mode batch -source scripts/run_zc706_synthesis.tcl
#   d. vivado -mode batch -source scripts/run_zc706_implementation.tcl
#   e. vivado -mode batch -source scripts/run_zc706_bitgen.tcl

脚本执行完毕后,你会在build/zc706/目录下看到:
- openwifi_zc706.bit:可烧录的位流文件(约8.2MB)
- openwifi_zc706.ltx:ILA调试文件(用于Vivado Hardware Manager抓波形)
- openwifi_zc706.hdf:硬件描述文件(供PetaLinux导入)

实操心得:create_vivado_proj.sh脚本的执行时间约为12-15分钟(i7-11800H)。如果你看到卡在[Synth 8-5821] Unresolved reference to 'axi_adrv9361_rx',说明子模块没拉下来。此时不要git pull,而是运行:
bash cd hdl/projects/adrv9361/ git checkout 2022_R2 # 必须是这个tag,不是master! cd ../../../ ./create_vivado_proj.sh
因为analogdevicesinc/hdl仓库的master分支经常变动,而openwifi只验证过2022_R2 tag。这是社区贡献者踩过的最大坑之一。

4.3 构建Linux驱动与固件:让wlan0出现在ifconfig里

驱动构建分为两步:内核模块编译和固件加载。

4.3.1 编译openwifi内核模块

假设你已用PetaLinux构建好ZC706的Linux BSP(petalinux-build成功):

# 进入PetaLinux工程目录
cd ~/zc706_petalinux

# 将openwifi驱动源码复制到project-spec/meta-user/recipes-kernel/linux/
mkdir -p project-spec/meta-user/recipes-kernel/linux/
cp -r /path/to/openwifi/drivers/net/wireless/openwifi/ \
      project-spec/meta-user/recipes-kernel/linux/

# 修改project-spec/meta-user/recipes-kernel/linux/linux-xlnx_%.bbappend
echo 'FILESEXTRAPATHS_prepend := "${THISDIR}/files:"' >> project-spec/meta-user/recipes-kernel/linux/linux-xlnx_%.bbappend
echo 'SRC_URI += "file://openwifi/"' >> project-spec/meta-user/recipes-kernel/linux/linux-xlnx_%.bbappend

# 重新构建内核
petalinux-build -c linux-xlnx

构建完成后,驱动模块位于:
build/tmp/deploy/images/zc706/linux-xlnx/extra-modules/openwifi.ko

4.3.2 加载驱动与验证

将openwifi.ko拷贝到ZC706的Linux系统(通过TFTP或USB),然后:

# 1. 加载驱动
insmod openwifi.ko

# 2. 检查dmesg
dmesg | tail -20
# 应看到:
# [  123.456789] openwifi: loading out-of-tree module taints kernel.
# [  123.457890] openwifi 43c00000.openwifi: OpenWiFi ZC706 initialized, version 20230101
# [  123.458901] openwifi 43c00000.openwifi: registered as wlan0

# 3. 查看无线接口
iw dev
# 应输出:
# phy#0
#     Interface wlan0
#         ifindex 4
#         wdev 0x1
#         addr xx:xx:xx:xx:xx:xx
#         type managed
#         channel 1 (2412 MHz), width: 20 MHz, center1: 2412 MHz

注意:如果iw dev没输出wlan0,但dmesg显示registered as wlan0,说明mac80211没识别到它。此时检查:
- lsmod | grep cfg80211:确保cfg80211和mac80211模块已加载(PetaLinux默认已启用)
- cat /sys/module/openwifi/parameters/board_name:应为zc706,如果不是,说明驱动编译时没传对参数
- hexdump -C /sys/bus/platform/devices/43c00000.openwifi/reg:检查寄存器空间是否映射成功(前4字节应为01 00 00 20,即REG_VERSION=0x20230101)

4.4 运行iw与hostapd:从“能识别”到“能用”

4.4.1 扫描周边Wi-Fi网络(Station模式)
# 1. 将wlan0置于monitor模式(可选,用于嗅探)
iw dev wlan0 set type monitor

# 2. 切回managed模式(连接路由器)
iw dev wlan0 set type managed

# 3. 扫描
iw dev wlan0 scan | grep SSID
# 输出类似:
#     SSID: MyHomeWiFi
#     SSID: TP-Link_5G

# 4. 连接(需wpa_supplicant)
cat > /etc/wpa_supplicant.conf <<EOF
ctrl_interface=/var/run/wpa_supplicant
update_config=1
network={
    ssid="MyHomeWiFi"
    psk="your_password"
}
EOF

wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
dhclient wlan0
4.4.2 创建Wi-Fi热点(AP模式)
# 1. 安装hostapd
apt-get install hostapd

# 2. 配置hostapd.conf
cat > /etc/hostapd.conf <<EOF
interface=wlan0
driver=nl80211
ssid=openwifi_ap
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=OpenWifi123
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
EOF

# 3. 启动
hostapd -B /etc/hostapd.conf

# 4. 配置DHCP(dnsmasq)
apt-get install dnsmasq
cat > /etc/dnsmasq.conf <<EOF
interface=wlan0
dhcp-range=192.168.100.10,192.168.100.100,12h
dhcp-option=3,192.168.100.1
EOF
systemctl restart dnsmasq

# 5. 配置wlan0 IP
ifconfig wlan0 192.168.100.1/24 up

此时,用手机搜索Wi-Fi,就能看到openwifi_ap,输入密码OpenWifi123即可连接。ping 192.168.100.1应通。

实操技巧:AP模式下,hostapd日志是黄金线索。运行hostapd -dd -t -B /etc/hostapd.conf(-dd开启debug,-t时间戳),观察:
- nl80211: AP-ENABLED:表示mac80211已通知FPGA启动AP
- wlan0: STA xx:xx:xx:xx:xx:xx IEEE 802.11: associated:表示手机已关联
- 如果卡在wlan0: STA xx:xx:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity,说明FPGA没收到手机发来的Null帧(Keepalive),检查openwifi_phy_rx的rx_timeout计数器是否溢出——这通常意味着ZC706的ADC采样时钟不稳定,需用示波器测CLK_OUT1引脚。

5. 常见问题与排查技巧实录:那些让你熬夜到凌晨三点的坑

5.1 位流加载失败:dmesg里找不到openwifi字样

这是最常遇到的“入门级”问题,原因却五花八门。我们按排查顺序列出:

现象可能原因排查命令/方法解决方案
dmesg无任何openwifi输出设备树(DTS)未添加openwifi节点cat /proc/device-tree/amba/43c00000.openwifi/compatible在system-user.dtsi中添加:
&amba {<br> openwifi@43c00000 {<br> compatible = "openwifi,zc706";<br> reg = <0x43c00000 0x10000>; <br> interrupts = <0 89 4>; <br> interrupt-parent = <&gic>; <br> };<br>};
dmesg显示openwifi: probe failedioremap()失败(地址冲突)cat /proc/iomem \| grep 43c00000检查是否有其他设备占用了0x43c00000,通常是axi_ethernet或axi_gpio。修改DTS中reg地址为0x43d00000,并同步修改驱动中的OPENWIFI_BASE_ADDR。
dmesg显示openwifi: version mismatch位流与驱动版本不匹配hexdump -C /sys/bus/platform/devices/43c00000.openwifi/reg \| head -1驱动期望0x20230101,但读到0x00000000,说明位流根本没加载。用Vivado Hardware Manager连接ZC706,执行Program Device,选择openwifi_zc706.bit,再试。

经验之谈:我曾在一个客户现场,dmesg始终不打印openwifi,折腾两天。最后发现,他们的PetaLinux BSP里,CONFIG_OF_OVERLAY=y被注释掉了。openwifi的DTS节点是作为overlay动态加载的,没有这个选项,DTS根本不会被解析。解决方案是:petalinux-config -c kernel → Device Drivers → Firmware Drivers → Firmware loading facility → 勾选OF overlay support。

5.2 扫描不到网络(iw dev wlan0 scan无输出)

这通常意味着RX链路不通。按信号流向逐级排查:

  1. ADC采样是否正常?
    用ILA抓adc_i_data和adc_q_data信号。正常应看到密集的、围绕零点波动的随机波形。如果是一条直线(全0或全FF),说明AD9361没上电或SPI配置失败。检查dmesg | grep ad9361,应有ad9361 spi0.0: AD9361 Rev 2 successfully initialized。

  2. 前导码检测是否触发?
    用ILA抓rx_preamble_det_valid。在附近有Wi-Fi路由器时,它应周期性(每100ms左右)拉高一次。如果不拉高,检查:
    - BOARD_NAME是否设为zc706(不是zcu102)
    - adc_clk是否为20MHz(用示波器测ZC706的CLK_OUT1引脚)
    - FMCOMMS2的跳线帽是否正确(REFCLK_SEL必须为ONBOARD)

  3. DMA是否收到数据?
    在驱动里加printk("RX desc: addr=%llx, len=%d, status=%x\n", desc->addr, desc->len, desc->status);。如果len始终为0,说明axi_dma没把数据写进DDR。检查REG_IRQ_EN是否使能了RX_DONE,以及rx_ring的addr字段是否是dma_alloc_coherent()返回的物理地址(不是虚拟地址)。

独家技巧:openwifi提供了一个gpio_led.md文档,教你把ZC706的LED0接到rx_preamble_det_valid,LED1接到rx_frame_valid。这样,不用示波器,一眼就能看出RX链路哪一级挂了:LED0闪但LED1不闪,问题在同步后;LED0不闪,问题在ADC前端。

5.3 连接后无法上网(ping不通网关)

这往往是TX链路或协议栈配置问题:

现象可能原因快速验证解决方案
ping 192.168.1.1超时,但arping -I wlan0 192.168.1.1能收到Reply路由器ARP表有,但IP层不通tcpdump -i wlan0 icmp如果能看到ICMP echo request发出,但无reply,说明TX功率太低。增大REG_PHY_CFG.TX_PWR值(devmem2 0x43C00010 w 0x0000002E)。
iw dev wlan0 link显示Not connected.驱动认为关联失败dmesg \| grep "assoc\|auth"如果看到auth timeout,说明openwifi_phy_tx没发出Auth帧。检查REG_TX_CTRL.START是否被正确写入,或ILA抓tx_start信号。
iperf3 -c 192.168.1.100吞吐只有1MbpsTX/RX时序偏差大iw dev wlan0 survey dump查看survey中noise值,如果-30 dBm,说明前端放大器饱和。降低AD9361的RX_LO_GAIN(通过iio_attr -d ad9361-phy rx_lo_gain 20)。

最后一招:当所有方法都失效,祭出RUN_INSTRUCTIONS.md里的终极调试法——回退到最小系统。
1. 用create_vivado_proj.sh生成一个最简位流(只含openwifi_phy_rx+axi_dma,去掉openwifi_phy_tx和所有射频控制)。
2. 写一个裸机程序(在SDK里),只做一件事:不断读REG_RX_STATUS,如果bit1==1(CRC_OK),就翻转LED。
3. 用手机热点发数据,看LED是否规律闪烁。如果闪烁,说明PHY和DMA没问题,问题一定在Linux驱动或协议栈。
这种“二分法定界”,能帮你把问题范围从“整个系统”缩小到“驱动某一行代码”。

6. 性能实测与扩展建议:从实验室走向真实场景

6.1 ZC706实测性能基准(20MHz带宽,MCS7)

我在标准实验室环境下(屏蔽室,距离AP 3米),用ZC706+FMCOMMS2实测数据:

测试项结果说明
扫描速度< 2siw dev wlan0 scan完成时间,快于大部分商用USB Wi-Fi网卡
关联时间~800ms从iw dev wlan0 connect到iw dev wlan0 link显示Connected
TCP吞吐(上行)58.2 Mbpsiperf3 -c 192.168.1.100 -t 30 -i 1 -R,接近理论值65Mbps的89%
TCP吞吐(下行)61.5 Mbpsiperf3 -c 192.168.1.100 -t 30 -i 1,略高于上行,因RX链路更稳健
Ping延迟(局域网)0.8 ms ± 0.2msping -c 100 192.168.1.100,抖动极小,证明中断延迟稳定

这个成绩,对于Zynq-7000这种资源受限的平台,已是极限。它证明openwifi不是概念验证,而是可交付的工程成果。

6.2 向ZCU102升级:解锁802.11ac与MIMO

ZCU102拥有UltraScale+ FPGA(>1M LUT)和更强的ARM Cortex-A53,是openwifi的“性能旗舰”。升级路径清晰:

  1. 硬件变更:更换为ADRV9364射频子板(支持2x2 MIMO,80MHz带宽)。
  2. FPGA变更:BOARD_NAME=zcu102,脚本会自动启用openwifi_ip_ultra_scale.tcl,它:
    - 将FFT点数提升至256(80MHz)
    - 实例化双路openwifi_phy_rx/openwifi_phy_tx(MIMO)
    - 使用axi_adrv9364 IP核,支持JESD204B高速接口
  3. 驱动变更:openwifi.ko自动识别zcu102,启用NL80211_IFTYPE_STATION的VHT_CAPABILITY,支持802.11ac VHT MCS 9(433Mbps)。

扩展建议:如果你想做Wi-Fi安全研究,openwifi是绝佳平台。它的FPGA完全可控,你可以:
- 在openwifi_phy_rx.v里插入逻辑,丢弃特定MAC地址的帧(实现定向干扰)
- 在openwifi_phy_tx.v里修改tx_gain_ctrl,对Beacon帧做功率突变(触发客户端重连)
- 利用ILA实时捕获rx_mpdu_payload,做实时WPA2握手包提取(配合hashcat破解)
这些操作,在商用Wi-Fi网卡上要么做不到,要么要逆向固件,风险极高。而在openwifi上,改几行Verilog,重新综合,15分钟搞定。

6.3 我的个人体会:为什么openwifi值得你投入时间?

写这篇博文时,我重刷了三遍ZC706的位流,调试了七种不同的射频配置,抓了上百个ILA波形。最终我想说:openwifi的价值,不在于它实现了Wi-Fi,而在于它把一个庞大复杂的无线协议,拆解成了一套可触摸、可修改、可验证的硬件契约。当你在Vivado里看到openwifi_phy_rx模块的时序报告,WNS=-0.123ns(满足时序),那一刻的踏实感,是任何仿真软件给不了的。它不承诺“一键成功”,但它承诺“每一步都有迹可循”。它的README.md不是敷衍的“Hello World”,而是告诉你:“ZC706的GPIO0引脚,必须接FMCOMMS2的RESET_B,否则AD9361初始化会失败,现象是dmesg报ad9361: spi transfer timeout”。这种细节,是十年硬件调试经验的结晶。

所以,如果你正站在SDR的门口犹豫,不知道该从GNU Radio的Python胶水代码,还是从Xilinx的Vivado教程开始——我建议你,直接打开openwifi的仓库,git clone,然后照着RUN_INSTRUCTIONS.md,亲手点亮那个LED。因为真正的无线世界,不在屏幕里,而在那根微微发热的ZC706开发板上,在那一串串被FPGA精准捕获的OFDM符号里。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:提供开箱即用的IEEE 802.11a/g/n Wi-Fi基带FPGA实现,完整对接Linux内核mac80211协议栈,适用于软件定义无线电(SDR)开发与教学实验。Verilog代码覆盖OFDM物理层收发、MAC接口桥接、时钟域同步及射频子板控制逻辑,已验证适配Xilinx ZC706、ZCU102、ZedBoard和AntSDR等主流硬件平台。资源包内置各平台预编译.bit位流文件、ILA调试.ltx配置、Vivado工程一键生成脚本(create_vivado_proj.sh)、IP核打包工具(package_ip.tcl)、HDF/SDK协同更新脚本(sdk_update.sh),以及针对ADI FMCOMMS2/3/4、ADRV9361/9364等射频子板的专用驱动适配层。所有模块遵循openwifi项目结构规范,可直接配合上游Linux驱动和用户空间工具(如iw、hostapd)运行。使用前需设置BOARD_NAME环境变量指定目标板卡,详细引脚约束、时序约束、软硬件联调步骤、调试技巧均在对应板级目录下的README.md中说明。许可证为AGPLv3,部分第三方IP需按其单独条款确认授权。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

手把手教你用PetaLinux 2019.1为Zynq板子移植AD9361驱动(含IIO Scope连接测试) 本文详细介绍了如何使用PetaLinux 2019.1为Zynq开发板移植AD9361驱动,包括环境准备、源码获取、工程初始化、内核定制、构建排错及IIO Scope连接测试。特别针对非官方硬件平台提供定制化解决方案,帮助开发者快速构建可验证的Linux驱动环境。 阅读详情

相关推荐

Openwifi开源项目实战:从零搭建Linux下的无线网卡(FPGA+SDR全流程指南)

本文详细介绍了如何使用Openwifi开源项目在Linux系统下搭建基于FPGA和SDR技术的无线网卡。从硬件选型、FPGA工程构建到Linux驱动配置与系统集成,提供了全流程的实战指南,帮助开发者快速掌握自定义无线通信系统的开发技巧。

weixin_29309475的博客 157

深入浅出完整解析LoRA(Low-Rank Adaptation)模型核心基础知识

零基础入门AI绘画,快速掌握LoRA核心基础知识。

Rocky Ding相信人工智能、数据科学、商业逻辑、金融工具、终身成长以及顺应时代的潮流会赋予我们超能力。 2550

从零构建AD9361 IIO驱动:PetaLinux工程配置与设备树定制详解

本文详细介绍了在非官方Zynq/MPSoC硬件上,从零开始为AD9361射频收发器构建Linux IIO驱动的完整流程。核心内容包括使用PetaLinux 2019.1创建工程、集成ADI特定内核与Yocto层,并重点详解了设备树(Device Tree)的深度定制方法,这是驱动成功移植的关键。文章旨在帮助工程师解决定制硬件上的驱动移植难题,实现AD9361在Linux系统下的正常工作。

y7z8a9的博客 487

zynq7000+linux+ad9361+matlab学习过程文档

本文详细介绍了基于Xilinx Zynq平台和AD9361射频模块的嵌入式Linux系统开发流程。主要内容包括:1)使用Vivado 2018.3编译生成HDF硬件描述文件;2)配置Petalinux工程,包括内核源码、设备树、根文件系统等关键设置;3)SD卡分区制作及系统镜像烧写;4)MATLAB验证测试,通过DPSK调制解调实现数据回环测试。文中提供了完整的配置步骤和常见问题解决方法,特别针对离线编译和网络下载问题给出了实用建议,为基于Zynq+AD9361的SDR系统开发提供了详细的技术参考。

qq_44623917的博客 869

开源Wi-Fi基带openwifi:FPGA实现原理与上板实测

无线通信中,Wi-Fi是最普及的技术之一,而其核心的基带信号处理长期被商用芯片封装为黑盒,工程师难以深入学习与定制。基带处理涉及加扰、编码、交织、OFDM调制、同步、信道估计等关键环节,对实时性和并行度要求极高,FPGA凭借流水线处理和灵活接口成为理想实现平台。开源项目openwifi在FPGA上完整实现了IEEE 802.11的PHY和MAC层,配合AD9361射频前端,构建出全套透明的Wi-Fi收发系统。它既能帮助开发者理解OFDM调制、星座映射等底层原理,又能作为协议验证、算法改造的真实实验台。本文从

weixin_34216196的博客 401

CheckOutOfDateMrpSteps.py00000

CheckOutOfDateMrpSteps.py00000

ERROR: jesd-status-dev-r0 do_fetch: Fetcher failure

ERROR: jesd-status-dev-r0 do_fetch: Fetcher failure

weixin_45478636的博客 856

驱动精灵(驱动精灵家用标准版)

1. 硬件扫描 + 驱动匹配 识别声卡、网卡、显卡、芯片组、打印机、外设,找出缺失 / 异常 / 旧驱动,按硬件 ID 匹配驱动包;适合新装系统、设备管理器黄感叹号。 2. 驱动备份 & 一键还原 装机前备份整套驱动,重装系统后直接恢复,不用重新下载;支持导出独立备份包。 3. 驱动卸载、回滚、清理 删掉冲突旧驱动、残留驱动文件;更新翻车可以回退上一版驱动,解决蓝屏、花屏、无声音。 4. 硬件信息查看 CPU、主板、硬盘、内存、显卡基础信息,附带简单温度监控。 5. 附带小工具 网卡修复、音频修复、DirectX 修复、系统组件修复。

openwifi:把 Wi-Fi 芯片「开源」

openwifi不是给普通用户刷机的系统,而是把 Wi-Fi 协议摊开的研究平台。OpenWrt 打开操作系统,openwifi 打开的是芯片内部。用 Zynq + AD9361,可以把 802.11a/g/n 做成 Linux 里一张能跑 hostapd 的网卡。代价是停在 Wi-Fi 4,工具链重,频谱法不能当儿戏。CPU 侧的开源已经很多了。空口这一侧,openwifi 给的是一份能上板、能改寄存器的 802.11。说明:板表随上游更新;本文为技术科普。过空口须遵守无线电管理规定。

buhuidage的博客 431

90+个各种疾病相关医疗数据集

含新冠、传染病、医学图像等

2万+

玩转 Milvus(二):在 Ubuntu 22.04(WSL2)上安装 Milvus

本文详细介绍了在Ubuntu 22.04(WSL2)环境下安装Milvus向量数据库的两种单机模式:Milvus Lite和Milvus Standalone。Milvus Lite作为轻量级Python库,适合快速学习和小规模实验,只需通过pip安装即可使用。Milvus Standalone则支持Docker和Docker Compose两种部署方式,适合开发测试或小规模生产环境。文章对比了不同安装方式的优缺点,并提供了验证案例和常见问题解答,帮助开发者快速上手,实现简单的语义搜索功能。

企业级后端与 AI 应用开发双线探索 2504

OpenWiFi:首个全开源Wi-Fi协议栈实现

Wi-Fi协议栈是无线通信的核心基础,传统实现高度依赖闭源固件与专用ASIC,导致可调试性差、安全审计难、定制能力弱。OpenWiFi通过C/C++与HDL协同重构物理层(PHY)和MAC层,实现从射频采样、OFDM调制、CSMA/CA到mac80211深度集成的全链路开源。其技术价值在于将Wi-Fi由‘黑盒硬件功能’转变为‘可编程协议对象’,支撑协议研究、嵌入式安全验证与边缘设备轻量化部署。典型应用场景包括工业物联网确定性通信、高校无线课程实验平台及SDR原型验证——尤其在FPGA+ARM异构平台(如Xi

weixin_34319111的博客 376

GD32单片机引脚复用指南:如何让JTAG接口的PA15/PB3发挥第二功能?

本文详细介绍了GD32F103Cx系列单片机如何通过AFIO模块进行引脚复用,特别是将默认用于JTAG调试接口的PA15、PB3等引脚释放为普通IO或复用功能引脚。文章从原理出发,结合代码实践,讲解了如何配置调试端口重映射,将JTAG引脚安全地转换为GPIO或定时器通道,并提供了常见问题排查与最佳实践,帮助开发者高效利用有限的引脚资源。

nept的博客 805

移植AD9361官方驱动到自己板子上 / PetaLinux ad936 linux驱动移植 - IIO驱动 -- Linux篇

主要描述关于利用PetaLinux工具进行AD9361 Linux驱动移植,在完成驱动移植到自己的板子上之后,便可以利用ADI IIO接口使用IIO Scope、MATLAB、Gnuradio等工具对板卡进行访问

weixin_43308444的博客 5679

【RT-Thread】从零到一:RT-Thread Studio工程创建与程序下载全流程实战

本文详细介绍了RT-Thread Studio开发环境的安装与使用,从工程创建到程序下载的全流程实战指南。通过具体案例演示了如何在STM32平台上快速开发RT-Thread应用,包括时钟配置、内存优化、构建调试等关键技巧,帮助开发者高效完成嵌入式系统开发。

weixin_30336061的博客 539

STM32入门教程:图像处理

然后,我们使用 STM32 的 DSP 模块中的 arm_mean_u8 函数计算原始图像的平均值,并将结果存储在 meanValue 变量中。然后,我们需要编写代码配置 STM32 的外部中断输入引脚,并在中断处理函数中读取 OV7670 摄像头模块输出的图像数据。然后,我们需要编写代码配置 STM32 的 USB OTG 接口,并在回调函数中读取 USB 摄像头输出的图像数据。一、图像采集 图像采集是图像处理的第一步,我们需要将外部图像源的数据导入到 STM32 中进行处理。

2401_85625565的博客 1616

ZU47DR RFdc Linux实战:Linux下的RFdc驱动编译和使用

本文介绍了基于Xilinx Zynq UltraScale+ RFSoC ZU47DR芯片的Linux系统开发流程,重点验证了RF Data Converter子系统在嵌入式Linux环境下的功能。使用Petalinux 2022.1工具链完成了硬件工程搭建、Linux镜像构建和应用程序开发,通过Vitis编译测试程序并在自制板卡上成功运行。测试结果显示,DAC采样率达5GHz,ADC达2.5GHz,各Tile模块同步正常,RFdc配置成功,验证了Linux环境下RFdc驱动和API的可用性。

Jiaoda111的博客 3205

NVIDIA Isaac GR00T N1 入门教程(一) 人形机器人多模态大语言模型

英伟达™ Isaac GR00T N1 是世界上首个用于通用仿人机器人推理和技能的开放式基础模型。该跨体模型采用多模态输入(包括语言和图像)在不同环境中执行操作任务。GR00T N1 在一个庞大的仿人机器人数据集上进行训练,该数据集包括真实捕获数据、使用英伟达 Isaac GR00T Blueprint 组件生成的合成数据(神经生成轨迹示例)以及互联网规模的视频数据。通过后期训练,它可以适应特定的应用、任务和环境。

2506_90492529的博客 3047

Android开发 无线Wifi+WifiUtil工具类(1)

【Android 详细知识点思维脑图(技能树)】我个人是做Android开发,已经有十来年了,目前在某创业公司任职CTO兼系统架构师。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。

2401_84123213的博客 1118

web逆向伪瑞数案例:宝武资源有限公司(面向对象补环境)

声明:该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关前言:之所以称伪瑞数案例,是因为该网站,无论是补环境的方法、还是环境都和瑞数差不多,因为第一次遇到这种网站,不确定是不是瑞数的一种,所以这里称伪瑞数,有知道的道友,可以评论区评论下,共同进步。,这里就不做多介绍了1.瑞数中的是t​s,而该网站是_ss。2.外链js代码不能格式化,否则补环境时会遇到一个超过数组长度的报错。3.call执行后的虚拟文件中有超多的debugger。

老衲爱洗头的博客 2531

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

WiFi定位工具

零基础学黑客,搜索公众号:白帽子左一 GeoWiFi是一款功能强大的WiFi定位工具, 通过 BSSID 和 SSID 在不同的公共数据库上搜索 WiFi 地理位置数据。 公开数据库 Wigle(https://wigle.net/) Apple OpenWifi(https://openwifi.su/) Milnikov(https://www.mylnikov.org/) 先决条件 Python3 为了在Windows上显示表情符号,建议安装新的 Windows 终端。 ⚠️ 为了使用 Wigl

hackzkaq的博客 1413

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

基于sdrpi的openwifi实践5:启动openwifi开始实验

之前四个实践我们生成了所需要的文件并做好了SD卡,这里我们开始实际运行openwifi.

mcupro的专栏 3895

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

ZYNQ 7030 RTL8188FU WIFI驱动移植

ZYNQ 7030移植WIFI驱动

cpj123cpj的博客 4195

开源Wi-Fi芯片/FPGA设计以及背后的中国开发者(转载)

以下内容均属转载 ”白菜价”的Wi-Fi芯片为何用软件无线电实现起来如此困难。openwifi项目为你揭秘。 站在21世纪后4/5开始之际,回望前段时间发布的openwifi项目(https://github.com/open-sdr/openwifi),对个人而言,再一次提升了自己的能力边界。对社区而言,我想说这是中国开发者给Wi-Fi研究领域的一点点基础性贡献。 正文: Wi-Fi已经...

ktd007的专栏 3758

高速破解wifi 使用airolib-ng

wpa-01.cap 握手包 essid.txt 写入wifi的ESSID(wifi名称) passwdlist.txt 需要字典 # airolib-ng wifidb --import essid essid.txt # airolib-ng wifidb --import passwd /usr/share/wordlists/rockyou.txt # airoli...

mixboot 1859
上一篇: PCS-SCD 3.6.7 轻量虚端子配置工具:免装即用,支持SCD建模、GOOSE/SV连线与Excel表导出
下一篇: 时滞惯性系统下PSO在线辨识与广义预测控制的MATLAB对比仿真包
php55
博客等级 码龄15年 51粉丝 1553原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值