GNU Radio:探索射频频谱的工具

作者:Eric Blossom

软件无线电是一种尽可能让代码接近天线的技术。它将无线电硬件问题转化为软件问题。软件无线电的根本特征是软件定义了发射的波形,软件解调了接收的波形。这与大多数无线电形成对比,在大多数无线电中,处理是通过模拟电路或模拟电路与数字芯片结合完成的。GNU Radio 是一个用于构建软件无线电的免费软件工具包。

软件无线电由于其创建可以动态变化的无线电的能力,从而为用户创造了新的选择,因此是无线电设计领域的一场革命。在基线水平上,软件无线电几乎可以完成传统无线电可以做的任何事情。令人兴奋的部分是软件为您提供的灵活性。在未来几年,我们将看到从大量固定功能设备向通用通信设备转变,而不是大量固定功能设备。想象一下,一个设备可以变成手机,并使用 GPRS、802.11 Wi-Fi、802.16 WiMax、卫星连接或当日新兴标准为您提供连接。您可以使用 GPS、GLONASS 或两者来确定您的位置。

也许最令人兴奋的是构建去中心化通信系统的潜力。如果您看看今天的系统,绝大多数是基于基础设施的。广播无线电和电视提供单向频道,受到严格监管,内容由少数组织控制。手机非常方便,但您的手机支持的功能由运营商的利益决定,而不是您的利益。

中心化系统限制了创新速度。我们可以从互联网中吸取一些教训,并将智能推向边缘。我们可以构建更智能的设备,而不是将手机视为二等公民,只有在基础设施到位且仅限于运营商认为值得的能力时才能使用。这些用户拥有的设备将生成网络。他们将在彼此之间创建网状网络,协商回程链路,并可以自由地发展新的解决方案、功能和应用。

框图

图 1 显示了软件无线电的典型框图。要理解无线电的软件部分,我们首先需要了解一些相关的硬件知识。查看图 1 中的接收路径,我们看到一个天线、一个神秘的射频前端、一个模数转换器 (ADC) 和一堆代码。模数转换器是连续模拟信号的物理世界与软件操作的离散数字样本世界之间的桥梁。

GNU Radio: Tools for Exploring the Radio Frequency Spectrum

图 1. 典型软件无线电框图

ADC 有两个主要特性:采样率和动态范围。采样率是 ADC 每秒测量模拟信号的次数。动态范围是指可以区分的最小和最大信号之间的差异;它是 ADC 数字输出中的位数和转换器设计的函数。例如,一个 8 位转换器最多可以表示 256 (28) 个信号电平,而一个 16 位转换器最多可以表示 65,536 个电平。一般来说,器件物理特性和成本会在采样率和动态范围之间造成权衡。

在我们深入研究软件之前,我们需要谈谈一点理论。1927 年,一位瑞典出生的物理学家和电气工程师哈里·奈奎斯特 (Harry Nyquist) 确定,为了避免从模拟到数字转换时的混叠,ADC 采样频率必须至少是感兴趣信号带宽的两倍。混叠是使西部老电影中的马车车轮看起来像在倒转的原因:电影摄像机的采样率不足以明确表示轮辐的位置。

假设我们处理的是低通信号——感兴趣的带宽从 0 到 fMAX 的信号,奈奎斯特准则规定我们的采样频率需要至少为 2 * fMAX。但是,如果我们的 ADC 以 20MHz 的频率运行,我们如何收听 92.1MHz 的广播 FM 广播?答案是射频前端。接收射频前端将其输入端出现的频率范围转换为其输出端的较低范围。例如,我们可以想象一个射频前端,它将 90-100MHz 范围内的信号转换为 0-10MHz 范围。

在大多数情况下,我们可以将射频前端视为一个黑盒子,只有一个控制,即要转换的输入范围的中心。作为一个具体的例子,我们成功使用的电缆调制解调器调谐器模块具有以下特性。它将频谱中以大约 50MHz 到 800MHz 为中心的 6MHz 频段转换为以 5.75MHz 为中心的输出范围。输出范围的中心频率称为中频或 IF。

在最简单-可能-有效类别中,射频前端可以完全消除。一位 GNU Radio 实验者通过将 100 英尺长的电线直接连接到他的 20M 采样/秒 ADC,收听了 AM 和短波广播。

转向软件

