应该在多大程度上采用#ifdef语句来实现硬件灵活性

时间:2015-05-21 07:30:39

标签: c coding-style arduino embedded

据我了解,在嵌入式系统程序中为不同硬件包含不同选项的最佳方法之一是#ifdef语句。在风格上,这应该走多远?我想具体一点,如果有人在功能减速时使用#ifdef,你会摇头吗?

对我来说这感觉很傻,但是一个硬件选项需要不同类型的函数参数而不是另一个选项。是否有更简洁的方法来实现这种效果,或者更好地使用次优代码来实现某些硬件选项?

如果要阅读的文字太多而您更喜欢代码:

#ifdef internaldac
    int dacWrite(int level) {
#else 
    int dacWrite(byte highbyte, byte lowbyte) {
#endif  

我认为这是写这个的最有效方式,但我应该采用另一种方式(风格)吗?

3 个答案:

答案 0 :(得分:6)

您应该创建硬件抽象层(HAL)。 HAL中的代码封装了所有硬件特定的差异。调用HAL的更高级代码不应该知道任何特定于硬件的差异,因为HAL已将这些细节抽象为更通用的接口。

您的示例不会抽象差异,而是以不同参数的形式将差异传递给更高级别的代码。更高级别的代码需要检查硬件类型,以便它可以对dacWrite()进行适当的调用。

作为替代方案,请考虑如何将int levelbyte highbyte, lowbyte抽象为一个与硬件无关的更通用的参数。然后调用dacWrite()的更高级代码不需要知道它运行的硬件。相反,dacWrite()会处理细节。

我不确定这在技术上是否适合您的情况,但这是一个例子。

    int dacWrite(int level) {
#ifdef internaldac
        byte highbyte = (level >> 8) & 0xFF;
        byte lowbyte = level & 0xFF;
#endif 
    ...
    }

答案 1 :(得分:0)

我使用的代码划分方法(可能还有更多):

  • #ifdef inside method - 声明未分割
  • #ifdef使用不同的参数 - 如上所述
  • 不同的方法在一个文件中命名一个文件和#ifdef来划分
  • 相同的方法名称和文件名但文件的位置不同(文件夹,目录)
  • 不同的方法名称不同的文件名

如果在共享代码中有很多dacWrite调用,那么如果你能用这样的方式包装它就会很好,可以在没有#ifdef的情况下使用newDacWrite调用。

答案 2 :(得分:0)

使用相同的二进制文件来覆盖硬件变体通常很方便。例如,生产更简单,如果你有某种固件升级系统,那就更简单了。

这意味着调整DAC功能,以便动态确定硬件类型并相应地运行,采用适合任何一种类型的args。

其余代码则独立于硬件类型。