nRF24 / RF24

OSI Layer 2 driver for nRF24L01 on Arduino & Raspberry Pi/Linux Devices
https://nrf24.github.io/RF24
GNU General Public License v2.0
2.23k stars 1.02k forks source link

Library doesn't compile for ubuntu-64bit on RPi3 & RPi4 #642

Closed sfouser1 closed 3 years ago

sfouser1 commented 4 years ago

I'm using Ubuntu 20.04.1 on Raspberry Pi Model B+

2bndy5 commented 4 years ago

npm?! This library has nothing to do with node.js. You may be experiencing an issue with some 3rd-party wrapper for node.js that uses this library as a code-base (there are many of those on npm). How/Why are you using Ubuntu 20.04 on a RPi B+? The download page at Ubuntu only offers images for the RPi2, RPi3, & RPi4. The RPi1 (B+) is not listed. Unless you're trying to say you're running Ubuntu on RPi3B+. I have no idea what librf24 is referring to. Its certainly not this library.

sfouser1 commented 4 years ago

I meant Ubuntu 20.04.1 on Raspberry Pi 3B+.

I should have explained it better.

I did a manual install of RF24LIB library as listed in the steps for RF24LIB/Linux.html.

After this, my gettingstarted and other files compiled successfully, but I'm unable to execute them. The OS doesn't recognise them as executables. I tried in sudo mode as well. After the compile, there are a few files that get moved to /user/local/lib folder - this includes librf24.so which is a link ultimately to a file librf24.so.1.3.9 - this file is moved as part of the compile. I suspect this .so file has the same problem as gettingstarted.

I tried to install 'nrf' module (natevw/node-nrf) as part of my node server - npm install nrf.

This goes through the compile of various modules of RF24, RF24MESH, etc. but after a few steps fails due to this incompatible .so file.

2bndy5 commented 4 years ago

