charlie-foxtrot / RTLSDR-Airband

Multichannel AM/NFM demodulator
GNU General Public License v3.0
760 stars 135 forks source link

[BUG] Compile Errors on RPi3 with Ubuntu 20.04 #274

Closed steve1515 closed 3 years ago

steve1515 commented 3 years ago

Describe your environment

What happened? When compiling the 2 errors below occur.

ubuntu@ubuntu:~/rtlsdr-airband/RTLSDR-Airband-3.2.1$ make PLATFORM=rpiv2 NFM=1
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -ffast-math  -DNFM -DWITH_RTLSDR   -c -o rtl_airband.o rtl_airband.cpp
g++: error: unrecognized command line option ‘-mfpu=neon-vfpv4’
g++: error: unrecognized command line option ‘-mfloat-abi=hard’
make: *** [<builtin>: rtl_airband.o] Error 1

What you expected to happen? Compile without errors.

Steps to Reproduce

$ sudo apt install libmp3lame-dev libshout3-dev libconfig++-dev
$ sudo apt install libraspberrypi-dev
$ sudo apt install libfftw3-dev
$ sudo apt install librtlsdr-dev rtl-sdr
$ mkdir rtlsdr-airband
$ cd rtlsdr-airband/
$ wget https://github.com/szpajder/RTLSDR-Airband/archive/refs/tags/v3.2.1.tar.gz
$ tar xvzf v3.2.1.tar.gz
$ cd RTLSDR-Airband-3.2.1/
$ make PLATFORM=rpiv2 NFM=1

g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard -ffast-math  -DNFM -DWITH_RTLSDR   -c -o rtl_airband.o rtl_airband.cpp
g++: error: unrecognized command line option ‘-mfpu=neon-vfpv4’
g++: error: unrecognized command line option ‘-mfloat-abi=hard’
make: *** [<builtin>: rtl_airband.o] Error 1
steve1515 commented 3 years ago

After doing some research, the issue here seems to be that I have a 64-bit OS. I was able to use the PLATFORM=armv8-generic options to compile successfully.

A question remains though... make help seems to indicate that compiling this way will use main CPU for FFT as opposed to the PLATFORM=rpiv2 option that indicates that the BCM VideoCore will be used for FFT. Is there a way to still use the VideoCore in 64-bit architectures? Will there be a performance penalty?

dlpwx commented 3 years ago

I can't answer your question as to a workaround to enable use of VideoCore after compiling, though I'm curious to see the answer. Because my 32-bit RPI 4 also needed to be compiled with armv8-generic. However, I can say there are limitations in what the CPU can do. It just depends on your use case and rtl_airband config. e.g. fft_size, sample_rate, channels and devices. I've been CPU limited in a few things I wanted to try. These CPU limits will apply even more so to the RPI 3. That said, for certain uses, you can enable multithreaded flags. See the wiki for when both of those can be used.

multiple_demod_threads = true; multiple_output_threads = true;

szpajder commented 3 years ago

@steve1515 -mfpu=neon-vfpv4 and -mfloat-abi=hard options are not available for aarch64 architecture because these features are always enabled on that arch. Just remove these options from the makefile and try again.

@dlpwx VideoCore in RPi4 is different than in earlier RPi generations, hence it is not supported in rtl_airband. armv8-generic is the only way to go on this platform.

steve1515 commented 3 years ago

@szpajder When I remove those two options, I get the following error:

cc1plus: error: unknown value ‘armv7-a’ for ‘-march’
cc1plus: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a armv8.5-a native; did you mean ‘armv8-a’?

If I then change the -march to either -march=armv8-a+crc or -march=armv8-a, I get the following error:

rtl_airband.cpp:22:2: error: #error Broadcom VideoCore support can only be enabled on ARM builds
   22 | #error Broadcom VideoCore support can only be enabled on ARM builds
      |  ^~~~~
make: *** [<builtin>: rtl_airband.o] Error 1

This might be something that needs to be fixed in the source code. It looks like __arm__ is only defined in 32-bit architectures, so the way the code is written (line 22 of rtl_airband.cpp) will only allow VideoCore with 32-bit systems.

