硬件调试故事:从 printf 到 Flash监视及其他方案
扫描二维码
随时随地手机看文章
在 20 世纪 90 年代,在实际硬件上调试嵌入式软件主要有两种基于工具的解决方案:一种是监控调试器,它是在嵌入式系统内存中编程的软件,可响应来自外部的调试器软件的请求。另一种是在线仿真器,它是一块(大型)硬件,可通过适配替换和仿真位于目标硬件中的微控制器/处理器。
监控调试器解决方案价格低廉,可实现基本调试功能;在线仿真器解决方案价格昂贵,使用复杂,而且适配通常不稳定且容易出错。作为回报,开发人员获得了完全透明度并可以访问微控制器/处理器的所有总线。当时已经可以进行时序测量和代码覆盖率分析。然而,半导体制造商必须为此开发一种特殊的、带有额外引脚的所谓仿真芯片。对于所有参与者来说,这都是一个关键的成本因素。
半导体的不断小型化和片上调试接口的引入对调试器作为开发工具本身的架构产生了巨大影响。以前在硬件中实现的功能越来越多地在软件中实现。开发环境和调试器软件变得更加强大,硬件变得更小,带宽和速度方面的性能不断提高。然而,调试的基本用例今天仍然相同。
硬件调试的演进,以及对调试“圣杯”的追求
从 printf 到“仅仅”闪现到断点、实时监视和步进,这就是您可以简要描述调试的方式。原则上,调试用于驱动程序开发、电路板/硬件启动、启动过程等的开发和故障排除,是“低级”硬件相关开发的标准方法。可以快速将调试器放在桌面上,将软件闪现到目标硬件上,通过断点开始执行或在代码中的某个点停止执行,检查内存区域和寄存器或操纵它们进行测试,读出调用堆栈等。
在应用方面,它简单易懂,原则上是大多数开发人员通过调试理解的。大多数时候,人们没有时间深入研究调试器本身,以发现“调试的圣杯”,这些附加功能最终可以节省大量调试和测试时间。例如,在这种情况下,跟踪是一种被低估的技术。它可以洞察软件的执行情况,而不会影响运行时行为。因此,开发人员可以获得软件在硬件上执行的真实图像。可以发现软件中偶尔发生的错误和瓶颈。这只是调试器众多替代用例中的一个例子。
微控制器、处理器和 SoC 带来了新的挑战
调试的发展伴随着半导体的小型化、复杂性和速度的提高。在过去的 15 年里,嵌入式行业,尤其是汽车行业,在其产品中引入了许多附加功能,以满足当前和未来的环境法规,减少总体车祸数量,通过将功能分布在多个电子控制单元 (ECU) 上而不是按功能开发专用 ECU 来更有效地开发和生产车辆,并使自己在竞争中脱颖而出。
为了实现所有这些,汽车行业需要半导体制造商通过开发和生产更紧凑、更快的微控制器来满足其要求。
这就是嵌入式多核微控制器(具有两个或更多个内核的控制器)的诞生。ECU 从单核架构向多核架构的转变给每个人都带来了新的挑战。嵌入式软件工具供应商面临着新的问题,从如何轻松访问多核 ECU 的所有内核到如何将嵌入式和旧版软件分布在不同内核上,以最高效的方式运行,同时保持高性能。此时,开发嵌入式软件的传统方式已经受到质疑。
随着高性能/计算平台和多核系统的推出,现在更复杂的处理器架构被用于开发高度复杂的应用程序。调试在这里仍然发挥什么作用?
原则上,它仍然基于基础知识。除了微控制器的内部闪存组件外,还必须操作 SoC 外部闪存组件。调试器首先帮助控制启动过程,然后在下一步中仔细检查这些处理器的各个部分和核心以及在这些设备上运行的软件。除了标准调试功能外,由于这些软件系统的复杂性不断增加,诸如时序分析、功能分析或 CPU 负载测量等分析选项的使用也越来越多。前提条件是所使用的半导体上有跟踪接口,并且相应的调试器(其软件可实现此类功能)可用。
半导体行业的技术发展正在改变软件开发流程,进而改变调试器作为流程工具的基础工具。
软件开发流程和标准
分布式开发团队、日益复杂的代码库、不断增长的功能需求、标准化和时间压力:即使在嵌入式软件开发中,也只有通过更高程度的抽象和自动化才能应对在最短时间内将可靠、安全的产品推向市场的挑战。
因此,传统意义上的开发工具必须比以往更加通用。调试器以前仅由微控制器专家用作与硬件相关的开发工具,现在越来越多地出现在各种软件开发环境中。调试器仍然是通过标准调试接口与实际目标硬件的连接,目的是尽可能接近实际硬件开发和测试嵌入式软件。
除了简单地与目标硬件接口之外,调试器还提供更高级的调试功能,包括测试功能。在这里,开发人员可以跟踪正在运行的软件的执行情况。为此,可以检查程序状态,并在某些条件下停止程序的执行。这样做对被测试的软件的影响很小甚至没有影响。专业的调试解决方案还可以实时记录软件中的进程(跟踪)、记录时钟周期范围内的执行时间以及评估与测试相关的软件处理部分(代码覆盖率)。
为了让客户能够灵活地使用所有这些功能,调试器制造商提供了通用接口(API),使这些工具能够集成到客户的开发和测试过程中。这些接口必须适合解决各种各样的任务(开发、测试、验证和确认软件和硬件)。这里的标准是支持编程(C、C++、C#、Java 等)和脚本语言(Python 等),以便从另一个(也是客户特定的)应用程序“远程控制”开发工具。基本上,部分流程可以在开发和测试期间实现自动化。
此外,当今的调试器提供所谓的“迷你 HIL”功能(用于测试的硬件在环、测量和刺激模块),用于生成或测量数字和模拟信号,同时记录和关联程序执行。这使得在软件开发过程中尽早进行非常接近现实的测试成为可能。所有这些都是在已知环境中实现的,几乎是即时的,无需学习新方法。
这些灵活的测试自动化接口的一个典型用例是持续集成 (CI)。CI 通过将开发人员的更改或新创建的代码集成到与团队共享的存储库中,以短间隔支持敏捷/分布式软件开发和测试。有几种适合此目的的持续集成服务器,例如 Jenkins、GitLab、TeamCity、CircleCI 或 GitHub Actions。通过集成,可以通过内部或云端托管的 CI 软件触发一系列快速且高度自动化的步骤(称为“管道”)。管道通常包括并结合构建、静态分析、单元和系统测试。
因此,经典的调试器就成为了在真实硬件上进行测试的测试工具。
通常,软件也可以在 PC 平台上进行大量测试,与目标硬件无关。然而,并非所有潜在错误都能在模拟环境中检测到:例如,所需的硬件外围设备通常不可用,或者应用程序的行为与真实硬件不同,时序行为不同,或者交叉编译器生成特定于目标的目标代码,因此与用于测试环境的编译器的代码不同。
因此,在早期阶段尽可能接近真实硬件进行测试是有意义的,以确保最终产品的正确功能以及应用程序的准确时序行为。
ISO26262 和 DO-178C 等安全标准对工具的功能范围以及向客户提供这些功能正确性的证明有影响。特别是在航空业,工具制造商长期以来一直需要在工具认证方面进行合作 - 但最近在汽车行业也开始采用 ISO26262。
为此,工具制造商必须针对特定用例创建用于验证所用工具功能正确性的验证选项。这些可以是组织措施,例如对开发过程进行外部审计或由独立第三方对工具进行认证,或支持客户进行正确性验证的参考工具套件。上述使用调试器自动化测试过程的方法非常适合实施此类工具鉴定过程。
结论:调试器更加复杂,新的商业模式正在不断发展
调试器正越来越多地成为一种流程工具。调试器的基本功能已得到普遍应用,并辅以强大的分析功能。软件的复杂性不断增加,软件开发本身所使用的软件和硬件工具数量庞大,以及它们的相互依赖性推动了工具制造商、芯片供应商和客户之间对知识转移和咨询服务的需求。
参与这些开发的各方之间持续而开放的沟通是成功的关键。如今,客户不再想购买工具,他们希望随时随地使用它们。嵌入式软件开发和软件测试的新商业模式将发挥作用,其中工具、知识转移和咨询是一种常见的产品,最终是一种服务。正如软件行业所发生的那样,订阅业务模式也适用于全球嵌入式软件开发和测试。