Cross-compiled gr-limesdr

Hello, thanks for the answer.
I did as you said, and I found it.
/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/gnuradio-companion
So I will install gr-limesdr on /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/ to see if it works.

My problem is that it is trying to use a python3 path that does not exist.
I have seen all the CMakeLists.txt but it does not say how it chooses that path.
I am trying to add the PYTHON_LIBRARIES and PYTHON_INCLUDE_DIRS on the Toolchain, but it doesn’t work for now.

Sorry, I can only approximate, because I do not know your exact layout or the exact names of things or how doing a cross compile affects things, but as a best guess you need something like -

set PYTHONPATH to

/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/lib/python3/dist-packages

cmake \

-DPYTHON_LIBRARY=/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/lib/libpython3.8.so
-DPYTHON_EXECUTABLE=/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/python3
-DPYTHON_INCLUDE_DIR=/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/include/python3.8
-DCMAKE_INSTALL_PREFIX=/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/

put in the correct names of the items and you should be ready to go. This worked on an install of gnuradio with one addition parameter.

Hello, I did cmake -DPYTHON_LIBRARY=/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/lib/libpython3.7m.so -DPYTHON_EXECUTABLE=/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/python3 -DCMAKE_INSTALL_PREFIX=/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/ …/

But the python still says this:
– User set python executable /opt/pkg/zynq-7010/build/tmp/work/cortexa9t2hf-neon-xilinx-linux-gnueabi/gnuradio/3.8.2.0-r0/recipe-sysroot-native/usr/bin/python3-native/python3
– Found PythonInterp: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/python3
– Could NOT find PythonLibs (missing: PYTHON_INCLUDE_DIRS) (Required is exact version “.”)
/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/python3: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/python3: cannot execute binary file

I cannot change the python executable using that, I don’t know why. Still I get the “cannot execute binary file” and I don’t know why. That’s what I should get if I was compiling for ubuntu, because that python is for ARM.

I managed to change the PythonInterp and the python executable. I edited the path directly on GnuradioConfig.cmake and GrPython.cmake.
Now I get the error:

– User set python executable /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/python3
– Found PythonInterp: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/python3
– Could NOT find PythonLibs (missing: PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS) (Required is exact version “.”)
/opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/python3: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/bin/python3: cannot execute binary file

I have doubts about which python I have to use. The one from the SDK (ARM) or the one from my system.

I looked into it a little -

It says that you should be using “python 2.7.5”

It also says that you need to be using a real version of “bash” or their scripts will not work.

In the “simple-way-to-compile” thread the last few steps of building a c program are -

$ export CC=aarch64-xilinx-linux-gcc -fuse-ld=bfd
$ export LD=aarch64-xilinx-linux-ld.bfd
$ make

You will also need a “export CXX” command.

If that actually sets the environment correctly then -

cd build
cmake …/
make -j 8

would be all that you need to cross compile LimeSuite for PetaLinux.

The reference manual gives you recommended ways to install libraries and applications.

2 Likes

@rodrirq I did suggest back in May that this is less of a Lime Suite problem and more of a Petalinux/cross-compilation one, with Xilinx and their community likely being a far better place to seek answers :slight_smile: In any case, thanks for looking it up, @RightHalfPlane.

Thanks for the answer and the research.
I have already cross-compiled LimeSuite. The one giving problems is gr-limesdr.
I can’t do those steps because PetaLinux SDK has its own cross-compiler, and as I got gnuradio from meta-sdr using that compiler, if I use a different one they won’t be compatible.
Now my problem is that, even after setting the correct python path, it says “cannot execute binary file” and I don’t know why.
@andrewback I just keep posting here because @RightHalfPlane kept answering even when the problem changed to be a cross-compiled one. I also ask about this on the Xilinx forum, but we still haven’t reached the solution. I just hope it is not bothersome since it is about the gr-limesdr. Maybe someone will come here looking for the same answer.

I hope this is one of the last posts I make regarding this topic.
I finally did it.
I will sum up all I did to make it work.
I had to add the path to LimeSuite by myself.
Modify some .cmake in order to change the python path.
I was using the executable from /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/ instead of /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/
I modified the GnuradioConfig.cmake changing the PYTHON_EXECUTABLE to /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/python3.
I added the PYTHON_EXECUTABLE to GrPython.cmake to /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/python3. I added this line just before the if(PYTHON_EXECUTABLE).
I hope if someone has the same problem, this thread will be of help.
Thank you so much @RightHalfPlane for your help.
This is the output from the cmake that made the program compile.