If I simply comment out that check on line 22 and compile with -march=armv8-a+crc or -march=armv8-a, I then get the following errors:

ubuntu@ubuntu:~/rtlsdr-airband/RTLSDR-Airband-3.2.1$ make PLATFORM=rpiv2 NFM=1
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR   -c -o rtl_airband.o rtl_airband.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR   -c -o input-common.o input-common.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR   -c -o input-helpers.o input-helpers.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR   -c -o input-file.o input-file.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR   -c -o output.o output.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR   -c -o config.o config.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR   -c -o util.o util.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR   -c -o mixer.o mixer.cpp
make -C hello_fft
make[1]: Entering directory '/home/ubuntu/rtlsdr-airband/RTLSDR-Airband-3.2.1/hello_fft'
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR -I..   -c -o mailbox.o mailbox.c
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR -I..   -c -o gpu_fft.o gpu_fft.c
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR -I..   -c -o gpu_fft_twiddles.o gpu_fft_twiddles.c
gpu_fft_twiddles.c: In function ‘float* twiddles_step_16(double, float*, double)’:
gpu_fft_twiddles.c:70:39: warning: unused parameter ‘two_pi’ [-Wunused-parameter]
   70 | static float *twiddles_step_16(double two_pi, float *out, double theta) {
      |                                ~~~~~~~^~~~~~
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR -I..   -c -o gpu_fft_shaders.o gpu_fft_shaders.c
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include  -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math  -DNFM -DWITH_RTLSDR -I..   -c -o gpu_fft_base.o gpu_fft_base.c
gpu_fft_base.c: In function ‘unsigned int gpu_fft_base_exec_direct(GPU_FFT_BASE*, int)’:
gpu_fft_base.c:65:16: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]
   65 |     for (q=0; q<num_qpus; q++) { // Launch shader(s)
      |               ~^~~~~~~~~
gpu_fft_base.c:72:50: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]
   72 |         if (((base->peri[V3D_SRQCS]>>16) & 0xff) == num_qpus) break; // All done?
      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
gpu_fft_base.c:54:17: warning: unused variable ‘t’ [-Wunused-variable]
   54 |     unsigned q, t;
      |                 ^
