嵌入式软件调试与验证1概述

发布时间 2023-09-23 20:22:51作者: 磁石空杯

1 嵌入式软件调试与验证技术概述

1.1 调试和验证过程的重要性

近年来,嵌入式系统(ES Embedded systems)因其灵活的操作和可能性而被广泛应用于电子系统行业。嵌入式系统由硬件、软件和其他模块(如机械)组成,旨在作为更大系统的一部分执行特定任务。网络物理系统(CPS Cyber-Physical System)和物联网(IoT Internet of Things)等重要的新概念也考虑到了嵌入式系统的不同方面。在CPS中,考虑到时间、能量和大小等物理量,计算和物理过程被整合在一起。在物联网中,物理对象被无缝集成到信息网络中。综上所述,车辆内部控制、自动驾驶仪、电信产品、电器、移动设备、机器人控制和医疗设备都是嵌入式系统的一些实际例子。

在过去几年中,嵌入式电子产品中使用的软件数量不断增加,而且这种趋势在未来仍将继续。全球已开发的微处理器中几乎有90%都已应用于嵌入式系统产品,因为嵌入式软件(ESW)是功能创新的主要推动力,例如,在汽车领域,它可以减少气体排放或提高安全性和舒适性。

嵌入式软件还经常用于安全关键型应用(如汽车),在这些应用中,故障是不可接受的,这一点从因软件错误而导致的灾难和不便清单中可见一斑。验证和调试过程的主要挑战是如何处理系统的复杂性。

嵌入式软件在现代SoC中以不同的视角进行应用,从分布在多个处理器内核中的应用软件(如应用程序、中间件、操作系统、驱动程序、固件),到依赖于硬件的软件(即裸机),最后涵盖通信软件栈。

电子系统级(ESL)设计和验证通常是自下而上和自上而下方法的结合。它通过硬件和软件的并行设计,利用硬件和软件的协同作用来实现系统级目标。因此,软件开发需要与 SoC 设计、集成和验证提前开始(并行)。在硅前阶段,是清除系统环境中关键错误的时候。在这一阶段,SW越来越多地成为一个需要解决的问题,因为如果错误过于严重,它可能会阻碍制造。生产完成后,可继续在芯片上开发SW,并进行硅后验证。

软件开发、调试和验证过程导致SoC项目成本高达整个开发成本的80%。设计复杂度越来越高,因此产生了设计生产力差距和验证差距。目前,技术能力每36个月翻一番。在过去几年中,通过在硅片中填充多核和内存组件,并在软件中提供额外功能,硬件设计生产率得到了提高。随着嵌入式软件数量的增加,可以注意到软件差距的存在,目前的主要挑战是如何将数百万门的软件线与数百万门的软件线相匹配。目前,软件部分每10个月翻一番,而依赖硬件的软件的生产率每5年才翻一番。随着设计复杂度的增加,对系统寿命和上市时间的要求也在不断缩短。如果能最大限度地减少验证和调试时间,开发周期就能缩短。如果由于设计错误而需要重新设计设备和/或增加新的项目开发周期,产品的最终成本可能会增加数十万美元。此外,人们还普遍认为,在设备投放市场之前,必须纠正功能错误。硬件和软件知识产权 (IP) 模块的供应公司就是对正确性要求很高的企业,因为他们需要确保自己的IP核在插入目标项目时能正确工作。

本章介绍调试/验证平台和方法,并概述本书的范围和组织结构。

1.2 调试和验证平台

调试和验证平台可以定义为计算机系统硬件的标准,决定了可以执行哪些类型的调试和验证过程。基本上,我们可以将平台分为两类: 硅前平台和硅后平台。在硅前平台中,设计调试和验证是通过虚拟环境和复杂的仿真与形式验证工具进行的。与之不同的是,在硅后平台中,使用逻辑分析仪和基于断言的工具在目标板上运行真实器件。

1.2.1 操作系统仿真

智能设备(如智能手机)的操作系统允许开发人员创建数以千计的附加程序,这些程序具有多种实用功能,如存储用户的个人数据。为了开发这些应用程序(即应用程序),每个平台都有其优势、劣势和挑战。
Gronli等人从软件架构、应用程序开发、平台能力和限制以及开发人员支持等几个不同方面对主要的移动操作系统平台进行了比较。比较的操作系统平台包括:(1) 谷歌基于Linux的操作系统 Android;(2)微软的 Windows Phone操作系统;(3) 苹果的iOS平台:(4) Mozilla新推出的基于网络的火狐操作系统。所有被评估的平台都提供了从良好到卓越的交互式调试选项。

1.2.2 虚拟平台