Thank you for more details. My first instinct is to try and re-create the issue, but... Its been A LONG TIME since I used node.js or npm on my RPi (I'm working with Raspbian on an RPi2), so I'm waiting on apt to update nodejs and npm installs right now. While waiting I looked into the node.js library titled "nrf". This caught my eye from the lib's README:

Not to be confused with node-rf24 which was/is an unfinished (and broken by recent V8 and libuv changes) wrapper around the RasPi port of the C++ RF24 library. In contrast, this module is implemented in pure JavaScript on top of native SPI bindings. It also provides a cleaner, node-friendly interface.

You can see that the "SPI bindings" link is yet another node.js library titled "pi-spi" (written by the same author of "nrf" library). I'm not convinced that "nrf" library actually looks for the DLL file in "usr/local/bin/" folder seen as how it's not listed under the "nrf" lib's dependencies. Additionally, if I'm looking at the wrong library, the other library titled "node-rf24" is based on a different fork of maniacbug's RF24 library. All of these libraries are 6-years stale or just no longer maintained. Please send a link to the exact library you're referring to.

ps.s did the automatic install.sh script not work for your RPi3?

sfouser1 commented 4 years ago

Thank you for your time.

Before the npm package install issue, I would like to solve the Rf24 basic C++ compile issue - so feel it's linked to this basic compilation issue. Why is it that I'm able to compile the code successfully but unable to execute them?

2bndy5 commented 4 years ago

sorry I have no idea. It installs and executes fine for me. Personally I don't use the C++ code due to restriction on the CSN pin options. I assume you have verified the files are properly moved with ls /usr/local/lib. It would also help to see the output on your terminal to provide some insight on how it complains librf24 is incompatible. This statement makes me think there may be a problem when gcc tries to link at compile time.

sfouser1 commented 4 years ago

OK. I got to the bottom of this. This is my version of what's going on!

The make files were invoking the cross compiler installed on my system, and it wasn't producing an executable that I could run - same issue with the rf24lib.so as well as the gettingstarted executable.

Output of ./config command detects the arm OS and sets up the C++ cross compiler. ./config output: [SECTION] Detecting arm compilation environment. [OK] arm-linux-gnueabihf-gcc detected. [OK] arm-linux-gnueabihf-g++ detected. [SECTION] Detecting target machine. [OK] machine detected: SoC=BCM2835, Type=RPi, CPU=aarch64. [SECTION] Detecting DRIVER [OK] DRIVER detected:RPi. [SECTION] Detecting OS. [INFO] OS detected:LINUX. [SECTION] Preparing configuration. [SECTION] Saving configuration. [SECTION] Cleaning previous builds. [OK] Finished.

Makefile.inc in RF24 directory OS=LINUX SOC=BCM2835 DRIVER=RPi CPUFLAGS=-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard CFLAGS=-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -Ofast -Wall -pthread PREFIX=/usr/local REMOTE_PREFIX=/usr/local LIB=rf24 LIBNAME=librf24.so.1.3.9 LIB_VERSION=1.3.9 LIBSYMLINKS=librf24.so.1.3 librf24.so.1 librf24.so LIBDEPRECATE=librf24-bcm.so CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ LIB_DIR=/usr/local/lib REMOTE_LIB_DIR=/usr/local/lib HEADER_DIR=/usr/local/include/RF24 REMOTE_HEADER_DIR=/usr/local/include/RF24 DRIVER_DIR=utility/RPi ARCH_DIR=utility SHARED_LINKER_FLAGS= -shared -Wl,-soname,librf24.so.1 SHARED_LINKER_LIBS= -pthread LDCONFIG=ldconfig REMOTE_LDCONFIG=/sbin/ldconfig EXAMPLES_DIR=/usr/local/bin REMOTE_EXAMPLES_DIR=/usr/local/bin

Am I correct? I had to change the CC and CXX reference to gcc and g++ respectively, delete most of the options in CPUFLAGS and CFLAGS (g++ compiler didn't understand most of the options), comment out the line that invokes config in the makefile, and run make. Now I was able to compile my code, and get executables, and also be able to transfer a 'compatible' .so file to /usr/local/lib folder. Now, the npm install of nrf also works. That invokes the cross-compiler but it goes through successfully.

Let me know if this work around is the right thing to do!

Now, onto the next challenge of making sure that my nrf interface works. I will use the gettingstarted and other files to test.

Avamander commented 4 years ago

delete most of the options in CPUFLAGS and CFLAGS (g++ compiler didn't understand most of the options),

And that left what? What did it not understand?

sfouser1 commented 4 years ago

The modified Makefile.inc: OS=LINUX SOC=BCM2835 DRIVER=RPi CPUFLAGS= CFLAGS=-Ofast -Wall -pthread PREFIX=/usr/local REMOTE_PREFIX=/usr/local LIB=rf24 LIBNAME=librf24.so.1.3.9 LIB_VERSION=1.3.9 LIBSYMLINKS=librf24.so.1.3 librf24.so.1 librf24.so LIBDEPRECATE=librf24-bcm.so CC=gcc CXX=g++ LIB_DIR=/usr/local/lib REMOTE_LIB_DIR=/usr/local/lib HEADER_DIR=/usr/local/include/RF24 REMOTE_HEADER_DIR=/usr/local/include/RF24 DRIVER_DIR=utility/RPi ARCH_DIR=utility SHARED_LINKER_FLAGS= -shared -Wl,-soname,librf24.so.1 SHARED_LINKER_LIBS= -pthread LDCONFIG=ldconfig REMOTE_LDCONFIG=/sbin/ldconfig EXAMPLES_DIR=/usr/local/bin REMOTE_EXAMPLES_DIR=/usr/local/bin

This let me avoid using the cross-compiler. Did I clarify?

Avamander commented 4 years ago

Run ./configure with --soc=BCM2836 and report back if you still have to manually mess with the Makefile.inc.

sfouser1 commented 4 years ago

Same issue. Ran ./configure with --soc=BCM2836

These are the steps that I followed Manual Install Install prerequisites if there are any (MRAA, LittleWire libraries, setup SPI device etc) Note See the MRAA documentation for more info on installing MRAA Make a directory to contain the RF24 and possibly RF24Network lib and enter it mkdir ~/rf24libs cd ~/rf24libs Clone the RF24 repo git clone https://github.com/tmrh20/RF24.git RF24 Change to the new RF24 directory cd RF24 Configure build environment using ./configure -> I did ./configure --soc=BCM2836 script. It auto detectes device and build environment. For overriding autodetections, use command-line switches, see ./configure --help for description. Build the library, and run an example file make; sudo make install cd examples_linux
Edit the gettingstarted example, to set your pin configuration nano gettingstarted.cpp make sudo ./gettingstarted

Avamander commented 4 years ago

Same issue.

What's the error message now?

sfouser1 commented 4 years ago

Same as before - doesn't recognize the files as executables.

$ sudo ./gettingstarted sudo: unable to execute ./gettingstarted: No such file or directory

I suspect that the arm-linux-gnueabihf-g++ doesn't generate an executable. This is what the CXX variable is set to in Makefile.inc

Avamander commented 4 years ago

It must output something during compilation, that's the error message I'm interested in. What you cause after that, not so much.

sfouser1 commented 4 years ago

There are absolutely no error messages.

This is the dump of all the things that happened. Hope this helps.

devuser@ubuntu:~/b/nrftest3$ mkdir rf24libs
devuser@ubuntu:~/b/nrftest3$ cd rf24libs
devuser@ubuntu:~/b/nrftest3/rf24libs$ ls
devuser@ubuntu:~/b/nrftest3/rf24libs$ git clone https://github.com/tmrh20/RF24.git RF24
Cloning into 'RF24'...
remote: Enumerating objects: 60, done.
remote: Counting objects: 100% (60/60), done.
remote: Compressing objects: 100% (40/40), done.
remote: Total 3812 (delta 25), reused 39 (delta 20), pack-reused 3752
Receiving objects: 100% (3812/3812), 1.67 MiB | 1.65 MiB/s, done.
Resolving deltas: 100% (2285/2285), done.
devuser@ubuntu:~/b/nrftest3/rf24libs$ ls
RF24
devuser@ubuntu:~/b/nrftest3/rf24libs$ cd RF24
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24$ ls
COMMON_ISSUES.md  Makefile   RF24_config.h       examples_linux      nRF24L01.h  utility
CONTRIBUTING.md   README.md  configure           keywords.txt        printf.h    wikidoc.xslt
Doxyfile          RF24.cpp   doxygen-custom.css  library.json        pyRF24
LICENSE           RF24.h     examples            library.properties  tests
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24$ ./configure --soc=BCM2836
[SECTION] Detecting arm compilation environment.
  [OK] arm-linux-gnueabihf-gcc detected.
  [OK] arm-linux-gnueabihf-g++ detected.
[SECTION] Detecting DRIVER
  [OK] DRIVER detected:RPi.
[SECTION] Detecting OS.
  [INFO] OS detected:LINUX.
[SECTION] Preparing configuration.
[SECTION] Saving configuration.
[SECTION] Cleaning previous builds.
[OK] Finished.
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24$ make
arm-linux-gnueabihf-g++ -fPIC -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c RF24.cpp
arm-linux-gnueabihf-g++ -fPIC -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c utility/RPi/spi.cpp
arm-linux-gnueabihf-gcc -fPIC -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c utility/RPi/bcm2835.c
arm-linux-gnueabihf-g++ -fPIC -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c utility/RPi/interrupt.c
utility/RPi/interrupt.c: In function ‘int waitForInterrupt(int, int)’:
utility/RPi/interrupt.c:62:16: warning: ignoring return value of ‘ssize_t read(int, void*, size_t)’, declared with attribute warn_unused_result [-Wunused-result]
   62 |     (void) read(fd, &c, 1);
      |            ~~~~^~~~~~~~~~~
utility/RPi/interrupt.c: In function ‘int attachInterrupt(int, int, void (*)())’:
utility/RPi/interrupt.c:156:13: warning: ignoring return value of ‘ssize_t read(int, void*, size_t)’, declared with attribute warn_unused_result [-Wunused-result]
  156 |         read(sysFds[bcmGpioPin], &c, 1);
      |         ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
arm-linux-gnueabihf-gcc -fPIC  -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c utility/RPi/compatibility.c
[Linking]
arm-linux-gnueabihf-gcc -shared -Wl,-soname,librf24.so.1 -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -o librf24.so.1.3.9 RF24.o spi.o bcm2835.o interrupt.o compatibility.o -pthread
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24$ sudo make install
[sudo] password for devuser: 
[Installing Libs to /usr/local/lib]
[Installing Headers to /usr/local/include/RF24]
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24$ cd examples_linux
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ make
arm-linux-gnueabihf-g++ -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -I/usr/local/include/RF24/.. -I.. -L/usr/local/lib gettingstarted.cpp -lrf24 -o gettingstarted
arm-linux-gnueabihf-g++ -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -I/usr/local/include/RF24/.. -I.. -L/usr/local/lib gettingstarted_call_response.cpp -lrf24 -o gettingstarted_call_response
arm-linux-gnueabihf-g++ -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -I/usr/local/include/RF24/.. -I.. -L/usr/local/lib transfer.cpp -lrf24 -o transfer
arm-linux-gnueabihf-g++ -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -I/usr/local/include/RF24/.. -I.. -L/usr/local/lib pingpair_dyn.cpp -lrf24 -o pingpair_dyn
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ sudo ./gettingstarted
sudo: unable to execute ./gettingstarted: No such file or directory
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ ls -al
total 132
drwxrwxr-x 4 devuser devuser  4096 Oct  5 14:41 .
drwxrwxr-x 9 devuser devuser  4096 Oct  5 14:40 ..
-rw-rw-r-- 1 devuser devuser   588 Oct  5 14:26 Makefile
-rw-rw-r-- 1 devuser devuser  1514 Oct  5 14:26 Makefile.examples
drwxrwxr-x 2 devuser devuser  4096 Oct  5 14:26 extra
-rwxrwxr-x 1 devuser devuser 15912 Oct  5 14:41 gettingstarted
-rw-rw-r-- 1 devuser devuser  5558 Oct  5 14:26 gettingstarted.cpp
-rwxrwxr-x 1 devuser devuser 16180 Oct  5 14:41 gettingstarted_call_response
-rw-rw-r-- 1 devuser devuser  5989 Oct  5 14:26 gettingstarted_call_response.cpp
drwxrwxr-x 2 devuser devuser  4096 Oct  5 14:26 interrupts
-rwxrwxr-x 1 devuser devuser 16036 Oct  5 14:41 pingpair_dyn
-rw-rw-r-- 1 devuser devuser  5635 Oct  5 14:26 pingpair_dyn.cpp
-rwxrwxr-x 1 devuser devuser  4490 Oct  5 14:26 pingpair_dyn.py
-rw-rw-r-- 1 devuser devuser   193 Oct  5 14:26 readme.md
-rwxrwxr-x 1 devuser devuser 16204 Oct  5 14:41 transfer
-rw-rw-r-- 1 devuser devuser  5372 Oct  5 14:26 transfer.cpp
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ 
Avamander commented 4 years ago

It does say that gettingstarted is there though.

sfouser1 commented 4 years ago

Yes it does! That's what I was saying in my previous comment - It generates an executable but the OS doesn't seem to recognize it as an executable.

Avamander commented 4 years ago

Run it as non-root and post what file says about it.

sfouser1 commented 4 years ago

You mean this "sudo ./gettingstarted" without sudo?

BTW, I tried the whole sequence of install with Raspbian OS - swapped another micro-SD card, and that seemed to go very smooth. This issue seems to come up with Ubuntu.

2bndy5 commented 4 years ago

@sfouser1 I think @Avamander means file ~/b/nrftest3/rf24libs/RF24/examples_linux/gettingstarted. Its a linux bash command. This is the output for gettingstarted when it compiles for me (just for comparison):

pi@b-pi2:~/RF24/examples_linux $ file gettingstarted
gettingstarted: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=4168765ea8ed5e79136f709fa1e88e696097e52a, with debug_info, not stripped
2bndy5 commented 4 years ago

This issue seems to come up with Ubuntu.

I had a feeling that was a problem, but I'm not as familiar with Linux as I'd like to be. Raspbian ships with some software that vanilla Ubuntu doesn't. I can't say what Raspbian has that Ubuntu doesn't to cause this error though.

I know that the RF24 github action uses "ubuntu-latest", but that docker image has a slew of software pre-installed. Not to mention that the action's workflow file also installs some stuff too.

@Avamander Would it be worth it to add compiling the "examples_linux" folder into the RF24 github actions? Maybe we could catch an issue like this before it arises...

sfouser1 commented 4 years ago

I wasn't familiar with what 'file' does. Here's the output:

file gettingstarted
gettingstarted: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=e8908d34ed91dacb63ce043baf9e1f83a1609e95, for GNU/Linux 3.2.0, with debug_info, not stripped

For comparison, for the stripped down version where I modified the Makefile.inc file on Ubuntu, I get this output:

gettingstarted: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=2348ca2eb72c11ce0bad587ce109ca81df9fa3ea, for GNU/Linux 3.7.0, with debug_info, not stripped

To remind you, the second output is where gettingstarted works.

Hope this helps.

Avamander commented 4 years ago

What's the output of the first one without running it as root?

Avamander commented 4 years ago

It seems that it gets built as 32-bit but Ubuntu 20.04 is forced 64-bit, I think. The makefile should probably autodetect that.

sfouser1 commented 4 years ago

Did a fresh install - Let me know if I have missed anything.

devuser@ubuntu:~/b/nrftest3$ rm -rf *
devuser@ubuntu:~/b/nrftest3$ ls -al
total 8
drwxrwxr-x  2 devuser devuser 4096 Oct  7 18:57 .
drwxrwxr-x 13 devuser devuser 4096 Oct  7 13:38 ..
devuser@ubuntu:~/b/nrftest3$ mkdir rf24libs
devuser@ubuntu:~/b/nrftest3$ cd rf24libs
devuser@ubuntu:~/b/nrftest3/rf24libs$ git clone https://github.com/tmrh20/RF24.git RF24 
Cloning into 'RF24'...
remote: Enumerating objects: 60, done.
remote: Counting objects: 100% (60/60), done.
remote: Compressing objects: 100% (40/40), done.
remote: Total 3812 (delta 25), reused 39 (delta 20), pack-reused 3752
Receiving objects: 100% (3812/3812), 1.67 MiB | 277.00 KiB/s, done.
Resolving deltas: 100% (2285/2285), done.
devuser@ubuntu:~/b/nrftest3/rf24libs$ cd RF24
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24$ ./configure --soc=BCM2836
[SECTION] Detecting arm compilation environment.
  [OK] arm-linux-gnueabihf-gcc detected.
  [OK] arm-linux-gnueabihf-g++ detected.
[SECTION] Detecting DRIVER
  [OK] DRIVER detected:RPi.
[SECTION] Detecting OS.
  [INFO] OS detected:LINUX.
[SECTION] Preparing configuration.
[SECTION] Saving configuration.
[SECTION] Cleaning previous builds.
[OK] Finished.
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24$ make
arm-linux-gnueabihf-g++ -fPIC -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c RF24.cpp
arm-linux-gnueabihf-g++ -fPIC -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c utility/RPi/spi.cpp
arm-linux-gnueabihf-gcc -fPIC -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c utility/RPi/bcm2835.c
arm-linux-gnueabihf-g++ -fPIC -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c utility/RPi/interrupt.c
utility/RPi/interrupt.c: In function ‘int waitForInterrupt(int, int)’:
utility/RPi/interrupt.c:62:16: warning: ignoring return value of ‘ssize_t read(int, void*, size_t)’, declared with attribute warn_unused_result [-Wunused-result]
   62 |     (void) read(fd, &c, 1);
      |            ~~~~^~~~~~~~~~~
utility/RPi/interrupt.c: In function ‘int attachInterrupt(int, int, void (*)())’:
utility/RPi/interrupt.c:156:13: warning: ignoring return value of ‘ssize_t read(int, void*, size_t)’, declared with attribute warn_unused_result [-Wunused-result]
  156 |         read(sysFds[bcmGpioPin], &c, 1);
      |         ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
arm-linux-gnueabihf-gcc -fPIC  -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -c utility/RPi/compatibility.c
[Linking]
arm-linux-gnueabihf-gcc -shared -Wl,-soname,librf24.so.1 -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -o librf24.so.1.3.9 RF24.o spi.o bcm2835.o interrupt.o compatibility.o -pthread
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24$ sudo make install
[Installing Libs to /usr/local/lib]
[Installing Headers to /usr/local/include/RF24]
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24$ cd examples_linux
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ make
arm-linux-gnueabihf-g++ -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -I/usr/local/include/RF24/.. -I.. -L/usr/local/lib gettingstarted.cpp -lrf24 -o gettingstarted
arm-linux-gnueabihf-g++ -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -I/usr/local/include/RF24/.. -I.. -L/usr/local/lib gettingstarted_call_response.cpp -lrf24 -o gettingstarted_call_response
arm-linux-gnueabihf-g++ -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -I/usr/local/include/RF24/.. -I.. -L/usr/local/lib transfer.cpp -lrf24 -o transfer
arm-linux-gnueabihf-g++ -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -Ofast -Wall -pthread  -I/usr/local/include/RF24/.. -I.. -L/usr/local/lib pingpair_dyn.cpp -lrf24 -o pingpair_dyn
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ sudo ./gettingstarted
sudo: unable to execute ./gettingstarted: No such file or directory
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ file gettingstarted
gettingstarted: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=e8908d34ed91dacb63ce043baf9e1f83a1609e95, for GNU/Linux 3.2.0, with debug_info, not stripped
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ ./gettingstarted
-bash: ./gettingstarted: No such file or directory
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ file gettingstarted
gettingstarted: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=e8908d34ed91dacb63ce043baf9e1f83a1609e95, for GNU/Linux 3.2.0, with debug_info, not stripped
devuser@ubuntu:~/b/nrftest3/rf24libs/RF24/examples_linux$ 
2bndy5 commented 4 years ago

@sfouser1 for the fresh install: Did you use the 32-bit Ubuntu image or the 64-bit image?

Here is a note directly from the Ubuntu download page for raspberry pi builds:

According to the Raspberry Pi foundation, there are limited benefits to using the 64 bit version for the Pi 3 due to the fact that it only supports 1GB of memory

Not sure if that note affects this scenario. Other issues about running this library on RPi4 (also 64-bit) don't seem to have compilation problems (they also never specify what OS they're using).

sfouser1 commented 4 years ago

I understand that each of you have been responding to me on this. My intention was to point out issues that may help in the upkeep of the good work.

@2bndy5 I used the 64-bit image. The reason I went to it is because I have been writing some Node JS code with MongoDB - it runs on a cloud environment now. I wanted to port it to Raspberry but had many issues with Mongo DB compatibility. Ubuntu allowed me to use the code as-is on Raspberry.

I have now been able to connect to NRF on Raspberry with Ubuntu - with the work around compile that I had done earlier.

2bndy5 commented 4 years ago

I'm ready to call this issue solved, but @Avamander how would we go about future-proofing the makefile to prevent this from happening again? Does it need to detect the OS's architecture ("bitness")?

To recap (according to my understanding), it would seem that @sfouser1 solution was to change

CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++

to

CC=gcc CXX=g++

While I don't know how

CPUFLAGS=-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard CFLAGS=-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -Ofast -Wall -pthread

were misunderstood by g++. @sfouser1 reported that "g++ compiler didn't understand most of the options". Thus, changing these options to

CPUFLAGS= CFLAGS=-Ofast -Wall -pthread

apparently fixed whatever g++ was saying about them (@sfouser1 we would appreciate the actual g++ output about that).

Please let me know if I've missed or misunderstood something.

Avamander commented 4 years ago

To recap (according to my understanding), it would seem that @sfouser1 solution was to change

CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++

to

CC=gcc CXX=g++

Can be overridden by export-ing them before configure. Solution: Preferably default should be native compilation, cross compilation separately. This would allow passing -march=native -mtune=native and not deal with that.

While I don't know how

CPUFLAGS=-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard CFLAGS=-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -Ofast -Wall -pthread

Yeah, he gave it a compiler that can't cross-compile to ARMv6. There's no 64bit ARMv8 target in the makefile, but the ARMv7 binary does run if the CPU is not forced 64bit, if I've understood materials on the internet correctly. Solution: add proper 64bit RPi4 target to the makefile.

2bndy5 commented 4 years ago

add proper 64bit RPi4 target to the makefile.

just a reminder, RPi3 is also 64-bit (as used by @sfouser1)

Avamander commented 4 years ago

just a reminder, RPi3 is also 64-bit (as used by @sfouser1)

64-bit capable, but requiring 64-bit is an another thing, the Ubuntu image might be doing that. See arm_control and arm_64bit.

sfouser1 commented 4 years ago

I'm ready to call this issue solved, but @Avamander how would we go about future-proofing the makefile to prevent this from happening again? Does it need to detect the OS's architecture ("bitness")?

To recap (according to my understanding), it would seem that @sfouser1 solution was to change

CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++

to

CC=gcc CXX=g++

While I don't know how

CPUFLAGS=-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard CFLAGS=-marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -Ofast -Wall -pthread

were misunderstood by g++. @sfouser1 reported that "g++ compiler didn't understand most of the options". Thus, changing these options to

CPUFLAGS= CFLAGS=-Ofast -Wall -pthread

apparently fixed whatever g++ was saying about them (@sfouser1 we would appreciate the actual g++ output about that).

Please let me know if I've missed or misunderstood something.

Yes, agree with your summary.

2bndy5 commented 3 years ago

questing to reproduce this on my RPi4, I found which flags were "unrecognized":

brendan@rpi4-ubuntu64:~/RF24$ ./configure
[SECTION] Detecting arm compilation environment.
  [INFO] arm-linux-gnueabihf-gcc not found.
  [INFO] arm-linux-gnueabihf-g++ not found.
[SECTION] Detecting target machine.
[OK] machine detected: SoC=BCM2835, Type=RPi, CPU=aarch64.
[SECTION] Detecting DRIVER
  [OK] DRIVER detected:RPi.
[SECTION] Detecting OS.
  [INFO] OS detected:LINUX.
[SECTION] Preparing configuration.
[SECTION] Saving configuration.
[SECTION] Cleaning previous builds.
[OK] Finished.
brendan@rpi4-ubuntu64:~/RF24$ make
g++ -fPIC -marm -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -Ofast -Wall -pthread  -c RF24.cpp
g++: error: unrecognized command-line option ‘-marm’
g++: error: unrecognized command-line option ‘-mfpu=vfp’
g++: error: unrecognized command-line option ‘-mfloat-abi=hard’
make: *** [Makefile:42: RF24.o] Error 1

the errors were the same when forcing the SPIDEV driver. Above output uses unmodified CC and CXX settings.

ps - It took a while to get ubuntu (apt updated/upgraded) to boot to console (required installing grub2-common & some other modifications) and enabling ssh (basically required installing ssh and systemctl enable ssh.service)

2bndy5 commented 3 years ago

I just tried installing this lib with CMake (using the rp2xxx branch) on ubuntu 64-bit running on my RPi4...

So far, our CMake implementation doesn't care about what compiler is used and it will default to the GNU compiler that ships with the OS.

I was able to build and run the examples (with required sudo privilege) using the RPi driver (specific to BCM2xxx processors), but the payloads transmitted/received were incorrect (?? probably related to 64-bit vs 32-bit ??). The SPIDEV driver failed to initialize the radio (using the same pins and pin numbers as when trying the RPi driver).

I feel like we're getting close to a solution for this; it just needs some polish...

sfouser1 commented 3 years ago

Thank you. Look forward to having this. I currently have a work around done but will be great to have this is a straightforward installation.

2bndy5 commented 3 years ago

making a note here to kind of bookmark my progress towards compiling 32-bit lib (and examples) in ubuntu 64-bit env.

Ubuntu 64-bit needs sudo apt install libc6-dev-i386 gcc-multilib g++-multilib to provide the proper header files for 32-bit compilation.

UPDATE 😦

kripton commented 3 years ago

The main question for me is why anyone would want to run an "arm32" binary on an aarch64 host? On x86_64 it makes sense for historical reasons to support multilib libraries since there might be binary-only programs "from the past" that need 32-bit libraries to work (I know this mainly from Valve's Steam where lots of games are 32bit binaries). However, when you run an aarch64 system (64bit kernel + 64bit user-space), I would not know a use case for being able to run 32bit ARM binaries. All the software one might want to use is either packaged by the OS (= raspbian package repo) or can and should be compiled on the target from source (or on a second machine using a cross-compiler to target aarch64). The gcc of raspbian 64bit not supporting the usual "-m32" switch is another indication that this is a very seldom use case. To be more precise: If you check the man-page of gcc, the "-m32" switch is architecture-specific and only support on x86_64 and a few select other platforms (Hints: https://forums.gentoo.org/viewtopic-t-1021994-start-0.html, https://lists.96boards.org/pipermail/dev/2015-November/000549.html, https://patchwork.openembedded.org/patch/106801/). So while it's a good thing to support multilib builds on x86_64, it won't work on aarch64 and it's not our fault :)

Avamander commented 3 years ago

The main question for me is why anyone would want to run an "arm32" binary on an aarch64 host?

If my data is not too outdated, Raspbian is 32bit even on aarch64 hosts.

2bndy5 commented 3 years ago

I'm not an architecture expert (even talking about this stuff makes feel like a noob), but I assumed the inaccuracies in the payloads being transmitted were due to the difference in bitness of the nodes' platforms. I'll roll back some changes I made and take a another look at executing in 64-bit (the ackPL example was the most obvious due to the use of dynamic PLs) - this time I'll post my problematic examples' output (hopefully somebody with fresh eyes will pick up on something I overlooked).

BTW, specifying the arm compiler in CMake brings another set of problems when linking the examples to the installed lib... It turns out that the way the PicoSDK forces the arm compiler isn't recommended because of reasons with CMake's cache (which is easily avoided since Cmake's build env basically needs to be flushed for each attempted build anyway).

@avamander Screenshot from 2021-05-28 02-09-04 It is still 32-bit

2bndy5 commented 3 years ago

Arduino Nano output (ackPl example)

radioNumber = 0
*** PRESS 'T' to begin transmitting to the other node
*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK
Transmission successful! Time to transmit = 648 us. Sent: Hello 0 Recieved 8 bytes on pipe 0: World 0
Transmission successful! Time to transmit = 664 us. Sent: Hello 1 Recieved 8 bytes on pipe 0: World 1
Transmission successful! Time to transmit = 660 us. Sent: Hello 2 Recieved 8 bytes on pipe 0: World 2
Transmission successful! Time to transmit = 664 us. Sent: Hello 3 Recieved 8 bytes on pipe 0: World 4
Transmission successful! Time to transmit = 664 us. Sent: Hello 5 Recieved 8 bytes on pipe 0: World 4
Transmission successful! Time to transmit = 660 us. Sent: Hello 5 Recieved 8 bytes on pipe 0: World 8
Transmission successful! Time to transmit = 668 us. Sent: Hello 9 Recieved 8 bytes on pipe 0: World 8
Transmission successful! Time to transmit = 660 us. Sent: Hello 9 Recieved 8 bytes on pipe 0: World 14
Transmission successful! Time to transmit = 664 us. Sent: Hello 15 Recieved 8 bytes on pipe 0: World 14
Transmission successful! Time to transmit = 660 us. Sent: Hello 15 Recieved 8 bytes on pipe 0: World 16
Transmission successful! Time to transmit = 668 us. Sent: Hello 17 Recieved 8 bytes on pipe 0: World 16
Transmission successful! Time to transmit = 660 us. Sent: Hello 17 Recieved 8 bytes on pipe 0: World 26
*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK
Received 8 bytes on pipe 1: Hello 26 Sent: World 27
Received 8 bytes on pipe 1: Hello 26 Sent: World 27
Received 8 bytes on pipe 1: Hello 28 Sent: World 27
Received 8 bytes on pipe 1: Hello 28 Sent: World 29
Received 8 bytes on pipe 1: Hello 28 Sent: World 29
Received 8 bytes on pipe 1: Hello 30 Sent: World 29
Received 8 bytes on pipe 1: Hello 30 Sent: World 31
Received 8 bytes on pipe 1: Hello 30 Sent: World 31
Received 8 bytes on pipe 1: Hello 32 Sent: World 31
Received 8 bytes on pipe 1: Hello 32 Sent: World 33
Received 8 bytes on pipe 1: Hello 32 Sent: World 33
Received 8 bytes on pipe 1: Hello 34 Sent: World 33
Received 8 bytes on pipe 1: Hello 34 Sent: World 35
Received 8 bytes on pipe 1: Hello 34 Sent: World 35
Received 8 bytes on pipe 1: Hello 36 Sent: World 35

Ubuntu 64-bit output (ackPL example) - using RPi driver

Which radio is this? Enter '0' or '1'. Defaults to '0' 1
*** PRESS 'T' to begin transmitting to the other node
*** PRESS 'R' to begin receiving from the other node
*** PRESS 'Q' to exit
r
Received 12 bytes on pipe 1: lw~~00 Sent: World 0
Received 12 bytes on pipe 1: lw~~01 Sent: World 1
Received 12 bytes on pipe 1: lw~~03 Sent: World 2
Received 12 bytes on pipe 1: lw~~03 Sent: World 4
Received 12 bytes on pipe 1: lw~~07 Sent: World 4
Received 12 bytes on pipe 1: lw~~07 Sent: World 8
Received 12 bytes on pipe 1: lw~~013 Sent: World 8
Received 12 bytes on pipe 1: lw~~013 Sent: World 14
Received 12 bytes on pipe 1: lw~~015 Sent: World 14
Received 12 bytes on pipe 1: lw~~015 Sent: World 16
Received 12 bytes on pipe 1: lw~~025 Sent: World 16
Received 12 bytes on pipe 1: lw~~025 Sent: World 26
Nothing received in 6 seconds. Leaving RX role.
*** PRESS 'T' to begin transmitting to the other node
*** PRESS 'R' to begin receiving from the other node
*** PRESS 'Q' to exit
t
Transmission successful! Time to transmit = 54 us. Sent: Hello 26 Received an empty ACK packet.
Transmission successful! Time to transmit = 54 us. Sent: Hello 26 Received 8 bytes on pipe 0: World 27
Transmission successful! Time to transmit = 55 us. Sent: Hello 28 Received 8 bytes on pipe 0: World 27
Transmission successful! Time to transmit = 52 us. Sent: Hello 28 Received 8 bytes on pipe 0: World 27
Transmission successful! Time to transmit = 58 us. Sent: Hello 28 Received 8 bytes on pipe 0: World 29
Transmission successful! Time to transmit = 52 us. Sent: Hello 30 Received 8 bytes on pipe 0: World 29
Transmission successful! Time to transmit = 63 us. Sent: Hello 30 Received 8 bytes on pipe 0: World 29
Transmission successful! Time to transmit = 60 us. Sent: Hello 30 Received 8 bytes on pipe 0: World 31
Transmission successful! Time to transmit = 53 us. Sent: Hello 32 Received 8 bytes on pipe 0: World 31
Transmission successful! Time to transmit = 57 us. Sent: Hello 32 Received 8 bytes on pipe 0: World 31
Transmission successful! Time to transmit = 61 us. Sent: Hello 32 Received 8 bytes on pipe 0: World 33
Transmission successful! Time to transmit = 52 us. Sent: Hello 34 Received 8 bytes on pipe 0: World 33
Transmission successful! Time to transmit = 64 us. Sent: Hello 34 Received 8 bytes on pipe 0: World 33
Transmission successful! Time to transmit = 62 us. Sent: Hello 34 Received 8 bytes on pipe 0: World 35
Transmission successful! Time to transmit = 56 us. Sent: Hello 36 Received 8 bytes on pipe 0: World 35
kripton commented 3 years ago

Okay, maybe then I got the problem wrong due to the title of this issue report ;) @2bndy5: You are building and running on a 32bit based RPi and get strange output when building the library with CMake? And if you build it "the old way" without CMake it's fine?

2bndy5 commented 3 years ago

@kripton oh, no the traditional way won't compile on 64 bit Ubuntu (running on RPi3 or RPi4 - which both have 64 bit processors); see https://github.com/nRF24/RF24/issues/642#issuecomment-803759895 & https://github.com/nRF24/RF24/issues/642#issuecomment-706420296.

I figured I'd finally take a swing at solving this when testing the CMake for Linux implementation because I'm horribly versed in bash script. Adjusting the old configure file is best left to someone who knows what they're doing. But the CMake solution currently isn't considering the python wrapper (yet), so Ubuntu 64 bit users would still be left to their own devices for pyRF24.

Testing CMake on raspbian (32 bit running on 64 bit CPUs) is successful.

kripton commented 3 years ago

Alright, that means that the behaviour is incorrect when running on aarch64 (the output you posted above). When compiled by CMake since it's not possible to build it using the old scripts. Would be interesting to see how it behaves on x86_64. I'd bet it's a general problem somewhere in the source code (for example using "int" instead of "int32_t" or something....

2bndy5 commented 3 years ago

@kripton I looked into your suggestion, but it didn't pan out...

I was going to open a separate issue about the corrupted data, but then @dylviz opened a new issue #774 trying to tackle a seemingly similar problem with almost identical context.

Seems my problem was the SPI baudrate was set so high (default 10MHz) that data was getting corrupted on the RPi4's SPI bus (tested 4MHz successfully 🎉 ).