ar r hello_fft.a mailbox.o gpu_fft.o gpu_fft_twiddles.o gpu_fft_shaders.o gpu_fft_base.o
ar: creating hello_fft.a
make[1]: Leaving directory '/home/ubuntu/rtlsdr-airband/RTLSDR-Airband-3.2.1/hello_fft'
as   -o rtl_airband_neon.o rtl_airband_neon.s
rtl_airband_neon.s: Assembler messages:
rtl_airband_neon.s:26: Error: unknown pseudo-op: `.fpu'
rtl_airband_neon.s:30: Error: unknown mnemonic `push' -- `push {r4-r12,lr}'
rtl_airband_neon.s:31: Error: unknown mnemonic `vpush' -- `vpush {d4-d15}'
rtl_airband_neon.s:36: Error: operand 1 must be an integer register -- `ldr r4,[r0]'
rtl_airband_neon.s:37: Error: operand 1 must be an integer register -- `ldr r0,[r0,#4]'
rtl_airband_neon.s:39: Error: operand 1 must be an integer register -- `ldrb r5,[r1]'
rtl_airband_neon.s:40: Error: operand 1 must be an integer register -- `ldrb r6,[r1,#1]'
rtl_airband_neon.s:41: Error: operand 1 must be an integer register -- `ldrb r7,[r1,#2]'
rtl_airband_neon.s:42: Error: operand 1 must be an integer register -- `ldrb r8,[r1,#3]'
rtl_airband_neon.s:43: Error: operand 1 must be an integer register -- `ldrb r9,[r1,#4]'
rtl_airband_neon.s:44: Error: operand 1 must be an integer register -- `ldrb r10,[r1,#5]'
rtl_airband_neon.s:45: Error: operand 1 must be an integer register -- `ldrb r11,[r1,#6]'
rtl_airband_neon.s:46: Error: operand 1 must be an integer register -- `ldrb r12,[r1,#7]'
rtl_airband_neon.s:50: Error: operand 1 must be an integer register -- `ldr r5,[r3,r5,LSL#2]'
rtl_airband_neon.s:51: Error: operand 1 must be an integer register -- `ldr r6,[r3,r6,LSL#2]'
rtl_airband_neon.s:52: Error: operand 1 must be an integer register -- `ldr r7,[r3,r7,LSL#2]'
rtl_airband_neon.s:53: Error: operand 1 must be an integer register -- `ldr r8,[r3,r8,LSL#2]'
rtl_airband_neon.s:54: Error: operand 1 must be an integer register -- `ldr r9,[r3,r9,LSL#2]'
rtl_airband_neon.s:55: Error: operand 1 must be an integer register -- `ldr r10,[r3,r10,LSL#2]'
rtl_airband_neon.s:56: Error: operand 1 must be an integer register -- `ldr r11,[r3,r11,LSL#2]'
rtl_airband_neon.s:57: Error: operand 1 must be an integer register -- `ldr r12,[r3,r12,LSL#2]'
rtl_airband_neon.s:59: Error: unknown mnemonic `vldmia' -- `vldmia r2!,{d8-d11}'
rtl_airband_neon.s:60: Error: operand 1 must be an integer or stack pointer register -- `add r1,r1,#8'
rtl_airband_neon.s:62: Error: unknown mnemonic `vmov' -- `vmov d4,r5,r6'
rtl_airband_neon.s:63: Error: unknown mnemonic `vmov' -- `vmov d5,r7,r8'
rtl_airband_neon.s:64: Error: unknown mnemonic `vmov' -- `vmov d6,r9,r10'
rtl_airband_neon.s:65: Error: unknown mnemonic `vmov' -- `vmov d7,r11,r12'
rtl_airband_neon.s:66: Error: unknown mnemonic `pld' -- `pld [r1,#16]'
rtl_airband_neon.s:67: Error: unknown mnemonic `vmul.f32' -- `vmul.f32 q6,q2,q4'
rtl_airband_neon.s:68: Error: unknown mnemonic `vmul.f32' -- `vmul.f32 q7,q3,q5'
rtl_airband_neon.s:69: Error: unknown mnemonic `pld' -- `pld [r2,#8]'
rtl_airband_neon.s:70: Error: operand 1 must be an integer register -- `ldrb r5,[r1]'
rtl_airband_neon.s:71: Error: operand 1 must be an integer register -- `ldrb r6,[r1,#1]'
rtl_airband_neon.s:72: Error: operand 1 must be an integer register -- `ldrb r7,[r1,#2]'
rtl_airband_neon.s:73: Error: operand 1 must be an integer register -- `ldrb r8,[r1,#3]'
rtl_airband_neon.s:74: Error: operand 1 must be an integer register -- `ldrb r9,[r1,#4]'
rtl_airband_neon.s:75: Error: operand 1 must be an integer register -- `ldrb r10,[r1,#5]'
rtl_airband_neon.s:76: Error: operand 1 must be an integer register -- `ldrb r11,[r1,#6]'
rtl_airband_neon.s:77: Error: operand 1 must be an integer register -- `ldrb r12,[r1,#7]'
rtl_airband_neon.s:78: Error: unknown mnemonic `vstmia' -- `vstmia r0!,{q6-q7}'
rtl_airband_neon.s:79: Error: operand 1 must be an integer register -- `subs r4,r4,#1'
rtl_airband_neon.s:82: Error: unknown mnemonic `vpop' -- `vpop {d4-d15}'
rtl_airband_neon.s:83: Error: unknown mnemonic `pop' -- `pop {r4-r12,pc}'
make: *** [<builtin>: rtl_airband_neon.o] Error 1

Maybe it's not possible to use the VideoCore on 64-bit on a RPi 3?

szpajder commented 3 years ago

Right, I forgot to mention that the assembly code for DSP operations which is enabled together with VC support works only on 32-bit arches.

In this case I suggest switching to a 32-bit OS.

steve1515 commented 3 years ago

I just came to report that I've now tried with 32-bit Ubuntu and VC support. I'm now get about 25% CPU usage vs. the 50% I was getting without VC support in the 64-bit Ubuntu.