【问题标题】:How to make unit tests for embedded code?如何对嵌入式代码进行单元测试?
【发布时间】:2017-07-19 15:30:00
【问题描述】:

我正在为基于 Cortex-M4 的 C++ 微控制器开发软件。我有很多高度依赖机器的代码(驱动程序等)。而且我有更高级别的代码,它通过直接使用驱动程序密切依赖于低级代码。示例:低级部分是例如。一个硬件专用的UART驱动程序,高级部分是基于UART的通信协议。 (此软件运行在“裸机”上,即下面没有操作系统。)

此代码目前是紧密耦合的,因此不可单元测试。
我想让它可测试。

所以我想我会创建一个低级部分的抽象,并使高级部分只依赖于抽象。然后我可以创建单元测试将使用的抽象的模拟,以及将在微控制器上运行的真实实现。

  • 这是正确的方法吗?
  • 如何创建这样的抽象?
    大多数sourcesI've found 强烈反对在嵌入式系统中使用继承和virtual 函数。还有什么其他方法?

所以,总而言之,我想创建一个硬件抽象层 (HAL),但我想问怎么做?我应该在 C++ 中使用virtual 继承,还是有其他更好的方法?

【问题讨论】:

  • 您建议的抽象将是一个硬件抽象层,这并不罕见,事实上完全可以。您将在每个 HAL 上定义接口并实现它们。对于 Mocks,您只需实现该接口并提供所需的行为。
  • 如果你不想虚拟化,你仍然可以有两个实现。由于您永远不会同时需要两者,请指示您的工具链构建并链接正确的实现。
  • @Samer Tufail:除了性能影响之外,通常的论点是,通过使用函数指针,调用图不再是静态的。因此,在安全关键型系统中很难呈现静态工具辅助证明,例如最大堆栈使用率和分支覆盖率。
  • @doynax:这是一个安全的关键系统吗?如果是,那么您将遇到一系列不同的问题,并且动态内存排在首位。
  • @Samer Tufail:当然。不过,我对 OPs 应用程序一无所知。

标签: c++ unit-testing embedded abstraction


【解决方案1】:

对于 C++,我建议使用接口,假设我们有一个 HAL.hpp,并在其中定义我们想要实现的纯虚函数:

class HAL
{
    virtual void func1() = 0;
    virtual void func2() = 0;
};

然后你可以让你的Mock.cpp 实现这个,你可以让一个 Real.cpp 实现同样的:

Mock.cpp:
class Mock : HAL
{
        virtual void func1(){ }
        virtual void func2(){ }
}

现在另一种方法是您在HAL.h 中定义您的函数,并且在此处不提供任何实现:

void func1();
void func2();

然后您创建一个HAL.cpp 并在其中添加您希望在目标上看到的功能。将所有这些创建为名为 HAL 的库。将此库链接到您的主项目。

现在进行模拟和测试。为您的测试创建一个单独的项目。添加要测试但不链接 HAL 库的源。而是创建另一个源文件 Mock.cpp 包含 HAL.h 并为其提供实现。这样,将调用 Mock 的实现,而不是 HAL 库中的功能。

【讨论】:

    【解决方案2】:

    在与模拟 HAL 不同的文件中创建微控制器 HAL。对于微控制器,在您的项目中包含微控制器 HAL 源。对于单元测试系统,在您的项目中包含模拟 HAL 源代码。

    您还可以通过使用编译器宏定义来切换模拟 HAL 片段并切换出微控制器 HAL 片段,从而在目标上进行测试。

    您甚至可以使用调试器强制接口点的值触发所有路径;使用代码覆盖工具执行此操作将让您知道您是否已经使用了所有路径(如果需要,还可以使用 MC/DC)。这有时是模拟硬件故障或异常情况的唯一方法。

    【讨论】:

      猜你喜欢
      • 2012-11-27
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多