Navigate from the COSMOS sb1 console to a USRP 2974 SDR, detect it via PCIe (RIO0), and run a spectrum-visualization application to read and display IQ samples in a browser.
This tutorial walks through the basic steps to access a USRP 2974 ("Krypton") software-defined radio on COSMOS Sandbox 1, verify that the PCIe driver is active and the radio is detected via UHD, then compile and launch the spectrum_view application — a WebSocket server that streams spectrum samples to a browser-based client over an SSH tunnel.
The USRP 2974 is an NI-integrated platform where the X310 FPGA radio is connected to an embedded PC via PCIe (accessed as RIO0) rather than Ethernet. This tutorial introduces the PCIe/RFNoC access path and the UBX-TDD daughterboard's 10–6000 MHz frequency range.
By the end you will have confirmed radio detection, compiled the sample application, and viewed a live spectrum display for a band of your choice (the default is the 2.4 GHz Wi-Fi band).
After completing this tutorial you will be able to:
niusrprio) driver is active and detect the radio with uhd_find_devices --args="type=x300" and uhd_usrp_probe.spectrum_view application and its WebSocket dependency from source.| Difficulty | Beginner |
| Estimated time | 60 min |
| Domain / sandbox | sb1.cosmos-lab.org |
| Topic group | Getting Started |
| Last verified | Not re-tested (migrated 2026-06-20) |
Background knowledge
Account & access
Devices / nodes
| Resource | Role | Qty | Notes |
|---|---|---|---|
| sdr2-s1-lg1 | SDR host (USRP 2974 / Krypton) | 1 | USRP 2974 connected via PCIe (RIO0); UBX-TDD daughterboard, 10–6000 MHz |
Disk images
| Image | Load onto | Provides |
|---|---|---|
| baseline-sdr.ndz | sdr2-s1-lg1 | UHD 3.15, PCIe driver (niusrprio), build tools |
Software components
| Component | Version | Source |
|---|---|---|
| UHD (USRP Hardware Driver) | 3.15.0 (as shown in probe output) | preinstalled in baseline-sdr.ndz |
| niusrprio kernel module | TODO: verify | preinstalled in baseline-sdr.ndz; managed via systemctl restart niusrprio.service |
| spectrum_view application | TODO: verify | downloaded from wiki attachment (see Instructions) |
| libboost (program-options, system, thread, filesystem, regex) | TODO: verify | installed via apt during build |
| liblog4cxx, cmake, libfftw3, libxml2, libpopt, libsqlite3 | TODO: verify | installed via apt during build |
Spectrum / RF / special
The USRP 2974 on sb1 is an over-the-air capable radio. The tutorial's default configuration targets the 2.4 GHz Wi-Fi band (FREQ=2400e6, RATE=25e6, GAIN=30). Stay within your reservation's allowed spectrum and power limits.
One node (sdr2-s1-lg1) on Sandbox 1 hosts an NI USRP 2974. The X310 FPGA is connected to the node's embedded PC via PCIe and appears as RIO0 in UHD. The spectrum_view application runs a WebSocket server on port 9002 of the node. A browser-based client on your desktop connects through an SSH tunnel: localhost:5002 → sdr2-s1-lg1.sb1.cosmos-lab.org:9002.
Sign up for a COSMOS account.
Create a resource reservation for sandbox 1 and wait for it to be approved.
Once the reservation is confirmed, log into the console:
ssh <username>@console.sb1.cosmos-lab.org
Load the baseline-sdr.ndz image onto the node:
omf load -i baseline-sdr.ndz -t sdr2-s1-lg1
Once imaging is complete, turn the node on and verify its status:
omf tell -a on -t sdr2-s1-lg1
omf stat -t sdr2-s1-lg1
From your local machine (not the console), open an SSH tunnel so the browser client can reach the node's WebSocket server:
ssh -L 5002:sdr2-s1-lg1.sb1.cosmos-lab.org:9002 <username>@console.sb1.cosmos-lab.org
See SSH tunnel setup for full instructions.
After giving the node time to boot, SSH into it from the console:
ssh root@sdr2-s1-lg1
The USRP 2974 uses a PCIe driver (niusrprio) to control the X310 FPGA from the embedded PC. In the provided images this driver loads automatically on boot. If there are issues, restart it manually:
systemctl restart niusrprio.service
Run uhd_find_devices filtering for the PCIe-connected X310:
root@sdr2-s1-lg1:~# uhd_find_devices --args="type=x300"
[INFO] [UHD] linux; GNU C++ version 7.5.0; Boost_106501; UHD_3.15.0.HEAD-0-gaea0e2de
--------------------------------------------------
-- UHD Device 0
--------------------------------------------------
Device Address:
serial: 3171336
fpga: HG
name:
product: X310
resource: RIO0
type: x300
The output lists the detected X310. resource: RIO0 confirms the PCIe path. If no device is found, see Troubleshooting.
Probe the radio for detailed capability information. Specifying resource=rio0 ensures only the directly connected radio is probed (not any network-connected radios):
root@sdr2-s1-lg1:~# uhd_usrp_probe --args="resource=rio0,type=x300"
[INFO] [UHD] linux; GNU C++ version 7.5.0; Boost_106501; UHD_3.15.0.HEAD-0-gaea0e2de
[INFO] [X300] X300 initialization sequence...
[INFO] [X300] Connecting to niusrpriorpc at localhost:5444...
[INFO] [X300] Using LVBITX bitfile /usr/local/share/uhd/images/usrp_x310_fpga_HG.lvbitx
[INFO] [X300] Radio 1x clock: 200 MHz
[INFO] [GPS] Found an internal GPSDO: LC_XO, Firmware Rev 0.929b
[INFO] [0/DmaFIFO_0] Initializing block control (NOC ID: 0xF1F0D00000000000)
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1311 MB/s)
[INFO] [0/DmaFIFO_0] BIST passed (Throughput: 1303 MB/s)
[INFO] [0/Radio_0] Initializing block control (NOC ID: 0x12AD100000000001)
[INFO] [0/Radio_1] Initializing block control (NOC ID: 0x12AD100000000001)
[INFO] [0/DDC_0] Initializing block control (NOC ID: 0xDDC0000000000000)
[INFO] [0/DDC_1] Initializing block control (NOC ID: 0xDDC0000000000000)
[INFO] [0/DUC_0] Initializing block control (NOC ID: 0xD0C0000000000000)
[INFO] [0/DUC_1] Initializing block control (NOC ID: 0xD0C0000000000000)
_____________________________________________________
/
| Device: X-Series Device
| _____________________________________________________
| /
| | Mboard: NI-2974
| | revision: 12
| | revision_compat: 7
| | product: 31131
| | mac-addr0: 00:80:2f:26:08:92
| | mac-addr1: 00:80:2f:26:08:93
| | gateway: 192.168.10.1
| | ip-addr0: 192.168.10.2
| | subnet0: 255.255.255.0
| | ip-addr1: 192.168.20.2
| | subnet1: 255.255.255.0
| | ip-addr2: 192.168.30.2
| | subnet2: 255.255.255.0
| | ip-addr3: 192.168.40.2
| | subnet3: 255.255.255.0
| | serial: 3171336
| | FW Version: 6.0
| | FPGA Version: 36.0
| | FPGA git hash: fde2a94
| | RFNoC capable: Yes
| |
| | Time sources: internal, external, gpsdo
| | Clock sources: internal, external, gpsdo
| | Sensors: gps_gpgga, gps_gprmc, gps_time, gps_locked, gps_servo, ref_locked
| | _____________________________________________________
| | /
| | | RX Dboard: A
| | | ID: UBX-TDD (0x0203)
| | | Serial: 318D9DE
| | | _____________________________________________________
| | | /
| | | | RX Frontend: 0
| | | | Name: UBX RX
| | | | Antennas: TX/RX, RX2, CAL
| | | | Sensors: lo_locked
| | | | Freq range: 10.000 to 6000.000 MHz
| | | | Gain range PGA0: 0.0 to 31.5 step 0.5 dB
| | | | Bandwidth range: 160000000.0 to 160000000.0 step 0.0 Hz
| | | | Connection Type: IQ
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | RX Codec: A
| | | | Name: ads62p48
| | | | Gain range digital: 0.0 to 6.0 step 0.5 dB
| | _____________________________________________________
| | /
| | | RX Dboard: B
| | | ID: UBX-TDD (0x0203)
| | | Serial: 318D9EF
| | | _____________________________________________________
| | | /
| | | | RX Frontend: 0
| | | | Name: UBX RX
| | | | Antennas: TX/RX, RX2, CAL
| | | | Sensors: lo_locked
| | | | Freq range: 10.000 to 6000.000 MHz
| | | | Gain range PGA0: 0.0 to 31.5 step 0.5 dB
| | | | Bandwidth range: 160000000.0 to 160000000.0 step 0.0 Hz
| | | | Connection Type: IQ
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | RX Codec: B
| | | | Name: ads62p48
| | | | Gain range digital: 0.0 to 6.0 step 0.5 dB
| | _____________________________________________________
| | /
| | | TX Dboard: A
| | | ID: UBX-TDD (0x0202)
| | | Serial: 318D9DE
| | | _____________________________________________________
| | | /
| | | | TX Frontend: 0
| | | | Name: UBX TX
| | | | Antennas: TX/RX, CAL
| | | | Sensors: lo_locked
| | | | Freq range: 10.000 to 6000.000 MHz
| | | | Gain range PGA0: 0.0 to 31.5 step 0.5 dB
| | | | Bandwidth range: 160000000.0 to 160000000.0 step 0.0 Hz
| | | | Connection Type: QI
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | TX Codec: A
| | | | Name: ad9146
| | | | Gain Elements: None
| | _____________________________________________________
| | /
| | | TX Dboard: B
| | | ID: UBX-TDD (0x0202)
| | | Serial: 318D9EF
| | | _____________________________________________________
| | | /
| | | | TX Frontend: 0
| | | | Name: UBX TX
| | | | Antennas: TX/RX, CAL
| | | | Sensors: lo_locked
| | | | Freq range: 10.000 to 6000.000 MHz
| | | | Gain range PGA0: 0.0 to 31.5 step 0.5 dB
| | | | Bandwidth range: 160000000.0 to 160000000.0 step 0.0 Hz
| | | | Connection Type: QI
| | | | Uses LO offset: No
| | | _____________________________________________________
| | | /
| | | | TX Codec: B
| | | | Name: ad9146
| | | | Gain Elements: None
| | _____________________________________________________
| | /
| | | RFNoC blocks on this device:
| | |
| | | * DmaFIFO_0
| | | * Radio_0
| | | * Radio_1
| | | * DDC_0
| | | * DDC_1
| | | * DUC_0
| | | * DUC_1
The probe confirms two UBX-TDD daughterboards (channels A and B), each covering 10–6000 MHz, and RFNoC capability. Detailed driver installation and firmware update instructions are on the Krypton usage page.
Return to the console session (username@console). Download the application source archive and copy it to the node:
username@console:~$ wget https://wiki.cosmos-lab.org/raw-attachment/wiki/Tutorials/Wireless/BasicUsage/spectrum_view.tar.gz
username@console:~$ scp spectrum_view.tar.gz root@sdr2-s1-lg1:~/
On the node, extract the archive:
root@sdr2-s1-lg1:~# tar -zxvf spectrum_view.tar.gz
root@sdr2-s1-lg1:~# cd SPECTRUM_VIEW
Install the required build dependencies:
root@sdr2-s1-lg1:~/SPECTRUM_VIEW# apt update
root@sdr2-s1-lg1:~/SPECTRUM_VIEW# apt-get -y install libboost-program-options-dev libboost-system-dev libboost-thread-dev libboost-filesystem-dev libboost-regex-dev liblog4cxx-dev cmake libfftw3-dev libxml2-dev libpopt-dev libsqlite3-dev pkg-config libxml2-utils gnulib
Build the WebSocket library:
root@sdr2-s1-lg1:~/SPECTRUM_VIEW# make websock
Build the main application (produces the app_read_sdr_samples executable):
root@sdr2-s1-lg1:~/SPECTRUM_VIEW# make
Refer to the README file in the SPECTRUM_VIEW directory for additional build details.
Start the application. It listens for configuration commands on port 5180 and streams spectrum samples to browser clients via a WebSocket server on port 9002:
root@sdr2-s1-lg1:~/SPECTRUM_VIEW# ./app_read_sdr_samples
. INFO 21:17:51.808 (main.cpp:649) - Starting command server at 5180
INFO 21:17:51.808 (main.cpp:171) - Starting websock server at 9002
.....
Leave this running in the SSH session.
Download the spectrum_view.zip client package to your local machine spectrum_view.zip and unzip it. Open spectrum_view.html in a Chrome browser.
When first opened, the viewer looks similar to this:

Set the localhost field to localhost:5002. (This reaches the node's WebSocket server through the SSH tunnel you created in Setup step 6, which maps localhost:5002 → sdr2-s1-lg1.sb1.cosmos-lab.org:9002.)
Set the device type field to type=x300.
Click Connect once. The app_read_sdr_samples terminal on the node should log a "Websocket Connection" message.
Click make to create a device handle.
The RF parameter fields are pre-populated with defaults for the 2.4 GHz Wi-Fi band:
| RF Parameter | Value | Description |
|---|---|---|
| RATE | 25e6 | Sampling rate (Hz) |
| FREQ | 2400e6 | Center frequency (Hz) |
| GAIN | 30 | Receive gain (dB) |
To observe a different band, change RATE, FREQ, and GAIN accordingly, then click Submit to push the settings to the SDR.
Click the Halted button to begin streaming. If the spectrum display appears, the full pipeline is working.

uhd_find_devices --args="type=x300" returns a device with resource: RIO0 and the correct serial.uhd_usrp_probe --args="resource=rio0,type=x300" shows UBX-TDD daughterboards on both A and B slots, frequency range 10–6000 MHz, and RFNoC capable: Yes.app_read_sdr_samples logs the command server (5180) and WebSocket server (9002) starting without errors.omf tell -a offh -t sdr2-s1-lg1
No omf save is needed unless you modified the image (e.g., installed additional packages you want to keep).
| Symptom | Likely cause | Fix |
|---|---|---|
uhd_find_devices returns no devices |
PCIe driver (niusrprio) not loaded or failed |
Run systemctl restart niusrprio.service; retry uhd_find_devices |
uhd_usrp_probe hangs or fails |
FPGA firmware mismatch | See the Krypton usage page firmware update section |
| Browser viewer cannot connect | SSH tunnel not established or wrong port | Confirm tunnel is running (localhost:5002 → sdr2-s1-lg1:9002); check app_read_sdr_samples is still running on the node |
| Spectrum viewer shows no signal / blank display | Wrong FREQ/RATE or SDR not streaming | Click Halted again to toggle; verify RF parameters and click Submit before streaming |
apt-get install fails during build |
Package names differ on the installed OS version | Check apt-cache search <package> for the correct name on the node's distribution |
For additional troubleshooting (firmware updates, PCIe errors), refer to the Krypton usage page.
Author(s): COSMOS team · Last verified: Not re-tested (migrated 2026-06-20) · Tested image/release: baseline-sdr.ndz / TODO: verify · Tags: sdr, uhd, usrp2974, krypton, x310, rfnoc, spectrum