虚拟原型(VP Virtual prototyping)(又称虚拟平台)是一个系统的软件模型,可用于早期软件开发和 SoC/系统架构分析。虚拟原型包括处理器和外设模型,可以以实时或接近实时的速度运行,可能支持整个软件堆栈直至应用级的硅前开发。虚拟原型验证解决方案可能附带帮助开发模型的工具,通常还提供仿真和调试环境。早期的虚拟原型验证解决方案需要专有模型,而现在许多解决方案都使用基于开放系统级建模(OSCI)、事务级建模(TLM transaction-level modeling)标准和 IEEE-1666 SystemC 标准的 SystemC 模型。

除早期软件开发外,虚拟原型还可用于软件分发、系统开发套件和客户演示。例如,在后RTL软件开发中,虚拟原型可用作半导体公司向系统公司软件开发人员分发的硅参考板的低成本替代品。与参考板相比,虚拟原型可提供更好的调试能力和迭代时间,因此可加快硅后系统集成过程。

1.2.3 RTL 仿真

依赖于硬件的软件需要模拟器或目标平台进行测试。寄存器传输级(RTL Register Transfer Level)仿真是验证数字集成电路设计正确性最广泛使用的方法。它们更适合测试具有硬件依赖性的软件(如汇编代码)和需要时序精度的软件。然而,当模拟具有复杂内部行为的大型集成电路设计(如运行嵌入式软件的 CPU 内核)时RTL模拟可能会非常耗时。由于RTL到布局仍是最普遍的集成电路设计方法,因此必须加快RTL仿真过程。最近,图形处理单元上的通用计算(GPGPU)正在成为加速计算密集型工作负载的一种有前途的模式。

1.2.4 加速/仿真

传统调试工具跟不上系统级芯片 (SoC) /ASIC 设计规模和复杂性的快速增长。随着RTL/栅极设计规模的增大,传统仿真器的运行速度明显减慢,从而延误了硬件/软件(系统)集成,延长了整个验证周期。
当过长的仿真时间成为动态验证的瓶颈时,通常会使用硬件仿真和仿真加速。硬件仿真器提供的调试环境具有逻辑仿真器的许多功能,在某些情况下甚至超过了逻辑仿真器的调试功能,如设置断点和内存设计内容或符号的可见性。要在硬件仿真中使用基于断言的验证(ABV Assertion-based Verification)方法,必须在硬件中支持断言。传统的仿真器基于可重构逻辑和FPGA。为了提高灵活性并简化调试过程(调试过程需要断言处理能力),目前新一代的仿真器和仿真加速器通常基于处理元件阵列,如 Cadence Palladium 。另一种方法是在芯片内部集成调试和通信模块,如用于调试的片上在线仿真(ICE in-circuit emulation)架构。然而,由于仿真器成本高昂,对许多开发人员来说都是昂贵的。

1.2.5 FPGA 原型开发

近年来,现成的商用 FPGA(COTS Commercial-Off-The-Shelf)可提供处理能力,满足仪器分辨率和测量速度不断提高的要求,而且功耗低。此外,部分动态重新配置允许在运行过程中改变或调整有效载荷处理。
FPGA技术通常用于新数字设计的原型,然后再进入制造阶段。虽然这些物理原型的运行速度比逻辑仿真器快很多个数量级,但其根本局限在于调试时缺乏片上可见性。有公司在原型中安装了基于跟踪缓冲器的仪器,允许设计人员在实时运行期间捕获预定的信号数据窗口,进行离线分析。然而,设计人员无需在每次修改窗口时重新编译整个电路,而是建议仅使用备用 FPGA路由多路复用器构建一个覆盖网络,将所有电路信号连接到跟踪仪器。因此,在调试过程中,设计人员只需重新配置该网络,而无需寻找新的布局布线方案。

1.2.6 原型开发板

传统上,硅片后调试通常既痛苦又缓慢。硅片的可观测性有限,而且成本高昂。仿真和仿真速度慢,而且很难解决边角情况、并发和周期依赖行为。在仿真中,希望受限随机发生器能命中导致故障场景(触发错误)的输入组合。此外,当复杂的硅后错误浮出水面时,上市时间也是一个主要问题,而找到问题的根本原因并加以修复需要时间。

硅后自省技术已成为解决日益严重的正确性、可靠性和良品率问题的有力工具。以前使用硅后自省技术的工作包括在线错误检测、多处理器高速缓存一致性验证和在线缺陷检测。访问控制扩展(ACE Access-Control Extensions)可以访问和控制微处理器的内部状态。利用ACE技术,特殊固件可在执行过程中定期探测微处理器,以定位运行时故障,修复设计错误。

1.2.7 为软件开发和调试选择合适的平台

正如前文所述,没有 "放之四海而皆准 "的方法。每个平台都有其优势和劣势。

1.3 调试方法

