wiringPi error message after update/upgrade RPi Debian lite distro

1132 views
Skip to first unread message

GeertVc

unread,
Jul 9, 2017, 6:27:46 AM7/9/17
to Pi4J
This morning, I did an update/upgrade of my RPi Debian lite distro.  Quite a lot of new things came in, amongst others, kernel related stuff.

Before, I ran an application that went fine for a long time.  However, after the update/upgrade, I all of a sudden got the following output:

Unable to determine hardware version. I see: Hardware   : BCM2835
,
 - expecting BCM2708 or BCM2709.
If this is a genuine Raspberry Pi then please report this
to proj...@drogon.net. If this is not a Raspberry Pi then you
are on your own as wiringPi is designed to support the
Raspberry Pi ONLY.

This was the result of the command "SystemInfo.getCpuArchitecture());"

When I checked the code in Pi4J, I came to know it's reading /proc/cpuinfo at a certain moment in the file .\pi4j-core\src\main\java\com\pi4j\system\impl\DefaultSystemInfoProvider.java, method getCpuInfo().  This method is called from the following public method:

    @Override
    public String getCpuArchitecture() throws IOException, InterruptedException, UnsupportedOperationException {
        return getCpuInfo("CPU architecture");
    }

As a result, after the upgrade, the string BCM2835 is returned.

When I look to othe RPi's I have which did not update/upgrade yet, I get BCM2709 as return value.  So, the new kernel is indeed putting a different string in the /proc/cpuinfo file!

When I look into the wiringPi code, file wiringPi.c (from the original repository, not the Pi4J repository), I see in the newest version that the string BCM2835 has been added because of a change in the newer kernel.  See below:

// See if it's BCM2708 or BCM2709 or the new BCM2835.

// OK. As of Kernel 4.8,  we have BCM2835 only, regardless of model.
//    However I still want to check because it will trap the cheapskates and rip-
//    off merchants who want to use wiringPi on non-Raspberry Pi platforms - which
//    I do not support so don't email me your bleating whinges about anything
//    other than a genuine Raspberry Pi.

  if (! (strstr (line, "BCM2708") || strstr (line, "BCM2709") || strstr (line, "BCM2835")))
  {
    fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ;
    fprintf (stderr, " - expecting BCM2708, BCM2709 or BCM2835.\n") ;
    fprintf (stderr, "If this is a genuine Raspberry Pi then please report this\n") ;
    fprintf (stderr, "to proj...@drogon.net. If this is not a Raspberry Pi then you\n") ;
    fprintf (stderr, "are on your own as wiringPi is designed to support the\n") ;
    fprintf (stderr, "Raspberry Pi ONLY.\n") ;
    exit (EXIT_FAILURE) ;
  }

So, to solve this issue, I'm afraid we have to or move to the newer wiringPi code (I don't think the current wiringPi in Pi4J 1.1 is the latest one) or modify the current wiringPi code in the Pi4J 1.1

However, it's not clear to me if wiringPi is taken along in the maven build to creat the libpi4j.so.  Is it?  If so, would it be an "easy" task to throw in the latest wiringPi source code and put that into libpi4j.so?

If it's not, how to cope with the above?

Olivier Le Diouris

unread,
Jul 17, 2017, 3:27:43 PM7/17/17
to Pi4J
I had the same issue, and it was fixed by using a more recent PI4J, here is a snippet of Gradle that takes care of it:

repositories {
mavenCentral()
mavenLocal()
maven { url "https://oss.sonatype.org/content/groups/public" }
}

dependencies {
// compile 'com.pi4j:pi4j-core:1.1'
compile 'com.pi4j:pi4j-core:1.2-SNAPSHOT'
}

- Olivier

cee...@gmail.com

unread,
Jul 20, 2017, 10:17:58 AM7/20/17
to Pi4J
First of all, to the devs, please don't take my criticism too severely. :) You have built a damn good library which is quite fancy and practical to use. :)

But yes, today it broke things for me unexpectedly (and most likely, it will break stuff for more people as soon as they upgrade kernel)... and there's a lot of people using mainline hardware and software and either directly relying on Pi4J or using some package that uses it.

