【问题标题】:How to unit-test a bootloader on PIC18 with TCP/IP stack used?如何在使用 TCP/IP 堆栈的 PIC18 上对引导加载程序进行单元测试?
【发布时间】:2013-06-27 02:25:45
【问题描述】:

我正在使用 Microchip 的 MPLAB X 1.60 中的 XC8 C 编译器 1.12 开发引导加载程序。目标芯片是PIC18F87J60。 我的引导加载程序做了一些引导加载程序通常不会做的额外事情。它从服务器下载应用程序映像到闪存,并通过计算 MD5 哈希和来验证其完整性。此外,它必须通过特定于该项目的服务器上的身份验证测试。 为了使所有这些工作,我使用 Microchip 的 TCP/IP 堆栈 v5.42

我现在要做的是彻底测试引导加载程序,但我在选择正确的方法和工具时遇到了一些麻烦。我可以使用 Pickit 3 ICD,但不能使用任何其他专用硬件,例如逻辑分析仪等(示波器 除外)。引导加载程序被实现为分层的 FSM,它可能(或可能不会)使事情变得更加复杂。

我正在考虑至少对引导加载程序的所有不同部分进行单元测试/模块测试,并将 FSM 的所有状态视为单独的功能。互联网上有一些单元测试框架,其中一些声称可以在像我这样的嵌入式和受限环境中使用。

问题在于,大多数都是作为某种 C 库实现的,可以与程序的其余部分一起编译,但他们都希望编译器遵循一些标准。 XC8 编译器确实遵循 C90 标准,但没有完全扩展(显然是文档中的“与 ANSI C 标准的分歧”一章)。这给编译框架带来了麻烦。

我可以通过模拟所有硬件和注册访问并在我的 Windows 7 开发机器上进行测试来解决这个问题,但这将是大量工作,因为我使用引导加载程序严重依赖的 TCP/IP 库。另一个缺点是最终我想在芯片上进行测试,因为 C 代码在 PIC 芯片上的行为可能与我的 intel i7 上的行为不同。

有人对如何正确地unit-/moduletest 我的引导加载程序有任何想法吗?在这样的平台上对这样的程序进行单元测试甚至是一个好主意吗?还有其他我可能使用的测试方法吗?

要求/pre's/notes:

  • 我说的是白盒测试方法。黑盒测试目前并不痛苦。此外,从功能上讲,引导加载程序没有被编译,所有功能要求都是可衡量的。
  • 我想尽可能地自动化测试,甚至在我按下“编译”时自动触发测试。
  • 没有任何严格的性能要求,而且我有一些备用 ROM 内存,因此像放入大量探针这样的代码检测应该不是什么大问题。
  • 我远不是一个测试大师。我上面使用的任何花哨的词都来自几个小时的研究,但我没有任何实际的测试经验。

提前感谢您的任何想法和建议。

比特垃圾,

【问题讨论】:

    标签: c unit-testing embedded tcp-ip pic18


    【解决方案1】:

    我发现嵌入式系统中的单元测试非常困难。外围设备的副作用非常繁重。最难处理的是读取内存位置触发的副作用(例如读取清除标志)。您能做的最好的事情就是隔离硬件访问。即使在一个模块内限制访问也是一个好主意。单元测试是值得的,但在嵌入式空间中可以比其他测试更快地达到收益递减点。

    seatest 我很幸运。这是非常基本的;它不提供 Unity 等人提供的更高级的功能(没有自动模拟),但它是可移植的、直接的 C 语言,并支持测试所需的核心功能。

    我的第二个建议是创建一个文件,其中包含以 MCU 拥有的所有可用寄存器命名的变量。很容易从 Microchip 的链接描述文件中获取寄存器名称并将它们粘贴到 c 文件中。这使得在 PC 平台上编译所有代码变得更加容易。这可以让您更快地启动和运行,也使测试更容易。

    【讨论】:

    • 我下载并尝试了seatest。它经过一些调整后编译,但 PIC 在执行断言时由于堆栈溢出而重置。我担心任何框架,无论多小,对于我的 8 位 PIC18 来说都是大/复杂的。我将尝试使用MinUnit 构建自己的框架
    【解决方案2】:

    Microchip 的 XC8 / PIC16 有一个 Unity 的分支,不使用 setjmp/longjmp,这里:https://github.com/jwalkerbg/Unity

    使用单元测试意味着您的代码应该是可测试的。按照这个要求组织你的代码可以帮助你更好地定义每个功能的责任和前置/后置条件。

    尝试隔离不依赖于硬件状态的代码(如 md5 计算),以便您可以在您的开发环境(在您的 intel i7 中运行)上对其进行测试。这段代码的测试很容易实现自动化(您可以在构建脚本中添加测试作业,也可以在持续集成服务器中运行所有内容)。

    对于依赖于硬件状态的代码,您可以(1)模拟硬件或使用模拟器(并且仍然在您的开发或持续集成服务器环境中运行它),或者 (2) 运行将其嵌入到您的实际硬件中的测试。选项 2 可能不容易自动化。您甚至可能必须手动部署和运行每个测试。此外,获得测试结果可能并不简单,因为您的嵌入式环境中可能没有控制台或文件系统。

    【讨论】:

      猜你喜欢
      • 2013-04-03
      • 2012-01-28
      • 2014-08-21
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      相关资源
      最近更新 更多