调试可能是嵌入式系统开发人员最耗时的工作。对有效调试工具和基础设施的任何投资都会加速产品的发布。基本上,调试过程可以以交互式或后处理的形式进行。

表 1.1 软件包类别与调试方法和平台的关系

表 1.2 嵌入式软件调试

1.3.1 交互式调试

克服可观察性问题的一种常用调试方法是交互式(或运行/停止)技术。这种技术的优势在于,我们可以检查SoC的全部状态,而不会受到器件引脚速度的限制。此外,它只需要在SoC中增加少量调试逻辑。交互式调试的主要缺点是该技术具有侵入性,因为在观察其状态之前必须停止SoC。

最原始的调试方式是在标准输出上打印信息(如 C 语言的 printf)和使用调试应用程序(如gdb)。如果在硬件引擎上测试嵌入式软件,则应使用JTAG 2接口获取调试信息。工业调试解决方案包括Synopsys System-Level Catalyst, 侧重于虚拟平台和FPGA原型调试;SVEN和OMAR侧重于软件和硬件技术,增加了硅和软件调试设施。

1.3.2 后处理调试

后处理调试以批处理模式运行仿真,将数据记录到波形数据库,然后在仿真完成后分析结果。当DUT由基于类的验证环境(如开放验证方法(OVM Open Verification Methodology)或通用验证方法(UVM Universal Verification Methodology))驱动时,后一种使用模式会给后处理结果带来挑战。