I tried the Pi4J 1.2 binary snapshot, but it didn't help. I had too little time to edit out the version string check and recompile from sources, so I downgraded kernel from 4.9.35 to 4.4.50 and it helped. :)

But please, consider if you must check for this kind of things for the purpose of checking only... I wouldn't. Alternatively, if you feel that you must check because people are asking you to support random hardware configurations... maybe consider outputting a message about not wanting to support a multitude of clones instead of mainline hardware, and don't call exit() if you aren't certain that mainline hardware (which has lots of users) will never produce wrong values for your check.

I don't know what the situation looks like from your perspective, but to me, that version string check looks like politics in source code which *can* come back to bite everyone at precisely the most inconvenient time. :)

And best wishes. :) I wish I could contribute to the project, but I use it only occasionally and it's worked too well for me, so I haven't found any bugs to fix. :)

GeertVc

unread,
Jul 20, 2017, 2:19:29 PM7/20/17
to Pi4J
Keep in mind that those guys who delivered those "damn good libraries" doing this in their free time, free of charge and so on.  I personally admire their determination to put a lot of free time in such project.

That said, I've been able to build the whole Pi4J suite, including the native wiringPi on a Linux machine (Linux OS running in VirtualBox on my windows machine), solving the issue I mentioned above.  It took me some time but I finally got there.

If you're interested, be patient.  I'll write it down in this thread, but it won't be until tomorrow (earliest) before I will find some time to do so.

As they say: "Stay tuned!".

GeertVc

unread,
Jul 21, 2017, 8:35:23 AM7/21/17
to Pi4J
As promised, find below the steps I took to get the whole Pi4J library - including the native wiringPi part - build on a Linux machine, without the need for a RPi to build the wiringPi part.

On a Windows 10 Home Edition machine, I did:
  • install VirtualBox to be able to run a Linux distro on my regular PC
  • install ChaletOS, a quite new and truely interesting Linux distro; pay attention you install the 32-bit version, not the 64-bit version (if you do so, the libraries will be compiled according the "ELF64" class in stead of the "ELF32" class and 64 bits, that can't be handled by the RPi (2B, as I have...)
  • install Java, including specifying the JAVA_HOME env var (as of this writing, Java 1.8.0_131-b11 is the latest version); also make sure you take the 32 bit version here. This is a good reference explaining how to install Java.
  • install Git
  • install tree
  • install Maven (as of this writing, Maven 3.5.0 is the latest version); make sure the path is part of your PATH env var.
  • install the Raspberry Pi toolchain (see this page, section CROSS-COMPILING) on how to do that); you need that toolchain because it contains the cross compiler for the ARM architecture.  Again, use the 32 bit variant here.  Make sure the path is part of your PATH env var.
  • clone the Pi4J repository from GitHub: git clone https://github.com/Pi4J/pi4j.git

Once all the above is done, the following two files in the Pi4J repository need small modificatoins:

  • ./pi4j-native/pom.xml: on line 18, replace
    <pi4j-native-ant-build-target>build-libpi4j.so-remote</pi4j-native-ant-build-target>
    with
    <pi4j-native-ant-build-target>build-libpi4j.so-local</pi4j-native-ant-build-target>
  • ./pi4j-native/build.xml: on line 157, replace
    name="${raspberrypi.name}"/>
    with
    name="${raspberrypi.name}"
    args="ARCH=arm CC=arm-linux-gnueabihf-gcc"/>
Once the above is done, you can go to the ./pi4j directory and run the command mvn clean install -P raspberrypi.  When all goes fine, you should end up with the correct libraries in the path ./pi4j/pi4j-distribution/target/distro-contents/lib.  Those should be ready to use for the RPi projects.  At least, that was the case for me...

Note: if, during compilation,there's still something missing, you can easily get it through sudo apt-get install ... .  I've tried to be as complete as possible, but chances are I still did forget something to mention in the above list, that I installed on my system.  Bear with me... ;-)

cee...@gmail.com

unread,
Jul 21, 2017, 4:26:09 PM7/21/17
to Pi4J
Thanks, the cross-compiling tip about "build.xml" proved useful even if my platform is different. :)

Robert Savage