GNU Radio 提供了一个信号处理原语库以及将它们连接在一起的粘合剂。程序员通过创建一个图(如图论中的图)来构建无线电,其中节点是信号处理原语,边表示它们之间的数据流。信号处理原语是用 C++ 实现的。从概念上讲,原语处理从其输入端口流向其输出端口的无限数据流。原语的属性包括它们具有的输入和输出端口的数量以及流经每个端口的数据类型。最常用的类型是 short、float 和 complex。

有些原语只有输出端口或输入端口。这些在图中充当数据源和数据接收器。有从文件或 ADC 读取数据的源,以及写入文件、数模转换器 (DAC) 或图形显示器的接收器。GNU Radio 附带大约 100 个原语。编写新的原语并不困难。

图可以在 C++ 中构建和运行,但将所有内容粘合在一起的简单方法是使用 Python。清单 1 是 GNU Radio 的“Hello World”。它生成两个正弦波并将它们输出到声卡,一个在左声道,一个在右声道。

清单 1. Hello World(拨号音输出)

#!/usr/bin/env python

from GnuRadio import *

def build_graph ():
    sampling_freq = 32000
    ampl = 8192

    fg = gr_FlowGraph ()

    src0 = GrSigSourceS (
        sampling_freq, GR_SIN_WAVE, 350, ampl)

    src1 = GrSigSourceS (
        sampling_freq, GR_SIN_WAVE, 440, ampl)

    sink = GrAudioSinkS ()

    fg.connect (src0, sink)
    fg.connect (src1, sink)

    return fg

if __name__ == '__main__':
    fg = build_graph ()
    fg.start ()        # fork thread(s) and return
    raw_input ('Press Enter to quit: ')
    fg.stop ()

我们首先创建一个流程图来保存原语和它们之间的连接。两个正弦波由 GrSigSourceS 调用生成。S 后缀表示源生成 shorts 类型数据。一个正弦波的频率为 350Hz,另一个正弦波的频率为 440Hz。它们一起听起来像美国拨号音。

GrAudioSinkS 是一个接收器,它将其输入写入声卡。它以一个或两个 shorts 类型数据流作为输入。我们使用流程图的 connect 方法将三个原语连接在一起。构建图后,我们启动它。调用 start 会派生一个或多个线程来运行由图描述的计算,并立即将控制权返回给调用者。在本例中,我们只是等待任何击键。

完整的 FM 接收器

清单 2 显示了一个经过简化但完整的广播 FM 接收器。它包括射频前端的控制和所有必需的信号处理。此示例使用由电缆调制解调器调谐器和 20M 采样/秒模数转换器构建的射频前端。

清单 2. 简单广播 FM 接收器

#!/usr/bin/env python

# simple broadcast FM receiver

from GnuRadio import *

#
# return a gr_FlowGraph
#
def build_graph (IF_freq):
    input_rate = 20e6

    CFIR_decimate = 125
    RFIR_decimate = 5
    fm_demod_gain = 2200

    quad_rate = input_rate / CFIR_decimate
    audio_rate = quad_rate / RFIR_decimate

    volume = 1.0

    src = GrHighSpeedADCSourceS (input_rate)

    # compute FIR filter taps for channel selection
    channel_coeffs = \
      gr_firdes.low_pass (
        1.0,          # gain
        input_rate,   # sampling rate
        250e3,        # low pass cutoff freq
        8*100e3,      # width of trans. band
        gr_firdes.WIN_HAMMING)

    # input: short; output: complex
    chan_filter = \
      GrFreqXlatingFIRfilterSCF (CFIR_decimate,
                                 channel_coeffs,
                                 IF_freq)
    # input: complex; output: float
    fm_demod = \
      GrQuadratureDemodCF (volume * fm_demod_gain)

    # compute FIR filter taps for audio filter
    width_of_transition_band = audio_rate / 32
    audio_coeffs = \
      gr_firdes.low_pass (
        1.0,            # gain
        quad_rate,      # sampling rate
        audio_rate/2 - width_of_transition_band,
        width_of_transition_band,
        gr_firdes.WIN_HAMMING)

    # input: float; output: short
    audio_filter = \
      GrFIRfilterFSF (RFIR_decimate, audio_coeffs)

    final_sink = GrAudioSinkS ()

    fg = gr_FlowGraph ()

    fg.connect (src, chan_filter)
    fg.connect (chan_filter, fm_demod)
    fg.connect (fm_demod, audio_filter)
    fg.connect (audio_filter, final_sink)

    return fg