Incisive Debug Analyzer(IDA提供了交互式调试流程的功能以及在后处理模式下调试的优势,允许所有调试数据文件运行一次仿真。

参考资料

1.4 验证方法

1.4.1 验证规划

验证规划是一种定义如何测量变量、场景和功能的方法。此外,它还记录了如何衡量验证结果,例如仿真覆盖率、定向测试和形式分析。它还提供了一个框架,用于达成共识和定义设计的验证闭合。验证规划工具的一个例子是 Enterprise Planner,它可以创建、编辑和维护验证计划,既可以从头开始,也可以通过链接和跟踪功能规范来实现。

1.4.2 验证环境开发

动态验证需要在验证过程中执行嵌入式系统。它主要侧重于测试、共同验证和基于断言的验证。另一方面,静态验证在不执行嵌入式系统的情况下对其进行验证。静态验证的重点是静态分析和模型检查方法。定理证明要求用户熟练迭代,主要与其他静态验证方法结合使用。最后,混合方法侧重于静态方法和动态-静态方法的结合。

1.4.2.1 动态验证

动态验证侧重于测试、共同验证和基于断言的验证方法。独立于硬件的软件的动态验证可直接在主机上测试。而依赖硬件的软件则需要模拟器或目标平台。如果嵌入式软件要求高性能(如操作系统启动、视频处理应用),则可使用硬件引擎(如在线仿真器、仿真加速器或快速原型)来提高性能。动态验证的主要优势在于整个系统都可用于验证,以便更深入地测试系统状态空间。

  • 测试

测试是一种经验性方法,旨在执行软件设计,以识别任何设计错误。如果嵌入式软件不能正常工作,则应进行修改以使其正常工作。脚本语言用于编写不同的测试场景(例如,具有不同参数值或不同函数调用序列的函数)。

  • 指标驱动的硬件/软件协同验证

度量驱动验证是指使用验证计划和覆盖率度量来组织和管理验证项目,并优化日常活动,以实现验证闭合。设计测试平台的目的是将输入驱动到硬件/软件模块,并监控设计的内部状态(白盒验证)或输出结果(黑盒验证)。执行回归套件会产生一个失败运行列表,这些失败运行通常代表系统中有待解决的错误,而覆盖率则提供了验证完成度的衡量标准。错误会被反复修复,但度量驱动验证的独特过程是使用覆盖率图表和覆盖率漏洞分析来帮助完成验证。通过分析覆盖漏洞,可以深入了解尚未生成的系统场景,使验证团队能够对验证环境进行调整,以实现更多的功能覆盖。

例如,覆盖率驱动验证已成功应用于硬件领域的e语言。最近,它又通过 Incisive Software extensions (ISX) 扩展到了嵌入式软件领域。

  • 基于断言的验证

基于断言的验证方法以时间属性捕捉设计的预期行为,并在系统仿真过程中监控这些属性。在对系统需求进行规范后,非正式的规范被转化为捕捉设计意图的时态属性。这种需求的形式化已经提高了对新系统的理解。这种方法已成功应用于较低层次的硬件设计,特别是寄存器传输层(RTL),它需要时钟机制作为时序参考和布尔层信号。因此,将这种硬件验证技术直接应用于嵌入式软件并不合适,因为嵌入式软件没有时序参考,而且包含更复杂的结构(如整数、指针等)。因此,为了将基于断言的方法应用于嵌入式软件,需要使用新的机制。

1.4.2.2 静态验证

静态验证在不执行程序的情况下进行分析。分析在源代码或目标代码上进行。嵌入式软件的静态验证主要侧重于抽象静态分析、模型检查和定理证明。

静态分析已广泛应用于编译器设计的优化(例如指针分析)。 在软件验证中,静态分析已用于突出显示可能的编码错误(例如linting工具)或正式静态分析,以验证不变属性,例如除零、数组边界和类型转换。这种方法还用于分析最坏情况执行时间 (WCET worst case execution time) 和堆栈/堆内存消耗。

形式静态分析基于抽象解释理论,它近似于程序执行的语义。这种近似是通过抽象函数(例如数值抽象或形状分析)来实现的,抽象函数负责将实际值映射到抽象值。 该模型过度近似系统的行为,使其易于分析。 另一方面,它是不完整的,并非原始系统的所有真实属性都对抽象模型有效。 然而,如果该属性在抽象解释中有效,则该属性在原始系统中也有效。

  • 模型检查

模型检查 (MC) 验证设计模型是否满足给定的规范。 模型检查有两种主要范例:显式状态模型检查和符号模型检查。
显式状态模型检查使用显式表示(例如哈希表)来存储由状态转换函数给出的探索状态。 另一方面,符号模型检查以紧凑的形式象征性地存储探索的状态。 尽管显式模型检查已用于软件验证(例如,SPIN模型检查器),但与符号模型检查器相比,它具有内存限制。 符号模型检查基于二元决策图(BDD)或布尔可满足性(SAT)[31],并且已应用于形式验证过程中。 然而,每种方法都有其自身的优点和缺点。

形式化验证可以处理中等规模的软件系统,其中可供探索的状态空间较小。 对于较大的软件设计,使用模型检查的形式验证通常会遇到状态空间爆炸问题。 因此,应用抽象技术来减轻后端模型检查器的负担。

常用的软件模型检验方法有:

  • 将C程序转换为模型并将其输入模型检查器。

这种方法通过使用合适的抽象将程序的语义建模为有限状态系统。 这些抽象模型使用基于BDD和基于SAT的模型检查器进行验证。

  • 边界模型检查(BMC)

这种方法解除了嵌入式软件中的循环,并将所得子句公式应用于基于 SAT 的模型检查器。

当前模型检查方法的主要弱点仍然是合适的抽象模型的建模和大型工业嵌入式软件的状态空间爆炸。

  • 定理证明

定理证明是一种演绎验证方法,它使用一组公理和一组推理规则来证明针对属性的设计。 在过去的几年里,自动定理证明器(ATP)领域的研究一直是嵌入式软件验证的一个重要课题[27]。 然而,独立的定理证明技术仍然需要熟练的人类指导才能构建证明。

1.4.2.3 混合验证

验证技术的组合是一种有趣的方法,以克服上述孤立的动态和静态验证方法的缺点。
用于嵌入式软件验证的主要混合验证方法侧重于模型检查和定理证明的结合,例如可满足性模理论(SMT)和谓词抽象方法。
SMT结合了以经典一阶逻辑表达的理论(例如线性不等式理论、数组理论、列表结构理论、位向量理论),以确定公式是否可满足。 公式中的谓词符号可能有附加的解释,这些解释根据它们所属的理论进行分类。 从这个意义上说,SMT的优点是问题不必转换为布尔级别(如SAT求解),并且可以在字级别上处理。 例如,基于SMT的BMC已用于多线程软件的验证,通过从 SMT 求解器生成的不满足性证明中抽象出状态变量和交错的数量来减少状态空间。

使用定理证明器或SAT求解器进行谓词抽象的模型检查是基于"抽象-检查-提炼"范式来检查软件的。它根据谓词构建抽象模型,然后检查安全属性。如果检查失败,它就会完善模型并重复整个过程。
动态验证和静态验证的结合已在硬件验证领域进行了探索。基本上,仿真用于达到"有趣"(也称为灯塔或临界)状态。从这些状态出发,模型检查器可以在一定数量的时间步长内对局部状态空间进行穷举验证。这种方法可用于硬件商业验证工具,如。此外在硬件串行协议的验证中,仿真和形式验证的结合也被用于查找错误,而孤立的技术(即仅仿真或仅形式验证)无法发现这些错误。

控制嵌入式软件复杂性的一种方法是将形式化方法与仿真方法相结合。这种方法结合了深入系统和详尽覆盖嵌入式软件系统状态空间的优点。例如,基于断言的验证和基于最先进软件模型检查器的形式验证相结合,并应用于使用C语言的嵌入式软件验证。

1.5 小结

本章介绍并讨论了最先进的嵌入式软件调试和验证技术的主要优点和不足。