嵌入式硬件测试自动化

有没有人成功地直接在嵌入式硬件上进行测试?

具体来说,我正在考虑为硬件层模块自动化一系列unit testing。 我们需要对硬件层代码更有信心。 我们的很多项目都使用中断驱动的定时器,ADC,串行io,串行SPI器件(闪存)等。

这甚至值得努力吗?

我们通常针对:

处理器:8位或16位微控制器(某些DSP产品)
语言:C(有时是c ++)。

当然。 在汽车行业,我们为每种新产品使用100,000美元的定制测试仪,以validation硬件和软件是否正常运行。

然而,开发人员还构建了一个更便宜(低于1,000美元)的测试仪,其中包括一堆USB I / O,A / D,PWM输入/输出等,并使用工作站上的脚本或专用的HIL / SIL测试软件比如MxVDev。

硬件在环(HIL)测试可能就是你的意思,它只是涉及一些USB硬件I / O连接到你的设备的I / O,计算机上的软件运行测试。

是否值得它取决于。

在高可靠性行业(飞机,汽车等)中,客户指定了非常广泛的硬件测试,因此您必须获得它才能获得出价。

在消费行业,对于非复杂的项目,通常不值得。

但是,对于涉及多个程序员的任何项目,在硬件上运行夜间回归测试真的很不错 – 很难正确地模拟硬件,以达到满足自己软件测试就足够的程度。

然后,测试会在问题进入构建时立即显示。

通常,您执行黑盒和白盒测试 – 您在设备上运行诊断代码,允许您监视硬件中的信号和内存(可能只是一个调试器,或者可能是您编写的对消息作出反应的代码)例如,一辆公共汽车)。 这将是白盒测试,您可以在其中查看内部发生的情况(甚至导致某些事情发生,例如关键内存错误,如果不自行引入错误则无法测试)。

我们还运行了一系列“黑盒子”测试,其中忽略了诊断路径,只激励/读取了I / O.

对于更便宜的设置,您可以获得100美元的带有USB和/或以太网的微控制器板(例如Atmel UC3系列),您可以将其连接到您的设备并运行基本测试。

它对于产品维护特别有用 – 项目完成后,将一些工作板,测试仪和一整套软件存储在CD上。 当您需要进行修改或调试问题时,可以很容易地将其全部备份并使用一些知识(经过测试后)确定主要function不受您的更改影响。

-亚当

是。 我已经取得了成功,但这不是一个难以解决的问题。 简而言之,这是我的团队所做的:

  1. 使用自制的Cunit testing框架定义了各种unit testing。 基本上,只有很多宏,其中大部分都被命名为TEST_EQUALTEST_BITSETTEST_BITVLR等。

  2. 编写了一个启动代码生成器,它使用这些编译的测试并将它们编排到执行环境中。 它只是一个执行我们正常启动例程的小驱动程序 – 但它不是进入控制循环,而是执行测试套件。 完成后,它将最后一个套件存储在闪存中运行,然后重置CPU。 然后它将运行下一个套件。 这是为了在套件死亡时提供隔离。 (但是,您可能希望禁用它以确保模块配合。但这是集成测试,而不是unit testing。)

  3. 单个测试将使用串行端口记录其输出。 这对我们的设计来说没问题,因为串口是免费的。 如果消耗了所有IO,则必须找到存储结果的方法。

有效! 这很棒。 使用我们的自定义数据记录器,您可以点击“测试”按钮,几分钟后,您将获得所有结果。 我强烈推荐它。

更新以阐明测试驱动程序的工作原理。

是。

困难取决于您尝试测试的硬件类型。 正如其他人之前所说,问题将是您需要应用的外部刺激的复杂性。 外部刺激可能最好通过一些外部测试装备实现(如Adam Davis所述)。

但是,要考虑的一件事就是你要validation的确切内容。

很容易假设要validation硬件和固件的相互作用,那么你真的别无选择,只能直接应用外部激励(即将DAC应用于所有ADC输入等)。 但是,在这些情况下,您真正​​想要测试的极端情况通常会受到时序问题的影响(例如,当您执行函数foo()时到达的中断)将会非常难以测试一种有意义的方式 – 甚至更难从中获得有意义的结果。 (即。我们运行此测试的前100K次很好。上次我们运行它失败了。为什么?!?)

但是硬件的validation应该单独进行。 一旦完成,除非它定期更改(通过可下载的fpga图像等),否则您应该能够假设硬件正常工作并纯粹测试您的固件。

因此,在这种情况下,您可以专注于validation用于处理外部刺激的算法。 例如,使用固定值调用ADC转换例程,就好像它们直接来自ADC一样。 这些测试是可重复的,因此是有益的。 他们需要特殊的测试版本。

测试设备的通信路径将相对简单,不需要特殊的代码构建。

我们在嵌入式系统上进行自动化测试,取得了良好的效果。 我们使用在专用测试机器上运行的高级(易于编程和调试)语言编写测试。 这些测试通常会进行健全性检查或生成随机输入到设备中,然后检查是否有正确的行为。 生成和维护这些测试有很多工作要做。 我们设计了一个框架,然后让实习生自己处理测试。

