由于Raspberry Pi需要一些特殊的代码(我在说C/C++)来访问某些硬件功能(例如,对bcm_host_init()的调用)。我正在寻找一种可靠且优雅的方法来自动检测到此情况。我认为没有可以滥用的编译器#defines(例如_WIN32),因此从CMake(可以执行shell脚本)中检测它就足够了。我也希望该方法在大多数发行版中都可以使用。

我可以想到的一种方法是,我可以寻找例如/opt/vc/include/bcm_host.h文件(这并不困难),并检查架构是否为ARM(在编译时很容易,因为存在#define宏,例如__arm____ARMEL__)。当您在另一台计算机上有交叉编译环境但当前未交叉编译时,此额外的arch检查是为了防止错误肯定。有没有比这更好的方法了?

#1 楼

在配置/编译时检查代码所依赖的功能是正确的方法。检查特定设备是有问题的,因为避免假阳性几乎是不可能的(即使不费吹灰之力也可能有人故意对您说谎),并且此类检查的目的是回答以下问题:“我可以在这里构建吗?如果是,应该使用什么代码路径我正在使用吗?”,而不是“这是我喜欢的设备吗?”


根据此参考文献(一般来说,有关预定义宏的大量信息来源),您可以使用宏:

__arm__


要检测GCC /手臂组合。

我在矿井上用以下方法进行了检查:

 #include <stdio.h>

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


确实打印了消息。

请注意,这还将捕获所有消息。武装设备,所以我的建议是使用构建工具的一部分(例如cmake/autoconf)来检查/opt/vc/include/bcm_host.h的存在。



例如在autoconf中使用
AC_CHECK_HEADERS




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


原因:



HAVE__OPT_VC_INCLUDE_BCM_HOST_H


可以在config.h中定义

或用于CMake:



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



我认为没有更好的方法可以检测到此问题-您可以配置/ CMake查找硬件特定的东西,但是会有其他具有相同SoC的平台,所以即使这不是真的可靠,您真正关心的是该头文件的存在,因为这会告诉您如何为给定目标进行构建。即使您可以证明它是Raspberry Pi,但找不到正确的头文件,仍然会卡住,而且早期出错比未完成编译要好。

如果您真的要检查它是一个Pi(或足够相似),您可以诉诸以下简单方法:

grep -o BCM2708 /proc/cpuinfo


或(对于raspberrypi 2和3):

grep -o BCM2709 /proc/cpuinfo


在配置时,它将与Raspberry Pi所基于的SoC相匹配。

您还可以进行一些测试(例如USB将帮助您弄清楚它的位置,甚至暗示它是A型还是B型设备),但还不能肯定地说。

您可以根据已知列表检查/ boot中文件的哈希值,但是如果有固件更新或您不知道的非正式更新,则将无法构建。 (或其他具有相同启动设置的类似非Pi设备)

评论


也许我对这个想法的描述不够清楚,但是__ARMEL__的定义方式与您的__arm__完全一样。我只是没有去寻找最好的宏。

–塔皮奥
2012年6月26日20:40

我修改了我的想法描述,以澄清寻找文件也不是问题-我正在寻找其他更好的方法来实现此目的,而不是如何实现我提出的想法。

–塔皮奥
2012年6月26日20:45

@Tapio-我认为这不是正确的问题-即使您证明是Pi,没有头文件的信息也无用,您需要构建特定于Pi的代码。即使您找到了BCM非Pi器件,但如果您为Pi编写的代码基于同一SoC,则在该代码上也可以很好地运行。

–柔印
2012年6月26日20:54

你是对的。这个想法让我念念不忘,但我想得还不够。无论如何,您的编辑使它成为一个很好的答案,非常值得接受。

–塔皮奥
2012年6月26日21:06

检查/opt/vc/include/bcm_host.h-交叉编译如何工作,因为文件不太可能位于(编译)主机上的那个位置?同样,grep -o BCM2grep -o BCM2708 / proc / cpuinfo708 / proc / cpuinfo将检测编译主机而不是目标主机...?

– SlySven
16 Jan 10'在3:38