Como posso detectar que estou compilando para o Raspberry Pi?

24

Como o Raspberry Pi precisa de um pouco de código especial (estou falando C/C++) para acessar alguns recursos de hardware (por exemplo, uma chamada para bcm_host_init()). Estou procurando uma maneira confiável e elegante de detectar isso automaticamente. Eu não acho que exista algum compilador #definesque _WIN32eu possa abusar, portanto, detectá-lo CMake(que pode executar scripts de shell) seria suficiente. Eu também gostaria que o método funcionasse na maioria, senão em todas as distros.

Uma maneira que eu posso pensar é que eu poderia procurar por exemplo /opt/vc/include/bcm_host.harquivo (que não é difícil), e também verificar que a arquitetura é ARM (que é fácil em tempo de compilação, pois há #definemacros para que, por exemplo, __arm__da __ARMEL__). Essa verificação de arco extra é para evitar falsos positivos quando você tem um ambiente de compilação cruzada em outra máquina, mas atualmente não está compilando. Existe uma maneira diferente e melhor que essa?

Tapio
fonte

Respostas:

20

Verificar no tempo de configuração / compilação os recursos de que seu código depende é o caminho a percorrer. A verificação de dispositivos específicos é problemática porque é praticamente impossível evitar falsos positivos (alguém pode mentir para você deliberadamente, mesmo com pouco esforço) e o objetivo dessas verificações é responder à pergunta: "posso criar aqui? Se sim, qual caminho de código deve Eu estou usando? " , não "é um dispositivo do qual gosto do nome?"


De acordo com esta referência (uma ótima fonte de informações sobre macros predefinidas em geral), você pode usar a macro:

__arm__

Para detectar a combinação GCC / braço.

Eu verifiquei isso no meu com:

#include <stdio.h>

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

O que realmente imprimiu a mensagem.

Observe que isso também captura todos os dispositivos Arm, portanto, minha recomendação seria usar parte de sua ferramenta de construção (por exemplo cmake/autoconf) para verificar a presença deles /opt/vc/include/bcm_host.h.

Por exemplo, com

AC_CHECK_HEADERS
no autoconf:

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

causas:

HAVE__OPT_VC_INCLUDE_BCM_HOST_H

a ser definido em config.h

Ou para o CMake:

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

Eu não acho que realmente exista uma maneira melhor de detectar isso - você pode configurar / CMake para procurar coisas específicas de hardware, mas haverá outras plataformas com o mesmo SoC, mesmo que isso não seja realmente confiável e com o que você realmente se importa é a existência desse arquivo de cabeçalho, pois isso informa como criar para o destino especificado. Mesmo se você puder provar que é um Raspberry Pi, mas não conseguir encontrar o arquivo de cabeçalho correto, você ainda está preso e um erro no início é melhor do que um erro de construção.

Se você realmente deseja verificar se é um Pi (ou suficientemente semelhante), pode recorrer a algo simples como:

grep -o BCM2708 /proc/cpuinfo

ou (para raspberrypi 2 e 3):

grep -o BCM2709 /proc/cpuinfo

no momento da configuração, que corresponderá ao SoC no qual o Raspberry Pi se baseia.

Você pode fazer mais alguns testes (por exemplo, o USB o ajudará a descobrir um pouco mais e até a sugerir se é um dispositivo modelo A ou B), mas nada é suficiente para dizer com certeza.

Você pode verificar os hashes dos arquivos em / boot em uma lista conhecida, mas não poderá criar se houver uma atualização de firmware ou uma atualização não oficial que você não conhecia. (Ou outros dispositivos não Pi semelhantes com a mesma configuração de inicialização)

Flexo
fonte
Talvez a descrição da minha ideia não tenha sido clara o suficiente, mas a __ARMEL__maneira de definir seja exatamente igual à sua __arm__. Só não me preocupei em encontrar a melhor macro ainda.
Tapio
Alterei a descrição da minha ideia para esclarecer que também procurar o arquivo não é o problema - estou procurando maneiras melhores e diferentes de fazer isso, não como implementar a ideia que apresentei.
Tapio
@ Tapio - Eu não acho que esse seja o problema certo - mesmo se você provar que é um Pi que as informações são inúteis sem os arquivos de cabeçalho necessários para criar seu código específico do Pi. Mesmo se você encontrar um dispositivo BCM não Pi, o código que você escrever para o Pi provavelmente funcionará muito bem se for baseado no mesmo SoC.
Flexo
Você está certo. Esse pensamento passou pela minha cabeça, mas eu não pensei o suficiente. De qualquer forma, suas edições fazem desta uma excelente resposta que vale a pena aceitar.
Tapio
2
A verificação /opt/vc/include/bcm_host.h- como isso funciona para a compilação cruzada, pois é improvável que o arquivo esteja naquele local na máquina host (compilada)? Da mesma forma grep -o BCM2grep -o BCM2708 /proc/cpuinfo708 /proc/cpuinfovai detectar o host de compilação e não o destino ...?
precisa saber é o seguinte