unread,
Aug 5, 2017, 10:58:58 AM8/5/17
to Pi4J
@GeertVc,

FYI, you should not have to modify the build scripts to cross compile on linux.  You should just be able to use the "cross-compile" Maven profile .

mvn clean install -Pcross-compile,raspberrypi


Please let me know if that's not working for you.  I just tested it here on Ubuntu with a RPI toolchain installed and it seems to be working.

Thanks, Robert

GeertVc

unread,
Aug 5, 2017, 1:30:18 PM8/5/17
to Pi4J
Hi Robert,

First off, I didn't know you could add an extra item to the -P parameter of Maven; I always tried -P raspberrypi (as is indicated in the build instructions of the project).  This shows I'm not (yet?) a Maven expert...

I studied the differences between the XML files of release1.1 and master and now I understand why there's no need to do modifications to the build scripts if you're using the master branch from git.

The changes I did locally for the XML files for release1.1 are now part of the master branch.  I'm referring to the build.xml file, where for the cross compilation the args="ARCH=arm CC=arm-linux-gnueabihf-gcc" item has been added to indicate to the build system that not the gcc compiler should be used (which is OK if you build on the RPI, since gcc is in that case the arm-linux-gnueabihf-gcc compiler) but instead the cross compiler should be used.  That was not there in the build.xml file for the native part in release1.1 and that's what I had to figure out and add myself to get the wiringPi correctly built into the libpi4j.so file...

I did some initial tests with the master branch on my hardware (mainly I2C related) and at least I don't see the wiringPi error message (mismatch of hardware name for the BCM2709/BCM2835 processor) any more.
I will do some more in-depth tests, especially around I2C, and if I still find issues I'll come back on it here in this thread.

Anyhow, it's good to know that my changes are not needed anymore for the master branch (which will probably become version pi4j_1.2 in due time, right?).  However, for people that still want to use release 1.1 in combination with the most recent version of wiringPi for one reason or another, my changes are still needed.

Thanks anyway for pointing this out.

Best rgds,
--Geert

GeertVc

unread,
Aug 6, 2017, 5:30:40 AM8/6/17
to Pi4J
Hi Robert,

I want to come back on my previous answer (just above) regarding the cross-compilation for RPi on a Linux machine.

With your solution, you indeed don't have to change anything towards the build files, you only have to invoke it with the correct parameters, being -Pcross-compile,raspberrypi.

What I did before, was to force the build system to go into a local environment in stead of a remote environment, because I thought "remote" meant building wiringPi on the RPi and "local" meant building wiringPi on the Linux machine using a cross-compiler.

Therefor, in the build.xml file, I had to add the cross-compiler args to the targets in the "LOCAL PLATFORM BUILD TARGETS" section which was, seen afterwards, totally not needed...

Conclusion: when you're on the master branch, my changes are totally unnecessary...

Best rgds,
--Geert

Robert Savage

unread,
Aug 6, 2017, 10:08:40 AM8/6/17
to Pi4J
The build environment for the native bits is a bit complicated/confusing and the chain between maven, ant, and bash script files makes its a bit of a treasure hunt to find the right path.  
The project could probably use some updated documentation for building the native bits.  

So in theory anyone should be able to build the entire Pi4J project locally on their Pi (albeit it make take a long time) or remotely where all the java bits are compiled on their workstation and the native parts are compiled on a Pi using SSH/SCP or using the cross-compiler option to build all of the project on their (linux) workstation.  

I mostly build using the default "remote" option because I am building from an OSX workstation and have never setup the cross-compiler to work on my OSX desktop.  So the native builds gets remotely build on a RPI3 on my network.
For deployed snapshot and release builds I always build using the "remote" option where the native libraries are build directly on the ARM platform.  I'm probably just paranoid that way and should have more confidence in the cross compiler.  

The Travis CI builds do use the cross compiler option since its built entirely on a Linux VM in the cloud.


For the 1.1 branch ... it looks like there is a "cross-compile" profile option here:
In theory it should cause the "build-local-cross-compile.sh" script to get invoked to do the native builds.  
But I have not tested this in some time so I won't profess to say it all works properly :-) 

Cheers,
Robert




Reply all
Reply to author
Forward
0 new messages