单元测试设备驱动程序

Nou*_*him 27 embedded unit-testing drivers

我有一种情况需要为嵌入式硬件的某些设备驱动程序编写一些单元测试.代码很老很大,很遗憾没有很多测试.现在,唯一可能的测试是完全编译操作系统,将其加载到设备上,在现实场景中使用它并说"它有效".没有办法测试单个组件.

我在这里遇到了一个很好的线程,它讨论了嵌入式设备的单元测试,我从中获得了大量信息.我想更具体一点,并询问是否有人在这种情况下测试设备驱动程序是否有任何"最佳实践".我不希望能够模拟有问题的电路板正在与之交谈的任何设备,因此可能必须在实际硬件本身上测试它们.

通过这样做,我希望能够获得驱动程序的单元测试覆盖率数据,并诱使开发人员编写测试以增加其驱动程序的覆盖范围.

我遇到的一件事是编写在操作系统上运行的嵌入式应用程序并运行驱动程序代码,然后将结果传回测试工具.该设备有几个接口,我可以使用它来从我的测试PC驱动应用程序,以便我可以运用代码.

任何其他建议或见解将非常感谢.


更新:虽然它可能不是确切的术语,但当我说单元测试时,我的意思是能够测试/练习代码而无需编译整个OS +驱动程序并将其加载到设备上.如果我必须这样做,我会称之为集成/系统测试.

问题是我们所拥有的硬件是有限的,开发人员经常使用它们来修复错误等.要保持一个专用的并连接到CI服务器和自动化测试的机器可能是不可能的这个阶段.这就是为什么我正在寻找测试驱动程序的方法,而无需实际构建整个程序并将其上传到设备上.


摘要

基于下面的优秀答案,我认为解决问题的合理方法是使用IOCTL公开驱动程序功能,然后在嵌入式设备的应用程序空间中编写测试以实际运行驱动程序代码.

让一个小程序驻留在设备的应用程序空间中也是有意义的,它暴露了一个可以通过串行或USB运行驱动程序的API,这样单元测试的内容就可以写在PC上了,它将与PC通信.硬件并运行测试.

如果项目刚刚启动,我认为我们可以更好地控制组件的隔离方式,以便主要在PC级别进行测试.鉴于编码已经完成并且我们正在尝试将测试工具和案例改装到系统上,我认为上述方法更实用.

谢谢大家的回答.

Cra*_*een 7

真正依赖于硬件(分层体系结构中驱动程序堆栈的最低级别)的代码无法真正在任何地方进行测试,除了在硬件上,或者在硬件的高质量模拟上。

如果您的驱动程序具有某些不直接依赖于硬件的高级功能组件(例如,用于以特定格式向硬件发送消息的协议处理程序),并且该部分在代码中很好地自包含,则您可以在基于 PC 的单元测试框架中单独进行单元测试。

回到最底层——如果它依赖于硬件,那么测试夹具需要包括硬件。您可以制作包含硬件、驱动程序和一些测试软件的测试夹具。我认为主要是将正常产品的应用程序代码从测试中取出,并放入一些测试代码。测试代码可以系统地测试驱动程序的所有功能和极端情况(应用程序代码可能不会),并且还可以在短时间内真正深入地锤击驱动程序(应用程序可能不会)。因此,与仅运行应用程序相比,它可以更有效地利用有限的硬件,并为您提供更好的结果。

如果您可以将 PC 加入循环,那么 PC 可能有助于测试。例如,如果您正在为嵌入式设备编写串行端口驱动程序,那么您可以:

  • 为发送各种已知数据流的嵌入式设备编写测试代码。
  • 将其连接到 PC 的串行端口,运行测试代码以验证传输的数据流。
  • 另一个方向相同——PC发送数据;嵌入式设备接收并验证它,并将任何错误通知 PC。
  • 这些测试可以全速传输数据,并使用一系列不同的字节计时(我曾经发现一个微控制器 UART 硅错误,该错误仅在字节之间以约 5 毫秒的延迟发送字节时才会出现)。

您可以使用以太网驱动程序、Wi-Fi 驱动程序做类似的事情。

如果您正在测试存储设备驱动程序,例如 EEPROM 或闪存芯片,则 PC 无法以同样的方式参与其中。在这种情况下,您的测试工具可以测试各种写入条件(单字节、块...),并使用各种读取条件验证数据完整性。


wal*_*lyk 5

在过去,这就是我们测试和调试设备驱动程序的方式.调试这种系统的最佳方法是让工程师将嵌入式系统用作开发系统,并且一旦达到足够的系统成熟度,就可以取消原有的交叉开发系统!

根据您的情况,我想到了几种方法:

  • 添加ioctl处理程序:每个代码执行特定的单元测试
  • 使用条件编译,将main()添加到驱动程序中,该驱动程序在驱动程序中执行功能单元测试并将结果输出到stdout.
  • 为了便于调试,可能可以将其设置为多平台可操作,这样您就不必在目标硬件上进行调试.
  • 也许条件代码也可以模拟环回式设备.

  • 如果您的嵌入式系统足够大,可以在其上安装编译器,那么您以前就不会工作了. (5认同)