/cl-rust-adalm-pluto-glfw

visualize software defined radio with rust

Primary LanguageCommon LispOtherNOASSERTION

https://github.com/plops/cl-rust-adalm-pluto-glfw/blob/master/doc/2020-03-08-165218_1405x810_scrot.png?raw=true Screen recording: https://github.com/plops/cl-rust-adalm-pluto-glfw/blob/master/doc/screen_pluto-2020-03-08_16.48.32.mkv?raw=true

Introduction

Is code is an experiment in Rust. I tried to create a minimal GUI for the Adalm Pluto software defined radio.

Currently it reads IQ data and shows the FFT as a waterfall diagram. The frequency of the RX local oscillator can be changed with a slider.

This software requires the industrial-io crate which apparently only works in Linux.

A binary can be downloaded here: https://github.com/plops/cl-rust-adalm-pluto-glfw/releases/tag/first_useful_gui

It assumes you have a pluto connected as 192.168.2.1

Note: I actually didn’t write the code in Rust but in a language that resembles Common Lisp and is converted into Rust using this: https://github.com/plops/cl-rust-generator/

Getting repo and building from source

You’ll need Rust and cargo https://doc.rust-lang.org/cargo/getting-started/installation.html

Which apparently can be installed like this. Looks scary to me, be careful running a script from the web like this.

curl https://sh.rustup.rs -sSf | sh
git clone https://github.com/plops/cl-rust-adalm-pluto-glfw
cd cl-rust-adalm-pluto-glfw/code/
cargo run 

Architecture:

start a bunch of threads to form a pipeline

read adc data (this thread runs on an isolated processor (kernel param isolcpus=0,1), in the hope that this reduces drops) perform fft of block convert complex fft result into something that can be displayed

the pipeline threads run with crossbeam scope and can all access the memory memory contains a timestamp and an array threads talk to each other through bounded channels r0,s0,r1,s1 threads transmit a single number, indicating which array has been processed by this stage

at startup they all wait for the fft library to initialize with https://docs.rs/crossbeam/0.7.1/crossbeam/sync/struct.WaitGroup.html https://stjepang.github.io/2019/01/29/lock-free-rust-crossbeam-in-2019.html

the visualizer imgui is running simultaneously and occasionally (60fps) updates the texture with the waterfall fft with the output of the last stage

What settings we can change?

martin@labolg ~ $ ssh root@192.168.2.1
root@192.168.2.1's password: 
Welcome to:
______ _       _        _________________
| ___ \ |     | |      /  ___|  _  \ ___ \
| |_/ / |_   _| |_ ___ \ `--.| | | | |_/ /
|  __/| | | | | __/ _ \ `--. \ | | |    /
| |   | | |_| | || (_) /\__/ / |/ /| |\ \
\_|   |_|\__,_|\__\___/\____/|___/ \_| \_|

v0.31
http://wiki.analog.com/university/tools/pluto
# ls
# cd /sys/bus/iio/devices/
# ls
iio:device0  iio:device1  iio:device2  iio:device3  iio:device4
# cd iio\:device1/
# ls
calib_mode
calib_mode_available
dcxo_tune_coarse
dcxo_tune_coarse_available
  
  • we have 5 devices
  • each device has a few channels
  • each device has attributes
  • each channel has attributes
  • each device has a name
  • some channels have names

References:

datelinknote
https://users.rust-lang.org/t/sharing-buffer-between-threads-without-locking/10508
https://docs.rs/triple_buffer/5.0.4/triple_buffer/
https://medium.com/@polyglot_factotum/rust-concurrency-patterns-communicate-by-sharing-your-sender-11a496ce7791
https://wiki.analog.com/resources/tools-software/linux-software/libiio_internals
2017-03https://users.rust-lang.org/t/spmc-buffer-triple-buffering-for-multiple-consumers/10118
2017-11https://users.rust-lang.org/t/code-review-triplebuffer-for-sending-huge-objects-between-threads/13787/7
https://github.com/HadrienG2/triple-bufferconsumer is not in sync with producer
https://doc.rust-lang.org/book/ch16-02-message-passing.html
https://stjepang.github.io/2019/01/29/lock-free-rust-crossbeam-in-2019.htmlscoped thread, atomic cell
https://users.rust-lang.org/t/how-can-i-allocate-aligned-memory-in-rust/33293std::slice::from_raw_parts[_mut]
https://users.rust-lang.org/t/solved-how-to-move-non-send-between-threads-or-an-alternative/19928
2015imgui-rs/imgui-rs#7string handling in imgui

