为了硬件灵活性,#ifdef 语句应该走多远

How far should one take #ifdef statements for hardware flexibility

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

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

如果文字太多难以阅读,而您更喜欢代码:

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

我认为这是最有效的写法,但我应该换一种方式(风格上)吗?

我使用的分码方法(应该还有很多):

  • 方法内部的#ifdef - 声明不被分割
  • #ifdef 有不同的参数 - 和你上面的一样
  • 不同的方法命名一个文件和一个文件中的#ifdef来分割
  • 方法名和文件名相同但文件位置不同(文件夹、目录)
  • 不同的方法名不同的文件名

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

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

这意味着编写您的 DAC 函数,以便它动态确定硬件类型并相应地运行,采用适合任一类型的参数。

其余代码与硬件类型无关。

您应该创建一个硬件抽象层 (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 
    ...
    }