Comment puis-je détecter que je compile pour Raspberry Pi?

24

Comme Raspberry Pi a besoin d'un peu de code spécial (je parle C/C++) pour accéder à certaines fonctionnalités matérielles (par exemple, un appel à bcm_host_init()). Je cherche un moyen fiable et élégant de détecter cela automatiquement. Je ne pense pas qu'il existe de compilateur #definestel que _WIN32je pourrais abuser, donc le détecter CMake(qui peut exécuter des scripts shell) suffirait. J'aimerais également que la méthode fonctionne dans la plupart, sinon dans toutes les distributions.

Une façon dont je peux penser est que je pourrais chercher par exemple un /opt/vc/include/bcm_host.hfichier (ce qui n'est pas difficile), et également vérifier que l'architecture est ARM (ce qui est facile au moment de la compilation car il existe des #definemacros pour cela, par exemple __arm__de __ARMEL__). Cette vérification d'archivage supplémentaire vise à éviter les faux positifs lorsque vous disposez d'un environnement de compilation croisée sur une autre machine mais que vous ne procédez pas actuellement à la compilation croisée. Existe-t-il un moyen différent et meilleur que celui-ci?

Tapio
la source

Réponses:

20

La vérification au moment de la configuration / compilation des fonctionnalités dont dépend votre code est la voie à suivre. La vérification de périphériques spécifiques est problématique car éviter les faux positifs est pratiquement impossible (quelqu'un pourrait vous mentir délibérément même avec peu d'effort) et le but de ces vérifications est de répondre à la question: "puis-je construire ici? Si oui, quel chemin de code doit J'utilise? " , pas "est-ce un appareil dont j'aime le nom?"


Selon cette référence (une excellente source d'informations sur les macros prédéfinies en général), vous pouvez utiliser la macro:

__arm__

Pour détecter la combinaison GCC / Arm.

J'ai vérifié cela sur le mien avec:

#include <stdio.h>

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

Ce qui a effectivement imprimé le message.

Notez que cela interceptera également tous les appareils Arm, donc ma recommandation serait d'utiliser une partie de votre outil de construction (par exemple cmake/autoconf) pour vérifier la présence de /opt/vc/include/bcm_host.h.

Par exemple avec

AC_CHECK_HEADERS
en autoconf:

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

provoque:

HAVE__OPT_VC_INCLUDE_BCM_HOST_H

à définir dans config.h

Ou pour CMake:

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

Je ne pense pas qu'il y ait vraiment une meilleure façon de détecter cela - vous pourriez avoir configurer / CMake chercher des choses spécifiques au matériel, mais il y aura d'autres plates-formes avec le même SoC donc même ce n'est pas vraiment fiable et ce qui vous intéresse réellement est l'existence de ce fichier d'en-tête, car cela vous informe sur la façon de construire pour la cible donnée. Même si vous pouvez prouver qu'il s'agit d'un Raspberry Pi mais que vous ne trouvez pas le bon fichier d'en-tête, vous êtes toujours bloqué et une erreur au début vaut mieux qu'une erreur de construction.

Si vous voulez vraiment vérifier qu'il s'agit d'un Pi (ou suffisamment similaire), vous pouvez recourir à quelque chose de simple comme:

grep -o BCM2708 /proc/cpuinfo

ou (pour raspberrypi 2 et 3):

grep -o BCM2709 /proc/cpuinfo

au moment de la configuration, qui correspondra au SoC sur lequel le Raspberry Pi est basé.

Vous pouvez lancer quelques tests supplémentaires (par exemple, l'USB vous aidera à comprendre un peu plus et même à indiquer s'il s'agit d'un appareil de modèle A ou B), mais rien ne suffit pour le dire avec certitude.

Vous pouvez vérifier les hachages des fichiers dans / boot par rapport à une liste connue, mais vous ne pourrez pas créer s'il y a une mise à jour du micrologiciel ou non officielle que vous ne connaissiez pas. (Ou d'autres appareils non Pi similaires avec la même configuration de démarrage)

Flexo
la source
Peut-être que la description de mon idée n'était pas assez claire, mais la __ARMEL__façon de définir est exactement comme la vôtre __arm__. Je n'ai tout simplement pas pris la peine de trouver la meilleure macro pour le moment.
Tapio
J'ai modifié la description de mon idée pour clarifier que la recherche du fichier n'est pas non plus le problème - je recherche des façons différentes et meilleures de le faire, pas la façon de mettre en œuvre l'idée que j'ai présentée.
Tapio
@Tapio - Je ne pense pas que ce soit le bon problème - même si vous prouvez que c'est un Pi que les informations sont inutiles sans les fichiers d'en-tête dont vous avez besoin pour construire votre code spécifique Pi. Même si vous trouvez un périphérique BCM non Pi, le code que vous écrivez pour le Pi fonctionnera probablement très bien si il est basé sur le même SoC.
Flexo
Vous avez raison. Cette pensée me traversa l'esprit, mais je n'y pensai pas assez. Quoi qu'il en soit, vos modifications en font une excellente réponse qui mérite d'être acceptée.
Tapio
2
La vérification /opt/vc/include/bcm_host.h- comment cela fonctionne-t-il pour la compilation croisée car le fichier est peu susceptible d'être à cet endroit sur la machine hôte (de compilation)? De même, grep -o BCM2grep -o BCM2708 /proc/cpuinfo708 /proc/cpuinfova détecter l'hôte de compilation pas la cible ...?
SlySven