下面提到的一些技巧可以帮助开发一种解决嵌入式系统问题的逻辑方法和分析思维。
嵌入式系统由硬件、固件和应用软件组成。有时,当报告问题时,并不清楚问题出现在系统中的什么位置。这可能是由于硬件、固件代码或应用软件。
步骤1-了解设置并正确重现问题
首先,我们需要做的是正确再现问题。有时问题是在本地看到的,工程师能够很容易地重现问题。然而,有时问题是在远程位置或客户现场发现的,工程师不得不完全依靠可用的日志来了解设置和重现问题。在第二种情况下,工程师正确理解设置非常重要,因为这将有助于成功重现问题。如果工程师未能做到这一点,那么将来该问题可能会在远程位置或客户现场再次出现。这主要是因为工程师可能没有正确理解问题,因此没有制定正确的解决方案。因此,这将导致修复问题的多次迭代。
对于我们的例子,让我们考虑一个视频显示器,其中噪声只出现在某些监视器上。因为设备安装在远程位置,所以只有视频日志可用于调试。从日志中很难找出噪音的根本原因。最初,我们尝试使用不同的剪辑,但无法在我们这边重现问题。在嵌入式开发中,我们不确定为什么问题无法重现。我们不清楚这是由于使用的视频文件还是由于设置。最后,我们通过使用与客户使用的完全相同的夹子和一台显示器重现了问题。
第2步-将问题分成更小的问题
一旦问题被正确再现,下一步就是将整个问题分解成更小的问题。这是非常重要的,可以通过理解整个数据流来完成。第一步是在应用层与固件层的接口处中断数据流,然后是固件层与硬件层的接口。这样,每一层都可以针对任何问题进行独立的审查和测试。此外,我们不需要就此止步,我们可以根据逻辑理解将整个数据流路径分解为更多的子级别。
对于我们的示例,我们将视频帧数据的整个路径从应用程序划分到硬件层。我们了解了编码视频数据如何被接收、解码以及如何被传递到固件层的整个过程。在这里,我们了解了如何为每个视频帧分配指针,以及固件如何通过硬件层发送每个帧。在硬件层,我们了解视频帧如何在物理线路上发送的协议。一旦我们理解了整个路径,我们就把它分成逻辑块。一个模块用于应用层,其中编码的视频数据被解码为原始视频并存储在视频缓冲区中。另一个模块是固件层,我们检查视频缓冲区是如何分配给硬件的。最后一个模块用于硬件,我们检查视频数据是如何在实际物理线路上给出的。
步骤3–解决每个较小的问题
一旦我们将整个数据路径分成每一层的逻辑块,我们需要单独测试每个块,并以各自的方式进行验证。在嵌入式开发中,这将有助于找到问题的根源所在。有时一个系统问题可以通过只改变一层来解决,而有时需要改变不止一层。通过在逻辑上断开整个路径,我们可以正确地找到所有需要更改的地方,然后相应地修复它们。
对于我们的示例,在应用层,我们使用读写文件来验证数据路径流。将解码后生成的视频数据缓冲区与预期值进行比较。在固件级,固定模式被用作数据输入,而不是来自应用层的数据。这里,我们观察到视频数据是按照场而不是帧提供给固件层的,但是场信息(顶部或底部)没有从应用层正确地提供给固件层。因此,我们必须相应地修改代码,使缓冲区包含正确的字段信息。
在硬件层面,使用逻辑分析仪按照规范验证这些固定模式和接口的相应控制信号。在我们的例子中,我们使用的协议是BT.1120,我们发现协议计时不符合规范。所以我们意识到这就是为什么有些显示器工作正常而有些不正常的原因。一旦我们按照规范制定了协议,我们看到所有的监视器都工作正常。我们还意识到,噪声的整个问题实际上是错误的字段信息和错误的协议计时的组合。这就是为什么一些显示器能够工作而另一些不能工作的原因。
第4步-消极测试
测试当然是解决问题的一个非常重要的方面,重要的是测试问题是否得到了正确的解决并且不会再出现。因此,在修复问题后,我们在进行常规测试的同时进行负面测试是非常重要的。消极测试基本上意味着确保问题被强加到系统中,然后按照设计的解决方案验证系统的响应。在嵌入式开发中,这基本上意味着,如果我们通过给出正确的输入从系统得到错误的输出,并且我们想出了一个解决方案,那么我们应该能够产生一个错误的输入并馈送给系统,以便它将产生正确的输出。如果发生这种情况,这意味着根本原因已被正确识别,修复已得到验证。
对于我们的例子,我们用下面的方式测试。对于协议计时,我们看到在按照规范进行计时之后,所有的监视器都出现了噪声问题。即使是对规范的一个微小修改也会导致监视器行为的改变。这证实了硬件层错误的协议时序是监视器不同行为的根本原因。接下来,对于我们发现问题的显示器,我们故意在应用层交换了顶部和底部字段。然后我们看到问题没有发生。这证实了不正确的顶部和底部字段指针是噪音问题的根本原因。通过这种方式,我们测试了该解决方案实际上解决了根本原因,并且在应用程序和硬件层都进行了修复。
通过使用上述步骤,在嵌入式开发中,任何问题都可以以更好的方式解决。