How to build release:

optimzed for latency

   RUSTFLAGS="-C target-cpu=native -C llvm-args=-cost-kind=latency" cargo build --release
cargo run --release

optimized for size

https://github.com/johnthagen/min-sized-rust

check with https://github.com/RazrFalcon/cargo-bloat

largest crates

    RUSTFLAGS="-C target-cpu=native -C llvm-args=-cost-kind=latency" cargo bloat --release --crates

   Compiling code v0.1.0 (/home/martin/stage/cl-rust-adalm-pluto-glfw/code)
    Finished release [optimized] target(s) in 1m 12s
    Analyzing target/release/code

 File  .text     Size Crate
32.2%  61.2%   1.0MiB [Unknown]
 4.6%   8.7% 151.9KiB imgui_sys
 4.1%   7.9% 137.5KiB std
 2.0%   3.9%  67.9KiB glfw
 1.7%   3.2%  56.4KiB code
 1.3%   2.4%  42.6KiB gl
 1.1%   2.1%  36.9KiB rustc_demangle
 1.0%   1.9%  32.9KiB fftw_src
 0.9%   1.7%  30.2KiB imgui_opengl_renderer
 0.9%   1.6%  28.3KiB crossbeam_channel
 0.7%   1.2%  21.7KiB crossbeam_utils
 0.5%   1.0%  16.9KiB backtrace
 0.5%   0.9%  15.4KiB backtrace_sys
 0.2%   0.3%   5.2KiB parking_lot_core
 0.1%   0.2%   2.8KiB parking_lot
 0.1%   0.2%   2.6KiB industrial_io
 0.1%   0.1%   2.2KiB chrono
 0.1%   0.1%   2.0KiB rand_os
 0.0%   0.1%   1.6KiB rand_jitter
 0.0%   0.0%     720B rand_core
 0.1%   0.1%   1.8KiB And 6 more crates. Use -n N to show more.
52.5% 100.0%   1.7MiB .text section size, the file size is 3.2MiB

Note: numbers above are a result of guesswork. They are not 100% correct and never will be.

largest functions

    RUSTFLAGS="-C target-cpu=native -C llvm-args=-cost-kind=latency" cargo bloat --release -n 10

    Finished release [optimized] target(s) in 0.05s
    Analyzing target/release/code

 File  .text    Size                 Crate Name
 1.3%   2.4% 42.5KiB                    gl gl::load_with::inner
 0.9%   1.7% 30.1KiB imgui_opengl_renderer imgui_opengl_renderer::gl::Gl::load_with
 0.9%   1.7% 28.9KiB                  code code::main::{{closure}}::{{closure}}
 0.8%   1.6% 27.5KiB             [Unknown] t2_64
 0.8%   1.5% 26.0KiB                  code code::main
 0.7%   1.4% 23.6KiB             [Unknown] hb_64
 0.7%   1.3% 23.0KiB             [Unknown] t1_64
 0.7%   1.3% 22.3KiB             [Unknown] hf_64
 0.6%   1.1% 18.9KiB             [Unknown] r2cf_128
 0.6%   1.1% 18.8KiB             [Unknown] r2cb_128
44.1%  83.9%  1.4MiB                       And 2269 smaller methods. Use -n N to show more.
52.5% 100.0%  1.7MiB                       .text section size, the file size is 3.2MiB


bloaty output

    martin@labolg ~/stage/cl-rust-adalm-pluto-glfw/code/target/release $ bloaty code
     VM SIZE                       FILE SIZE
 --------------                 --------------
  72.3%  1.70Mi .text            1.70Mi  52.5%
   9.7%   234Ki .rodata           234Ki   7.1%
   0.0%       0 .debug_str        233Ki   7.0%
   0.0%       0 .debug_info       232Ki   7.0%
   5.6%   135Ki .bss                  0   0.0%
   0.0%       0 .strtab           125Ki   3.8%
   0.0%       0 .debug_ranges     118Ki   3.6%
   0.0%       0 .debug_line       108Ki   3.3%
   4.4%   106Ki .eh_frame         106Ki   3.2%
   0.0%       0 .symtab           101Ki   3.1%
   3.9%  93.6Ki .rela.dyn        93.6Ki   2.8%
   0.0%       0 .debug_pubnames  63.2Ki   1.9%
   1.9%  45.0Ki .data.rel.ro     45.3Ki   1.4%
   0.0%       0 .debug_pubtypes  37.5Ki   1.1%
   0.7%  16.2Ki [Other]          20.8Ki   0.6%
   0.7%  17.7Ki .eh_frame_hdr    17.7Ki   0.5%
   0.6%  14.2Ki .data            14.2Ki   0.4%
   0.0%       0 .debug_aranges   8.00Ki   0.2%
   0.3%  6.16Ki .dynsym          6.16Ki   0.2%
   0.0%       0 .debug_frame     4.89Ki   0.1%
   0.0%      54 [Unmapped]       4.05Ki   0.1%
 100.0%  2.36Mi TOTAL            3.24Mi 100.0%