– Toolchain file defaulted to ‘/opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/share/cmake/OEToolchainConfig.cmake’
– The CXX compiler identification is GNU 9.2.0
– The C compiler identification is GNU 9.2.0
– Check for working CXX compiler: /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/arm-xilinx-linux-gnueabi/arm-xilinx-linux-gnueabi-g++
– Check for working CXX compiler: /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/arm-xilinx-linux-gnueabi/arm-xilinx-linux-gnueabi-g++ – works
– Detecting CXX compiler ABI info
– Detecting CXX compiler ABI info - done
– Detecting CXX compile features
– Detecting CXX compile features - done
– Check for working C compiler: /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/arm-xilinx-linux-gnueabi/arm-xilinx-linux-gnueabi-gcc
– Check for working C compiler: /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/arm-xilinx-linux-gnueabi/arm-xilinx-linux-gnueabi-gcc – works
– Detecting C compiler ABI info
– Detecting C compiler ABI info - done
– Detecting C compile features
– Detecting C compile features - done
– Build type not specified: defaulting to release.
– Found LOG4CPP: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/lib/liblog4cpp.so
– Found PkgConfig: /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/pkg-config (found version “0.29.2”)
– Checking for module ‘gmp’
– No package ‘gmp’ found
– Found GMP: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/lib/libgmpxx.so
– Checking for module ‘mpir >= 3.0’
– No package ‘mpir’ found
– Could NOT find MPIR (missing: MPIRXX_LIBRARY MPIR_LIBRARY MPIR_INCLUDE_DIR)
– Found MPLIB: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/lib/libgmpxx.so
– Found Boost: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/lib/cmake/Boost-1.71.0/BoostConfig.cmake (found suitable version “1.71.0”, minimum required is “1.71.0”) found components: date_time program_options filesystem system regex thread
– Found VOLK: Volk::volk
– User set python executable /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/python3
– Found PythonInterp: /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/python3 (found version “3.7.6”)
– Found PythonLibs: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/lib/libpython3.7m.so (found suitable exact version “3.7.6”)
– Found Git: /usr/bin/git
– Extracting version information from git describe…
– LimeSuite version 20.10.0-g1480bfea found.
– Found Doxygen: /usr/bin/doxygen (found version “1.8.13”) found components: doxygen missing components: dot
– Using install prefix: /usr/local
– Building for version: 3.1.5.0 / 3.1.5
– No C++ unit tests… skipping
– Checking for module SWIG
– Found SWIG version 3.0.12.
– Found SWIG: /opt/pkg/sdk/sysroots/x86_64-petalinux-linux/usr/bin/swig2.0
– Found PythonLibs: /opt/pkg/sdk/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi/usr/lib/libpython3.7m.so (found version “3.7.6”)
– Configuring done
– Generating done
– Build files have been written to: /home/rodrirq/gr-limesdr/build

(I was going to post this about 4 weeks ago, but got distracted by other stuff, probably not useful posting now, but may help someone else in the future)

So the board has 1 GiB of RAM and dual 666.66MHz ARMv7-A cores. And everything is 32-bit which makes sense since ARMv7 does not support 64-bit. So to squeeze performance out of this board your application needs to be multi-threaded. Threading is supported by LiquidDSP, so there is that.

There were some LiquidDSP threading benchmarks done on three RPi boards:
Raspberry Pi 1 Model B+ (700 MHz ARMv6 with 512MiB RAM)
Raspberry Pi 2 Model B (overclocked to 1200 MHz ARMv7 with 1 GiB RAM)
Raspberry Pi 3 Model B (1.2GHz ARMv8 with 1 GiB RAM)

And at a guess your board would roughly end up close in performance to about 25% of number crunching ability of a RPi2B (quad core ARMv7 overclocked to 1200 MHz) or close to 200% the performance of a RPi1B+ (single core ARMv6 clocked at 700 MHz, but only because it had hardware support for floating point operations VFPv2, which was unusual for an ARMv6 CPU). Both assume that the application will use threads to maximise performance. Possibly one dealing with transferring data to the USB bus one one dealing with modulation.

You could try and extrapolate from the above benchmarks, and attempt workout a maximum theoretical throughput possible with your desired hardware platform. But there are so many variables. If you plan on sending full duplex data across a half-duplex USB 2.0 HS port, you will probably get half of what you would expect. Or if you plan to offload most of the DSP heavy lifting in parallel to custom gateware in the Xilinx Zynq FPGA, you may boost expectations. But either way you will be restricted by the limitations of a half-duplex USB 2.0 High Speed port (provided you do not have low voltage problems, the USB 2.0 specification has a maximum power output of 2.5 watts, and a LimeSDR-USB/LimeSDR-mini uses more than that). How much FEC (Forward Error Correction) you plan on adding if any, may reduce or increase average throughput depending on the properties of your local RF environment. There are so many variables, modulation used, bits per symbol, samples per symbol, length of preamble, clock recovery, … Frequency Division multiplexing or Time division multiplexing, … maybe burst transmission is right for the data type or maybe continuous transmission (e.g. digital tv/digital radio) is a better fit.

