24

As Raspberry Pi needs a bit of special code (I'm talking about C/C++) for accessing some hardware features (e.g. a call to bcm_host_init()). I'm looking for a reliable and elegant way to detect this automatically. I don't think there are any compiler #defines such as _WIN32 I could abuse, so detecting it from CMake (which can execute shell scripts) would suffice. I'd also like the method to work in most if not all distros.

One way I can think of is that I could look for e.g. /opt/vc/include/bcm_host.h file (which is not difficult), and also check that the architecture is ARM (which is easy at compile time as there are #define macros for that, e.g. __arm__ of __ARMEL__). This extra arch check is to prevent false-positives when you have a cross-compiling environment on another machine but are not currently cross-compiling. Is there a different, better way than this?

20

Checking at configure/compile time for the features your code depends upon is the way to go. Checking for specific devices is problematic because avoiding false-positives is virtually impossible (someone could lie to you deliberately even with little effort) and the aim of such checks is to answer the question: "can I build here? If yes what code path should I be using?", not "is this a device I like the name of?"


According to this reference (a great source of information on predefined macros in general) you can use the macro:

__arm__

To detect the GCC/Arm combination.

I checked this out on mine with:

#include <stdio.h>

int main() {
  #ifdef __arm__
  printf("Why yes it is, thank you\n");
  #endif
  return 0;
}

Which did indeed print the message.

Note that this will also catch all Arm devices, so my recommendation would be to use part of your build tool (e.g. cmake/autoconf) to check for the presence of /opt/vc/include/bcm_host.h as well.

For example with

AC_CHECK_HEADERS
in autoconf:

AC_CHECK_HEADERS(/opt/vc/include/bcm_host.h)

causes:

HAVE__OPT_VC_INCLUDE_BCM_HOST_H

to be defined in config.h

Or for CMake:

include(CheckIncludeFile)
CHECK_INCLUDE_FILE(/opt/vc/include/bcm_host.h BCMHOST)

I don't think there's a better way of detecting this really - you could have configure/CMake look for hardware specific things, but there will be other platforms out there with the same SoC so even that's not really reliable and what you actually care about is the existence of that header file, since that informs you as to how to build for the given target. Even if you can prove it's a Raspberry Pi but can't find the right header file you're still stuck and an error early on is better than a miss-build.

If you really want to check it is a Pi (or sufficiently similar) you can resort to something simple like:

grep -o BCM2708 /proc/cpuinfo

or (for raspberrypi 2 and 3):

grep -o BCM2709 /proc/cpuinfo

at configure time, which will match the SoC the Raspberry Pi is based on.

You could throw in a few more tests (e.g. USB will help you figure it out a bit more and even hint if it's a Model A or B device), but nothing is sufficient to say for certain.

You could check the hashes of files in /boot against a known list, but then you won't be able to build if there's a firmware update or an unofficial one you didn't know about. (Or other similar non-Pi devices with the same booting setup)

  • Perhaps the description of my idea was not clear enough, but the __ARMEL__ define way is exactly like your __arm__. I just didn't bother to find the best macro yet. – Tapio Jun 26 '12 at 20:40
  • I amended my idea description to clarify that also looking for the file is not the problem - I'm looking for different, better ways to do this, not how to implement the idea I presented. – Tapio Jun 26 '12 at 20:45
  • @Tapio - I don't think that's the right problem - even if you prove it's a Pi that information is useless without the header files you need to build your Pi specific code. Even if you find a BCM non-Pi device the code you write for the Pi will probably run just fine on that if it's based on the same SoC. – Flexo Jun 26 '12 at 20:54
  • You are right. That thought crossed my mind, but I didn't think about it enough. Anyway, your edits make this an excellent answer well worth accepting. – Tapio Jun 26 '12 at 21:06
  • 2
    The check for /opt/vc/include/bcm_host.h - how does that work for cross-compiling as the file is unlikely to be in that place on the (compiling) host machine? Similarly grep -o BCM2grep -o BCM2708 /proc/cpuinfo708 /proc/cpuinfo is going to detect the compilation host not the target...? – SlySven Jan 10 '16 at 3:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.