martin@labolg ~/stage/cl-rust-adalm-pluto-glfw/code/target/release $ bloaty code_stripped
     VM SIZE                      FILE SIZE
 --------------                --------------
  72.3%  1.70Mi .text           1.70Mi  76.4%
   9.7%   234Ki .rodata          234Ki  10.3%
   5.6%   135Ki .bss                 0   0.0%
   4.4%   106Ki .eh_frame        106Ki   4.7%
   3.9%  93.6Ki .rela.dyn       93.6Ki   4.1%
   1.9%  45.0Ki .data.rel.ro    45.3Ki   2.0%
   0.7%  17.7Ki .eh_frame_hdr   17.7Ki   0.8%
   0.6%  14.2Ki .data           14.2Ki   0.6%
   0.3%  6.16Ki .dynsym         6.16Ki   0.3%
   0.0%      54 [Unmapped]      4.05Ki   0.2%
   0.2%  3.84Ki .dynstr         3.84Ki   0.2%
   0.2%  3.73Ki .rela.plt       3.73Ki   0.2%
   0.1%  2.61Ki .got            2.61Ki   0.1%
   0.0%     736 [ELF Headers]   2.59Ki   0.1%
   0.1%  2.50Ki .plt            2.50Ki   0.1%
   0.0%     634 [Other]           1022   0.0%
   0.0%     608 .dynamic           608   0.0%
   0.0%     526 .gnu.version       526   0.0%
   0.0%     424 .tbss                0   0.0%
   0.0%     400 .gnu.version_r     400   0.0%
   0.0%     332 .gnu.hash          332   0.0%
 100.0%  2.36Mi TOTAL           2.23Mi 100.0%

martin@labolg ~/stage/cl-rust-adalm-pluto-glfw/code/target/release $ ldd code_stripped
	linux-vdso.so.1 (0x00007ffcf098e000)
	libiio.so.0 => /usr/lib64/libiio.so.0 (0x00007f5a2d333000)
	libX11.so.6 => /usr/lib64/libX11.so.6 (0x00007f5a2d1f1000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f5a2d1eb000)
	libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/libstdc++.so.6 (0x00007f5a2cf6e000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5a2cf4a000)
	libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/libgcc_s.so.1 (0x00007f5a2cf30000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f5a2cd58000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f5a2cc17000)
	librt.so.1 => /lib64/librt.so.1 (0x00007f5a2cc0d000)
	libusb-1.0.so.0 => /lib64/libusb-1.0.so.0 (0x00007f5a2cbf1000)
	libxml2.so.2 => /usr/lib64/libxml2.so.2 (0x00007f5a2ca84000)
	libz.so.1 => /lib64/libz.so.1 (0x00007f5a2ca6a000)
	libicui18n.so.65 => /usr/lib64/libicui18n.so.65 (0x00007f5a2c776000)
	libicuuc.so.65 => /usr/lib64/libicuuc.so.65 (0x00007f5a2c593000)
	libicudata.so.65 => /usr/lib64/libicudata.so.65 (0x00007f5a2aae0000)
	libxcb.so.1 => /usr/lib64/libxcb.so.1 (0x00007f5a2aab4000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f5a2d5d3000)
	libXau.so.6 => /usr/lib64/libXau.so.6 (0x00007f5a2aaaf000)
	libXdmcp.so.6 => /usr/lib64/libXdmcp.so.6 (0x00007f5a2aaa5000)
	libbsd.so.0 => /usr/lib64/libbsd.so.0 (0x00007f5a2aa8b000)

On Reducing lag:

String handling in imgui