If you want to start simple, might be best to start with something really basic like AM modulation with OOK (On Off Keying), which is also know as BASK (Binary Amplitude Shift Keying). Forget about error detection, error correction, clock recovery, data preamble, start symbols, stop symbols, multiplexing and even antennas. Connect one SDR (TX only) to a second SDR (RX only) through a 20dB or 30dB T-pad attenuator (that way you avoid any other signal causing interference to yours, and any potential legal issues from transmitting without a license and/or unintentional interference on nearby channels).

Maybe do not even worry about sending a full image file. Start much much simpler.

How about just transmitting just two characters “HW”, short for “Hello World!”. “H” has a decimal ASCII value of 72 or a hexadecimal value of 0x48 or a binary value of 0100 1000. And W has a decimal ASCII value of 87 or a hexadecimal value of 0x57 or a binary value of 0101 0111. So if you wanted to transmit the binary bits for the ASCII values of “HW” you would send 0100 1000 0101 0111 but you would need to translate each bit (or a number of bits) into some kind of symbol. So how about for modulation every time a bit is “0” it is translated to 9 cycles of a sine wave with zero amplitude and every time a bit is “1” it is translated to 9 cycles of a sine wave with amplitude 2047 ( ((2^12 bits)/2) - 1 ). That would be a simple modulation scheme that could be implemented by a really simple lookup table, there are many other ways to modulate data and almost all are better than OOK. But lets go with it anyhow lets say that you were in the US and could theoretically transmit on the ISM band say 915 MHz and pick a sample rate of 2.7 MSPS (just to make the maths easier, since it is a multiple of 9). And lets randomly pick out carrier frequency as 675 kHz, I’m picking this again just because I can simplify the maths, a sine wave at 0 degrees has an amplitude of 0, at 90 degrees its amplitude is +1, at 180 degrees it is 0, at 270 degrees its amplitude is -1. This is so that I do not need to deal with any complex maths, trigonometry, floating point numbers or irrational numbers like Tau or Pi, since I’m only sampling the sine wave at 4 points (and for the next four it would repeat). So the next question is what does a constant amplitude AM waveform look like in terms of the In-phase (I) and quadrature (Q) components, and the answer is simple, there is a phase offset of one-quarter cycle (90 degrees or π/2 radians) between I and Q. So if we send 0,1,0,-1 for the In-phase we would send 1,0,-1,0 as the quadrature (-1,0,1,0 is also valid, it will just rotate around the unit circle in the opposite direction). Both would produce the same constellation diagram (one point at the origin and one point on the unit circle), both would produce a constant amplitude signal at exactly 675kHz, both would produce timing diagrams that consist only of samples at -1, 0, +1. So if we sent 0, 2047, 0, -2047 nine times to “I” and sent 2047,0,-2047,0 nine times to “Q” every time that the data we wanted to transmit has a 1 bit. And if we transmitted 0,0,0,0 nine times for “I” and 0,0,0,0 for “Q” nine times every time that the data we wanted to transmit had a 0 bit. But it may be simpler to send the unsigned 12-bit samples, so maybe send “I” as 2048,4095,2048,0 (0,1,0,-1) and “Q” as 4095,2048,0,2048 (1,0,-1,0 ) both repeated 9 times and for a zero amplitude sine wave send I as 2048,2048,2048,2048 and Q as 2048,2048,2048,2048 again repeated 9 times.

For demodulation you could use inspectrum and eyeball it for the first attempt at very basic demodulation. Or you could write some code to display the ASCII characters for the detected bit patterns but with “HW” (H:01001000 H W:01010111) repeating over and over and over. But with this basic level of modulation you would start to see the problems that are solved by adding a preamble and including a clock within the transmission.

You do not know where the bit stream starts or ends, so you could end up with bad alignment and interpreting the wrong ASCII characters as the correct message. e.g.

01001000 01010111 0x48 0x57 H  W (The right message)
10010000 10101110 0x90 0xAE ?  r 
00100001 01011101 0x21 0x5D !  ]
01000010 10111010 0x42 0xBA B  º
10000101 01110100 0x85 0x74    t
00001010 11101001 0x0A 0xE9 !  é
00010101 11010010 0x15 0xD2 ^U Ò
00101011 10100100 0x2B 0xA4 +  ¤
01010111 01001000 0x57 0x48 W  H
10101110 10010000 0xAE 0x90 ®    
01011101 00100001 0x5D 0x21 ]  !
10111010 01000010 0xBA 0x42 º  B
01110100 10000101 0x74 0x85 t   
11101001 00001010 0xE9 0x0A é  !
11010010 00010101 0xD2 0x15 Ò  ^U
10100100 00101011 0xA4 0x2B ¤  +
01001000 01010111 0x48 0x57 H  W (The right message)

And there was no way included in the basic transmission to detect, let alone fix, any data that was corrupt sometime between transmission to reception.

I had not seen your message.
Thank you for your answer.
I am pretty much a beginner regarding this, so many things are out of my knowledge.
Hope it helps, as you said.