这不是一个完美的解决方案,测试肯定容易出错,但最重要的部分是改善现有的覆盖漏洞。 找到最大的洞并设计一些以自动方式覆盖它的东西,即使它不完美或不能覆盖整个function。 稍后当你所有的东西都被覆盖时,你可以回来解决最差的覆盖范围或最关键的function。

有些事情需要考虑:

  • 固件错误的代价是什么? 在现场更新固件有多容易。
  • 我的测试提供什么样的保险? 这是一个简单的健全检查吗? 它是否足够可配置,可以测试许多不同的场景?
  • 一旦测试失败,您将如何重现该值以进行调试? 您是否记录了所有设备和测试设置,以便尽可能多地消除变量? 设备配置,固件版本,测试软件版本,所有外部输入,所有观察到的行为?
  • 你在测试什么? 规范是否足够清楚您正在测试的设备的预期行为,或者您是否根据您认为代码应该执行的操作进行validation?

如果您的目标是测试低级驱动程序代码,则可能需要创建某种测试夹具,使用环回电缆或多个互连单元来运行每个驱动程序。 将具有已知良好软件的电路板与运行开发构建的电路板配对将允许您测试通信协议中的回归等。

具体的测试策略取决于您要测试的硬件。 例如,可以通过呈现已知波形并转换一系列样本,然后检查适当的范围,频率,平均值等来测试ADC。

我发现这种类型的测试在过去非常有价值,使我能够自信地修改和改进驱动程序代码,而不必担心破坏现有的应用程序。

是的,我这样做,虽然我总是有一个可用于测试I / O的串口。

通常很难使装置完全未经修改。 某些测试需要注释掉一行或添加一个调用,例如处理看门狗。

恕我直言,这比没有unit testing更好。 当然,您也需要进行完整的集成/系统测试。

unit testing嵌入式项目非常困难,因为它通常需要外部刺激和外部测量。

我们已成功开发了一个外部串行协议(rs232或udp或tcpip消息),其中包含基本命令,用于在低级别驱动程序中查找调试日志,以查找错误条件或甚至是轻微exception情况(特别是限制检查)

但是一旦开发出来,我们就可以在每次构建后运行测试。 它绝对会让您提供更优质的产品。

我知道现在已经老了,但也许会有所帮助。 是的,您可以这样做,但这取决于您希望在您想要的解决方案上投入多少资金。 两年多来,我一直在为AUTOSAR的MCAL层进行测试和validation。 这是软件测试中最低的一种。 这是一种组件级别的测试。 有些人可能将其称为单位级别,但略高于此级别,因为我们正在测试MCAL组件的API。 例如:ADC,SPI,ICU,DIO等。

使用的解决方案包括: – 在目标微型计算机上运行的测试框架 – 在需要时提供和读取目标信号的dSPACE框 – 通过Vector CANape访问XCP以触发测试执行和结果收集 – 一个python框架执行测试控制和结果validation

测试用例用C语言编写,并将它们与被测软件一起闪存在目标上。 这是一个黑盒子测试,因为我们没有以任何方式改变MCAL的实施。 而且我认为甚至没有触及启动序列。 空闲任务用于持续检查作为开始执行测试的信号的标志的状态。 使用10毫秒的任务来实际运行测试。 测试用例实际上是一个切换案例。 此开关中的每个案例都是一个测试步骤。 Python在测试步骤级别触发测试执行。 这种方法的一个好处是重用不同参数的步骤。 这个测试控件,执行的内容以及如何通过测试控制数据结构在测试实现和测试触发和评估机制之间充当API来完成。 这就是CANape的用途。 设置要执行的测试并读取测试结果。 通过测试步骤获得的每个值都存储在数据结构的数组部分中。 测试步骤本身不参与任何validation,因为目标被认为是测试环境中不可信任的组件。 validation是由Python根据测试规范完成的。 Python正在解析这些规范,并能够自动创建测试触发脚本,包括每个测试步骤的validation标准。 每个测试用例的规范是一系列测试步骤描述及其validation标准。 其中一些步骤是与dSPACE相关的步骤。 例如,一步是初始化某些东西,并且要求在已配置的通道上捕获一些边缘,下一步是通过命令dSPACE设备在该通道上应用信号。

更便宜的解决方案是使用内部板而不是dSPACE设备。 在某种程度上,甚至可以使用可编程信号发生器,但如果您需要validation目标输出的信号,这将无济于事。

如果你的目标是制造测试(确保模块正确组装,没有无意的短路/打开/等),你应该首先关注测试电缆和连接器,然后是sockets和焊接连接,然后是PCB本身。 这些项目都可以通过查找访问模式进行短路和打开测试,这些访问模式可以驱动每个单独的行,而其邻居较低,反之亦然,然后读取行的值。

在不了解硬件的更多细节的情况下,很难更具体,但大多数嵌入式处理器可以将I / O引脚设置为GPIO模式,从而简化了这种测试。

如果您没有在PCA上进行钉床测试,则应将此测试视为新制造的电路板的必要的第一步。