if __name__ == '__main__':

    # connect to RF front end
    rf_front_end = microtune_eval_board ()
    if not rf_front_end.board_present_p ():
        raise IOError, 'RF front end not found'

    # set gain and radio station frequency
    rf_front_end.set_AGC (300)
    rf_front_end.set_RF_freq (100.1e6)

    IF_freq = rf_front_end.get_output_freq ()
    fg = build_graph (IF_freq)
    fg.start ()        # fork thread(s) and return
    raw_input ('Press Enter to quit: ')
    fg.stop ()

与 Hello World 示例一样,我们构建一个图,将原语连接在一起并启动它。在本例中,我们的源是高速 ADC,GrHighSpeedADC。我们接下来使用 GrFreqXlatingFIRfilterSCF,这是一个有限脉冲响应 (FIR) 滤波器,它选择我们正在寻找的 FM 电台并将其转换为基带 (0Hz, DC)。使用 20M 采样/秒转换器和电缆调制解调器调谐器,我们实际上抓取了频谱中大约 6MHz 的一块。这单个块可能包含十个或更多 FM 电台,GrFreqXlatingFIRfilterSCF 允许我们选择我们想要的那个。在本例中,我们选择位于射频前端中频 (IF) 正中心的那个 (5.75MHz)。GrFreqXlatingFIRfilterSCF 的输出是每秒 160,000 个采样的复数样本流。我们将复数基带信号馈送到 GrQuadratureDemodCF,这是执行实际 FM 解调的模块。GrQuadratureDemodCF 的工作原理是减去每个相邻复数样本的角度,有效地对频率进行微分。GrQuadratureDemodCF 的输出包含左右声道之和的 FM 单声道音频信号、19kHz 的立体声导频音、以 38kHz 为中心的左右声道之差的立体声信息以及高于该频率的任何其他子载波。对于这个简化的接收器,我们最后对流进行低通滤波和抽取,仅保留左右声道之和的音频信息,并以每秒 32,000 个采样的速率将其发送到声卡。有关信号处理的讨论和教程,请参阅 GNU Radio Wiki。

图形用户界面

GNU Radio 应用程序的图形界面是在 Python 中构建的。可以使用您可以从 Python 访问的任何工具包构建界面;我们建议使用 wxPython 以最大限度地提高跨平台可移植性。GNU Radio 提供了使用进程间通信将数据块从实时 C++ 流程图传输到 Python 领域的原语。

硬件要求

GNU Radio 在硬件方面相当独立。如今的商品级多千兆赫兹、超标量 CPU 带有单周期浮点单元,这意味着在桌面上进行严肃的数字信号处理是可能的。一个 2GHz 的奔腾或速龙处理器可以评估每秒 20 亿个浮点 FIR 抽头。我们现在几乎可以在软件中构建几年前还无法想象的通信系统。

您的计算要求取决于您尝试做什么,但一般来说,一台 1 或 2GHz 的机器,至少配备 256MB 的 RAM 就足够了。您还需要某种方式将模拟世界连接到您的计算机。低成本选项包括内置声卡和发烧友级 96kHz、24 位附加卡。使用这些选项中的任何一个,您都只能处理相对窄带的信号,并且需要使用某种窄带射频前端。

另一种可能的解决方案是现成的、高速 PCI 模数转换板。这些板卡在 20M 采样/秒范围内可用,但它们很昂贵,大约相当于一台完整 PC 的成本。对于这些高速板卡,电缆调制解调器调谐器是合理的射频前端。

通用软件无线电外围设备

首选解决方案是通用软件无线电外围设备 (USRP)。图 2 显示了 USRP 的框图。USRP 是 Matt Ettus 的创意,它是一个非常灵活的 USB 设备,可将您的 PC 连接到射频世界。USRP 由一个小主板组成,该主板最多包含四个 12 位 64M 采样/秒 ADC、四个 14 位 128M 采样/秒 DAC、一个百万门现场可编程门阵列 (FPGA) 和一个可编程 USB 2.0 控制器。每个完全配置的 USRP 主板支持四个子板,两个用于接收,两个用于发射。射频前端在子板上实现。有各种各样的子板可用于处理不同的频段。对于业余无线电用途,有低功率子板可用,它们在 440MHz 频段和 1.24GHz 频段接收和发射。基于电缆调制解调器调谐器的接收专用子板可用,它覆盖从 50MHz 到 800MHz 的范围。子板设计为易于手工原型制作,以便于实验。

GNU Radio: Tools for Exploring the Radio Frequency Spectrum

图 2. 通用软件无线电外围设备 (USRP)

