简介:HackRF One 软件无线电平台的中文用户手册,面向无线电爱好者、通信专业学生及安全研究人员,帮助读者快速了解平台的硬件架构、协议支持范围,并掌握在 Windows 与 Linux 环境下的开发环境搭建方法。手册内容覆盖硬件组成与 FPGA 处理逻辑、Windows 下 USB 驱动及 SDRSharp 配置、Linux 下 GNURadio 与 gqrx 环境部署,并附有 GNURadio 常用模块介绍和 FM 收发实例,便于从入门到实操逐步跟进。资源为单个 PDF 文件,压缩包大小 2.49MB,携带方便,可离线查阅。目前已有 1511 人浏览学习,适合希望低成本进入 SDR 开发领域的初学者作为第一份中文参考材料。
1. HackRF One 软件无线电平台:从 USB 驱动到 GNURadio 的完整上手路径
HackRF One 软件无线电平台用户手册拿到手时,我以为又是一份官网文档的翻译件,翻完才发现它把 USB 驱动、交叉编译、GNURadio 串成了一条完整的上手链路。HackRF One 的射频范围是 10MHz-6GHz,带宽 20MHz,ADC/DAC 为 8bit 20Msps,发射功率 14dBm,这套参数决定了它特别适合做接收实验、频谱观测和近距离收发验证,而不是追求高灵敏度的测量仪表。文档从 Windows 的 Zadig 驱动一步步写到 Linux 下的 gqrx 和 GNURadio,再给出 FM 收发实例,正好覆盖新手拿到板卡后最迷茫的「从连电脑到出波形」这一段。适合刚入手 HackRF One 的开发者,也适合想在一两天内搭出 GNURadio 信号链的从业者。
2. Windows 环境部署:从 Zadig 驱动到 libhackrf 静态库编译
2.1 Zadig 驱动安装:SDRSharp 收听 FM 的五个配置点
Windows 下的部署分两层:第一层是让系统识别 HackRF One,第二层是让 SDR 软件能调用它。手册先把 VS2012 Redistributable 装掉,这一步很多人会跳过,但后面跑 SDRSharp 和编译出来的 exe 时缺少运行库会直接报错,属于典型的「省事反而误事」。驱动安装用的是 Zadig,这套流程在 Windows 8 到 Windows 10 上都通用。
连接 HackRF One 后,打开配套资料光盘里的 zadig.exe,在下拉菜单里选择「HackRF One」设备,点「Install WCID Driver」。WCID 是 Windows 复合设备接口描述符,装完以后设备管理器里会多出一个识别正常的 HACKRF 设备项,而不是带感叹号的未知设备。常见做法是先用设备管理器确认枚举成功,再去点安装,这样能第一时间区分是 USB 识别问题还是驱动问题。
SDRSharp 是绿色软件,解压后直接运行。它的配置顺序有个强约束:先点「Start」启动设备,再点「Configure」拉增益滑块,否则滑块是灰色不可拖动的。这个顺序问题在手册里明确标注了,但实际使用中还是很多人会卡住——因为 SDRSharp 的界面不会提示你为什么滑块不可用,只能靠经验。
增益调节分两段:LNA Gain 负责射频前端低噪声放大器的增益,VGA Gain 负责中频可变增益。我一般会先把 LNA 拉到中等偏上位置看底噪,再逐步加 VGA,直到信号强度合适且底噪不爆炸。Radio 选项卡里选 WFM 解调,滤波器类型选 Blackman-Harris 4,带宽 250000,步进 50KHz,勾选 Snap to grid。Audio 选项卡选声卡输出。这几个参数配合好,点 Run 就能听到 FM 广播。
不同场景的解调参数选型如下表:
| 信号类型 | 解调模式 | 滤波器带宽 | 适用场景 |
|---|---|---|---|
| FM 广播 | WFM | 250kHz | 87-108MHz 调频广播 |
| AM 广播 | AM | 6-10kHz | 中波、短波 AM 电台 |
| 航空语音 | AM | 8-16kHz | 118-137MHz 航空波段 |
| 业余无线电 | LSB / USB | 2.4-3kHz | 短波单边带通话 |
有两点注意:滤波带宽设得过窄会让语音发闷,过宽则邻频干扰明显;Snap to grid 勾选后调频只能停在步进值上,适合快速扫台,扫到信号后再取消勾选做细调。
2.2 VS2010 编译 libhackrf:静态库工程与依赖项配置
如果只是收个 FM,SDRSharp 已经够用。要用代码控制 HackRF One,就得自己编译 libhackrf。手册给的编译环境是 VS2010,依赖两个外部库:pthreads-w32 和 libusbx-1.0.18。这两样缺一不可,pthreads 提供 POSIX 线程接口,libusbx 负责 USB 设备通信,libhackrf 是在两者之上封装出的 SDR 控制层。
先装 pthreads-w32,把 Pre-built.2 解压到固定路径,再把 pthreadVC2.dll 拷到 C:\Windows\System32。libusbx 解压后保持目录结构,里面同时有 MS32 和 MS64 两个平台的 static/dynamic 库。这里有个容易翻车的细节:VS2010 默认编译的是 32 位程序,库目录必须指向 MS32 而不是 MS64,否则链接器会报「无法解析的外部符号」。
创建 Win32 静态库工程,把 hackrf.c 和 hackrf.h 添加进去,然后在项目属性里配包含目录和库目录。包含目录指向 pthreads 的 include 和 libusbx 的 include,库目录指向 pthreads 的 lib/x86 和 libusbx 的 MS32/static。配置类型选静态库,编译后得到 Libhackrf.lib。
手册附带了一个测试程序 HackRFLibTest,核心逻辑是枚举板卡信息。去掉窗口初始化的干扰后,主干代码如下:
#include "hackrf.h" #include <stdio.h> #include <stdlib.h> int _tmain(int argc, _TCHAR* argv[]) // VS2010 Win32 控制台工程的默认入口 { hackrf_device* device = NULL; int result = HACKRF_SUCCESS; uint8_t board_id = BOARD_ID_INVALID; char version[255 + 1]; read_partid_serialno_t sn; result = hackrf_init(); // 1. 初始化库,加载 USB 上下文 if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_init() failed: %s (%d)\n", hackrf_error_name((hackrf_error)result), result); return EXIT_FAILURE; } result = hackrf_open(&device); // 2. 打开第一个 HackRF 设备 if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name((hackrf_error)result), result); return EXIT_FAILURE; } hackrf_board_id_read(device, &board_id); // 3. 读取板卡 ID printf("Board ID: %d (%s)\n", board_id, hackrf_board_id_name((hackrf_board_id)board_id)); hackrf_version_string_read(device, &version[0], 255); // 4. 读取固件版本 printf("Firmware: %s\n", version); hackrf_board_partid_serialno_read(device, &sn); // 5. 读取序列号 printf("Serial: 0x%08x 0x%08x 0x%08x 0x%08x\n", sn.serial_no[0], sn.serial_no[1], sn.serial_no[2], sn.serial_no[3]); hackrf_close(device); // 6. 关闭设备 hackrf_exit(); // 7. 释放库资源 printf("input ENTER to quit.\n"); getchar(); return 0; }这段代码的逻辑顺序是固定的:hackrf_init 必须先于一切调用,它在内部完成 libusb 的初始化;hackrf_open 会枚举 USB 总线上的 HackRF 设备,如果驱动没装好这里会直接失败;board_id 和 version 是两块只读信息,用来确认固件版本和板卡型号;partid_serialno 拿到的四个 32 位字是芯片生产时的唯一标识,同一批板卡前两个字通常相同,后两个字各不相同。
工程属性里链接器 → 输入 → 附加依赖项要加三条:libhackrf.lib、libusb-1.0.lib、pthreadVC2.lib。如果编译报找不到库文件,直接把 libusb-1.0.lib 和 pthreadVC2.lib 从原始路径复制到工程目录再添加引用,这种暴力做法能绕过绝大多数路径配置问题。运行阶段如果提示缺 pthreadVC2.dll,把它复制到 exe 所在目录即可。
注意:手动编译的 libhackrf 只包含库文件本身,运行时仍依赖 libusb 和 pthreads 的 DLL。发布程序给别人用时,这三个 DLL 要一起带上,否则目标机器会报缺失 DLL。
3. Linux 环境部署:用 GNURadio 与 gqrx 搭起可用的 SDR 开发链
3.1 安装源选择:Ubuntu 下的 gnuradio、gqrx 与 gr-osmosdr
Linux 下的开发工具链比 Windows 完整得多,GNURadio 是信号处理框架,gqrx 是图形化频谱接收软件,gr-osmosdr 是连接 HackRF 等 SDR 硬件和 GNURadio 之间的桥接层。手册推荐 Ubuntu 14.04,因为那个年代这套工具链的二进制包只在老版本源里齐备。现在的 Ubuntu 20.04 以上直接 apt 装 gqrx-sdr 也能用,但 gr-osmosdr 可能需要自行编译。
手册里的安装命令如下:
# 添加 gqrx 的 PPA 源,提供更新的 gqrx 版本 sudo add-apt-repository ppa:gqrx/releases sudo apt-get update # 安装 gqrx 图形接收软件、gnuradio 信号处理框架、 # gr-osmosdr 硬件抽象层和 hackrf 命令行工具 sudo apt-get install gqrx gnuradio gr-osmosdr hackrf第四行的 hackrf 包提供的是 hackrf_info、hackrf_transfer 等命令行工具,不装它也能用 gqrx,但后面做命令行收发验证就缺了工具。
如果安装过程中报 'Held packages' 类型错误,原因是系统里已有部分旧包与新包依赖冲突,尤其是 gnuradio 这种依赖树很深的大包。处理方式是执行sudo apt-get dist-upgrade,把包管理器里的版本升级到一致状态。这条命令会动系统里不少组件,虚拟机上操作问题不大,物理机建议先把当前状态快照好再执行。
3.2 现成虚拟机方案:导入步骤与三项快速验证
自己编译 GNURadio 动辄几小时,且依赖问题层出不穷。手册的配套光盘里放了一个搭好的虚拟机镜像,解压后用 VMware 打开 .vmx 文件即可。导入步骤并不复杂:解压压缩包、VMware 打开工程、按提示默认选项、登录密码是预设的。这套方案对只想快速验证 HackRF 接收能力的人特别友好,省掉了从源码编译 gr-osmosdr 的漫长等待。
虚拟机启动后,要让虚拟机里的系统识别到 HackRF 硬件,需要在 VMware 窗口右下角点击 USB 图标,把设备从「连接到主机」切换为「连接到虚拟机」。这一步容易忽略,设备没接进虚拟机的话,虚拟机里的 hackrf_info 会报找不到设备。
三项验证命令如下:
# 1. 验证 USB 驱动枚举是否成功,能看到板卡 ID 和固件版本就是正常 sudo hackrf_info # 2. 验证 GNURadio 图形界面能否启动,弹出画布窗口即可 gnuradio-companion # 3. 验证 gqrx 能否启动,能出现频谱窗口并把设备设为 HackRF 即可 gqrxhackrf_info 验证的是 USB 链路,输出里如果能看到 Board ID Number 和 Firmware Version,说明驱动、固件、USB 直通都通了。gnuradio-companion 弹出窗口只能说明框架是好的,真正的硬件验证要到 gqrx 这一步,在 gqrx 的 Input 控件里选择 HackRF 设备后,能看到跳动的频谱底噪才算完全打通。
注意:虚拟机里做接收实验问题不大,做发射实验要谨慎。USB 虚拟化会引入时序抖动,HackRF 的发射对 USB 实时性要求高于接收,常见做法是发射实验放到物理机上做,虚拟机的 USB 直通留给接收和信号分析。
4. GNURadio 信号链实操:FM 接收与发射实例的模块参数
4.1 从模块列表到画布:GNURadio 的基本操作习惯
GNURadio Companion(GRC)的操作逻辑是拖模块连线。右侧模块列表里找到需要的模块,双击添加到画布;模块间连线时依次点击两个模块的端口,GRC 会自动按类型匹配连接。模块多的时候用 Ctrl+F 搜索名字最省事,比如搜「osmocom」就能定位到硬件接口模块。
Options 模块是整个工程的元信息入口,双击打开后要设置 ID(工程名)和 Generate Options(生成代码风格)。这里有个实际经验:ID 里不要带空格和中文,生成的 Python 文件名会直接拿 ID 当模块名,空格会导致运行时报语法错误。这个坑在 GRC 里几乎每个人都踩过。
模块连好线后,双击任意模块都能改参数。每个调频广播信号链的核心在于三个数字:接收频率、采样率、音频输出率。三者关系没理清时,要么收不到台,要么出声速度不对。这部分的手动调参逻辑比界面操作本身更重要。
4.2 FM 接收实例:从 osmocom Source 到 Audio Sink 的模块链
手册第 5 章给了完整的 FM 接收实例,模块链是 osmocom Source → WBFM Receive → Rational Resampler → Audio Sink。这条链的含义是:硬件采集 IQ 数据,WBFM 模块做正交解调,重采样模块把采样率降到声卡能处理的范围,最后交给声卡输出。
| 模块 | 关键参数 | 推荐值 | 说明 |
|---|---|---|---|
| osmocom Source | Ch0 Frequency | 当地 FM 电台频率,如 97.5M | 频率必须落在 10MHz-6GHz 工作范围 |
| osmocom Source | Ch0 RF Gain | 0~14dB,从最小开始试 | 拉满时底噪明显抬高 |
| osmocom Source | Ch0 IF Gain / BB Gain | 20dB / 40dB | 中频和基带增益,影响弱信号灵敏度 |
| osmocom Source | Sample Rate | 2M | 20M 上限的 1/10,兼顾带宽和 USB 稳定性 |
| WBFM Receive | Quadrature Rate | 2M | 必须与 Source 采样率一致 |
| WBFM Receive | Audio Decimation | 4 | 音频率降为 500kHz 后交给下一级 |
| Rational Resampler | Interpolation / Decimation | 1 / 10 | 按声卡采样率换算,48kHz 输出配 480k 输入 |
| Audio Sink | Sample Rate | 48000 | 声卡标准采样率 |
参数设置的先后逻辑是:先定 Source 采样率,再让 WBFM Receive 的 Quadrature Rate 和它对齐,最后用 Rational Resampler 把音频率匹配到声卡。如果声音语速过快或过慢,问题出在 Rational Resampler 的换算系数上,而不是 WBFM 模块本身。
实际接收时还有两个操作细节。一是频率要先设到目标电台,再点 Run,不要默认 0Hz 去跑,那样收到的是噪声。二是日志窗口会输出溢出的警告信息,出现 "u" 提示时说明 USB 传输跟不上,把采样率从 2M 降到 1M 通常能解决。
4.3 FM 发射实例:WAV 文件到射频输出的上行信号链
发射实例的模块链是:Wav File Source → Multiply Const → WBFM Transmit → Rational Resampler → osmocom Sink。这条链路把磁盘上的 WAV 音频做窄带 FM 调制,重采样到 2M 采样率后交给 HackRF 的 DAC 发射出去。
| 模块 | 关键参数 | 推荐值 | 说明 |
|---|---|---|---|
| Wav File Source | File | 48kHz 采样率 WAV 文件 | 采样率越高,调制频谱越干净 |
| Multiply Const | Constant | 0.8 | 防止音频削波导致调制失真 |
| WBFM Transmit | Audio Rate | 48000 | 与 WAV 文件采样率匹配 |
| WBFM Transmit | Quadrature Rate | 200000 | 窄带 FM 调制后的符号率 |
| Rational Resampler | Decimation | 10 | 把 200kHz 升到 2MHz 给硬件用 |
| osmocom Sink | Ch0 Frequency | 与接收错开 5MHz 以上 | 避免收发同频段自激 |
发射链路不建议加 Throttle 模块,因为 osmocom Sink 本身是硬件时钟,有数据才发,没数据就等,天然起到限速作用。加了 Throttle 反而可能因为速率不匹配造成丢包,这也是新手最容易踩的坑。
发射实验前务必确认测试频率上没有在用的通信业务,14dBm 功率虽然不大,但近距离直射也能干扰到附近的同频接收设备。我一般会选一个本地完全空白的频点,天线远离显示器和其他设备,用手机或另一台 SDR 做远端的接收验证,而不是发完就在同一台电脑上看。
5. 避坑手册:驱动、DLL 与射频链路的典型问题
5.1 USB 枚举与驱动侧
现象 1:Zadig 下拉菜单里看不到 HackRF One 设备。打开 Zadig 时 HackRF 明明插在电脑上,但设备列表里只有系统自带的 USB 设备,找不到 HackRF 的条目。
原因:USB 枚举失败,或设备驱动被别的手动安装工具占用过,Zadig 无法识别设备 GUID。绝大多数情况是 USB 线质量问题或插在了前置面板、HUB 等供电不稳的接口上。
解决:先换一根短的数据线,直接插主板背板的 USB 口,拔掉其他 USB 设备减少总线压力。插好后按一下 HackRF 板上的复位按键再开 Zadig。如果之前装过其他驱动,先到设备管理器卸载未知设备,重新插拔后再试。这三个动作按顺序走,90% 的识别问题能解决。
现象 2:SDRSharp 里 Configure 窗口的增益滑块灰色不可拖动。点击 Configure 后,LNA Gain 和 VGA Gain 的滑块都是不可交互状态,怎么拖都没反应。
原因:启动顺序不对。SDRSharp 必须先点 Start 按钮让设备进入运行状态,再打开 Configure 配置增益,此时滑块才可操作。这是手册明确标注过的顺序约束,但界面没有任何提示,很容易忽略。
解决:先点 Start,再点 Configure 调整增益,调整完后点 Run 开始接收。如果想微调增益,需要先 Stop 再重新进 Configure,部分旧版本在运行中改增益不会生效。
5.2 编译与 DLL 侧
现象 3:VS2010 编译 libhackrf 报错「无法打开包括文件」或「无法解析的外部符号」。明明代码是从手册复制的,编译时却提示找不到头文件或库文件。
原因:包含目录和库目录配置路径与实际解压路径不一致,或 x86/64 平台选错。VS2010 工程默认是 32 位,如果库目录指向 MS64 下的 static 文件夹,链接时符号就没法解析。
解决:在工程属性 → VC++ 目录里重新指定包含目录和库目录,确认路径指向 MS32 而不是 MS64。另外检查附加依赖项里是否写全了 libhackrf.lib、libusb-1.0.lib、pthreadVC2.lib 三个文件名。最保险的做法是把两个依赖库的 .lib 文件直接复制到工程目录里再添加到依赖项,路径问题直接就消失了。
现象 4:编译出来的 exe 运行时弹窗提示找不到 pthreadVC2.dll。程序编译成功,双击运行却报缺 DLL,无法启动。
原因:DLL 搜索路径问题。pthreadVC2.dll 没有被复制到 exe 所在目录,系统搜索路径里也没有它。使用静态链接 pthread 可以规避,但手册给的是动态 DLL 方案,所以必须带这个文件。解决:把 pthreadVC2.dll 复制到 exe 所在的 Debug 目录,或复制到 C:\Windows\System32,两者选一即可,不要两处都放,避免版本混淆。
5.3 射频链路与配置侧
现象 5:gqrx 能启动,但频谱图是一条平线,完全看不到信号的起伏。任何频段都收不到信号,底噪也异常干净。
原因:HackRF 设备没有真正被 gqrx 接管,或采样率设置过高导致 USB 传输持续溢出。虚拟机上做 USB 直通时,这个现象尤其常见。
解决:先确认 gqrx 的 Input 设备选择的是 HackRF,而不是默认的 Airspy 之类。再把采样率降到 2M 并调整 IF/BB 增益到中间值。如果依然平线,关掉 gqrx,在终端跑hackrf_info看设备是否正常枚举,再用hackrf_transfer -r test.iq抓一段数据检查文件大小增长,从硬件层逐级排除。
现象 6:FM 发射实验中用另一台接收机收不到信号。发射链路搭建好后,接收端始终静默。
原因:发射功率只有 14dBm,也就是约 25mW,收发天线距离太近反而会因为近场效应让接收前端饱和,距离太远又信号太弱。另外天线如果接的是 GSM 频段天线,在 100MHz 附近谐振效率极低。
解决:先用另一台 HackRF 接收时设成相同的频率和调制方式,天线间距控制在 0.5 米到 1 米左右,不要贴在一起。确认开发板上的发射状态灯亮起,同时用频谱分析软件看是否有载波出现。如果载波都没有,回到 GNURadio 流图,检查 osmocom Sink 的 Gain 参数是否被设为 0。
6. 进阶验证技巧:用 hackrf_transfer 把收发链路跑通
图形工具链验证完毕后,再用命令行工具做一次回环测试,能把硬件链路和软件配置彻底分开。hackrf_transfer 是 libhackrf 自带的命令行收发工具,不需要写任何代码就能完成最基础的 IQ 数据收发。这套验证方法是我拿到任何一块 HackRF 板卡后的第一件事,比打开 gqrx 更直接,因为命令行工具的报错信息足够直白。
# 接收链路验证:配置频率 100MHz、采样率 8M、接收 800 万个采样后自动退出 hackrf_transfer -r rx.iq -f 100000000 -s 8000000 -n 8000000 -g 16 # 发射链路验证:把刚才抓到的 IQ 数据以相同参数循环发射 5 秒 hackrf_transfer -t rx.iq -f 100000000 -s 8000000 -g 14-r 指定接收文件名,-t 指定发射文件名,-f 是中心频率,-s 是采样率,-n 是采样数量,-g 是接收增益。发射端不设 -n 时默认循环发送直到手动终止。如果 -t 之前先跑过一次 -r,且文件大小正常增长,说明 ADC 和 USB 上行通路是通的;发射时在接收机上看到同频点有信号,说明 DAC 和射频放大通路也正常。
命令行验证通过后,再回 GNURadio 搭信号链,此时如果还出问题,就可以明确排除硬件本身的因素。发射实验做完后我一般会把频率恢复到 0 或关闭设备再拔线,避免板卡留在发射状态。从那以后我每次拿到新板卡都强制走一遍「hackrf_info 查固件 → gqrx 看底噪 → 命令行收发回环」的流程,整套下来十分钟,却能把「板子是不是好的」这个玄学问题彻底钉死。希望帮到你。
本文还有配套的精品资源,点击获取