USRP 的灵活性来自板上的两个可编程组件及其与主机端库的交互。为了感受 USRP,让我们看看它的启动顺序。USRP 本身不包含基于 ROM 的固件,仅包含指定供应商 ID (VID)、产品 ID (PID) 和修订版的几个字节。当 USRP 首次插入 USB 时,主机端库会看到一个未配置的 USRP。它可以通过读取 VID、PID 和修订版来判断它是否未配置。库代码做的第一件事是下载定义 USB 外围控制器行为的 8051 代码。当此代码启动时,USRP 会模拟 USB 断开和重新连接。当它重新连接时,主机看到不同的设备:VID、PID 和修订版都不同了。现在运行的固件定义了 USB 端点、接口和命令处理程序。USB 控制器现在理解的命令之一是加载 FPGA。库代码在看到 USRP 作为新设备重新连接后,进入启动过程的下一阶段并下载 FPGA 配置位流。

FPGA 是通用硬件芯片,其行为由加载到其中的配置位流决定。您可以将位流视为目标代码。位流是编译设计的高级描述的输出。在我们的例子中,设计是用 Verilog 硬件描述语言编写的。这是源代码,并且像 GNU Radio 中的其余代码一样,根据 GNU 通用公共许可证获得许可。

FPGA 中有什么?

FPGA 就像一台小型的、大规模并行的计算机,您可以设计它来完全按照您的意愿执行操作。对 FPGA 进行编程需要一些技巧,并且错误可能会永久损坏电路板。也就是说,我们提供了一个标准配置,它适用于各种各样的应用。

使用良好的 USB 主机控制器,USRP 可以通过 USB 保持 32MB/秒的速率。USB 是半双工的。根据您的需要,您可以在发射和接收方向之间分配 32MB/秒的速率。在接收方向上,标准配置允许您选择您感兴趣的数字化频谱的部分或全部,将它们转换为基带并根据需要进行抽取。这与射频前端中发生的情况完全相同,只是现在我们在数字化样本上进行操作。执行此功能的代码块称为数字下变频器(图 3)。在数字域中执行此功能的一个优点是我们可以立即更改中心频率,这对于跳频扩频系统非常方便。

GNU Radio: Tools for Exploring the Radio Frequency Spectrum

图 3. 数字下变频器框图

在发射方向上,执行完全相反的操作。FPGA 包含数字上变频器和下变频器的多个实例。这些实例可以连接到相同或不同的 ADC,具体取决于您的需要。我们没有足够的空间在这里涵盖它们背后的所有理论;有关更多信息,请参阅 GNU Radio Wiki。

GNU Radio 应用

除了上面讨论的示例外,GNU Radio 还附带完整的 HDTV 发射器和接收器、频谱分析仪、示波器、并发多通道接收器以及不断增长的调制器和解调器集合。

正在调查或正在进行的项目包括

  • 用于无线电的 TiVo 等效物,能够同时录制多个电台。

  • 一种被动雷达系统,它利用广播电视作为其信号源。对于那些连接天线的老式电视机的人来说,想想当飞机飞过时你看到的抖动。

  • 射电天文学。

  • TETRA 收发器。

  • 数字世界广播 (DRM)。

  • 软件 GPS。

  • 分布式传感器网络。

  • 频谱利用率的分布式测量。

  • 业余无线电收发器。

  • Ad hoc 网状网络。

  • RFID 检测器/读取器。

  • 多输入多输出 (MIMO) 处理。

政治

每一次革命都有其政治问题。用于构建无线电的自由软件对某些人来说是麻烦的。在美国,我们遇到了美国电影协会的反对,以及他们试图通过广播标志来限制可以为无线数字电视构建的接收器类型。

美国联邦通信委员会发布了关于“认知无线电技术和软件定义无线电”的拟议规则制定通知 (NPRM)。NPRM 中提出了几个令人不安的问题,包括限制高速数模转换器的销售、对数字签名或类似方法的要求,以防止未经授权的软件进入软件无线电硬件,以及对为业余无线电市场构建的无线电的新限制。

总结

软件无线电是一个令人兴奋的领域,GNU Radio 提供了开始探索的工具。深入理解软件无线电需要来自多个领域的知识。我们正在尽最大努力降低入门门槛。

本文资源: /article/7497

Eric Blossom 是 GNU Radio 项目的创始人。在参与软件无线电之前,他多年从事安全电话业务。当他不进行软件无线电黑客攻击时,您很可能会发现他在练习瑜伽或柔术。可以通过 eb@comsec.com 与他联系。

加载 Disqus 评论