调试复杂电子系统从来都不是一项简单的工作,但至少是可以实现的。您要找到问题所在。采用您最相信的“示波器”,通过模拟电路到数字转换,您可以追溯到问题的源头。然后,编写测试小程序,检查驱动和外设,增加一些逻辑探针,再回到外设控制器和CPU总线上,最终解决问题。当然,这需要利用别人的一些代码。
而芯片系统(SoC)集成从根本上改变了这一切。今天,微处理器、总线、外设控制器以及大部分存储器和模拟电路都被包封在一个封装中。它可以是ASSP、高级微控制器、FPGA,或者您自己设计的ASIC。不论SoC是什么,事实上是,除非芯片设计团队愿意帮助您,否则,您不可能深入了解芯片内部。
在嵌入式CPU中调试硬件,为您提供断点和准实时跟踪等传统调试功能,从而帮助您完成调试工作。但是,对于他们自己,调试内核也只是给出了您系统的CPU外观视图。如果不能针对系统总体状态来更广泛的定义某一事件,那么,当事件发生后,您可能需要编写诊断短代码,使系统暂时停止工作,将相应的数据写回CPU。这一过程最好的情况是仅仅耗费了您的时间,而最差的情况是,耗费了时间却不一定能解决问题,效率非常低。
硅片知识产权(IP)供应商提供越来越精细的SoC仪表调试手段,从而解决了这一难题。但是,当今的产品是个性化的,而不是标准化的。系统设计人员需要在芯片设计早期阶段独立作出选择,而另一公司的其他团队则根据产品能否及时面市、管芯面积等来确定自己的目标,并不关心能否方便的进行系统调试。而芯片设计人员、软件开发人员和系统设计人员等参与者还是有一个共同点——互相协作,在系统级找到问题所在。
从一开始就做好规划
实际上早已决定了您是否能够成功的找到系统中的问题——两年前,在您目前正在使用的SoC的开发阶段。Brad Quinton是泰克公司嵌入式验证的首席规划师,他认为在芯片设计早期阶段进行规划非常关键,不仅仅是能够充分探查芯片,而且还涉及到采用什么样的调试硬件。然而,这并不常见。
芯片设计团队的确在测试结构中开展了前端工作,但却是出于其他原因。芯片中置入了测试设计和内置自测试硬件来支持IC测试。但是,这些资源并不是用于调试,一般只提供很少的诊断信息。芯片设计人员会专门针对硅片开发团队而内置工具,但是,这些工具可能只有内部文档,硅片一旦发布后,就会禁用这些工具。高速串行端口上会有边界扫描,甚至是非常复杂的仪表功能,必须在系统中对其进行调整。但是,这些手段是为了在电路板级建立并验证连接能力,而不是用于系统调试。
Quinton质疑,虽然这些结构非常有用,但是芯片设计人员会有更多的问题。Quinton认为,“从系统级进行考虑。关键接口、高级状态机在哪里?通过掌握哪些信息您能够知道哪一子系统正在工作?”
这些思考导致某些IP供应商开发了一类新模块:在SoC中设计实现仪表和控制器,不仅供设计芯片的IC团队使用,而且还有使用它的系统设计团队,如图1所示。
图1.片内调试电路本身会成为实际的设计。
从不同的方向开始工作,两类供应商验证了这一发展趋势。ARM扩展了其CPU内核调试内核CoreSight,涵盖了多核SoC的大部分工作,而现在是泰克一部分的Quinton Veridae从仪表模块开始,集中开发触发器/踪迹控制器,包括了CPU调试内核。这两种方法对于系统调试人员都非常宝贵。这都为在SoC基础上扩展可探查性提供了重要的理念。
数据源
虽然您想立即开始在系统结构图中加入各种各样的数据采集节点,而Quinton首先提出了一些基本问题。谁会使用调试功能:应用编程人员、模拟设计人员,还是机械工程师?他们会在哪一抽象等级上来定义事件;功能调用、信噪比、扭矩读数?这些用户会怎样做:确定他们的代码热点、找到瞬变噪声,或者知道驱动杆为什么失效?只有您理解了问题所在,才能够找到解决问题的数据。
Quinton认为,现在的技巧是确定在哪里收集数据。很明显,首先是在源头采集所有数据:A/D转换器(ADC)输出、状态寄存器、网络接口等。当然,您希望尽可能获得接近源头的一些信息,例如,受控物理器件的状态等。
但是,在其他情况下,事先考虑好在哪里采集数据可以减少测量开销,以及后分析所需要的数据量。Quinton建议,“找到关键地方来观察系统。在一点上所通过的系统状态量会让人感到惊讶:例如,CPU与系统总线的接口。”
在哪里对数据进行采样也取决于用户所希望的抽象级。例如,可能是通过PCI Express (PCIe)总线的系统交换信息等。探查串化器/解串器(SERDES)和PCIe控制器,使您能够获得底层协议层工作的详细信息,这对于总线接口调试非常重要。但是,如果您希望总线接口能够正常工作,观察信息流,那么,您最好监视主存储器中的缓冲,而忽略总线控制器。
问题的相对性
一旦找到了您需要的数据,确定了要在系统中的哪些地方来提取这些数据,那么,您需要收集数据,知道数据与时间的相关性,找到触发模式,采集您希望保存的数据,从系统中提取出这些数据,送入分析工具中。在分立系统中,这一过程相对简单:所有工作都可以回到逻辑分析仪中完成,分析仪提供统一时间基础。在基于SoC的系统中,您可能希望把所有数据送回SoC的中心模块中,如图2所示。好消息是,泰克和ARM的IP简化了这一过程。
图2.完整的片内调试系统结合了传统的CPU内核调试和数据采集站以及信息路由,提供将数据从芯片中输出的方法。
但是,使用IP带来了新问题。中心模块和电路板另一侧芯片之间的延时会有十几个时钟周期。即使在芯片内部,也会有数十个时钟域,当您跨过时钟域边界时,延时会增加很多CPU周期。您怎样知道两路数据是同时的呢?
如果您要开发自己的调试工具,那么,这会很难。您可以估算数据采集模块和中心控制器之间的传播延时,然后,对数据流进行后处理,使其对齐。但是,这一方法难以解决时钟域交叉的非确定性延时问题。您可以分配一路主时钟,使用它对您采集的数据进行时间戳处理,但是,这需要很大的电路开销。泰克等提供的商用解决方案同时使用了硬核IP和软件算法,在底层自动完成所有这些工作。通过这些算法,可以在一个与时间相关的视图中看到SoC不同时钟域和不同物理位置上的事件,通常会发现意外的系统行为。
即使是自动完成,仍然会有变化。如果把在系统中不同部分同时发生的小事件作为触发器,只定义这类事件——例如,ADC输出等于0,而一个CPU内核进入某一中断服务例程,那么会出现什么情况?如果事件不仅仅涉及到不同的地方,而且还有不同的抽象级——例如,串行端口的接收眼图闭上后,出现了堆栈上溢,又会怎样呢?Quinton把这类跨域分配事件触发描述为系统触发的“圣杯”。正如这一隐喻所示,很难找到合适的解决方案。但是,采集了足够的数据,经过认真思考,构建能够采集这类复杂事件的本地触发器,通常能够实现这些解决方案。
从芯片到系统
我们详细讨论了芯片级调试功能,它比简单的CPU调试内核有很大的进步。对于开发自己的SoC的系统设计人员,这些数据非常有用。但是,其他人会怎样,谁会使用他人的芯片设计?这里的很多理念仍然能发挥作用。
其中最首要的是重视提前做好规划:确定用户及其使用环境,制定测试策略,回答这些用户可能提出的问题,规划数据采集来支持这一策略。最大的不同是,芯片设计人员会提出这些问题,然后,在他们的SoC中开发结构。系统设计人员也会提出问题,然后,通过SoC供应商所提供的工具以及他们的支持来解答问题。
相应的,系统设计团队至少会向他们的SoC供应商提出三类很难的问题。第一,芯片供应商会提供调试工作台——例如,Tektronix或者ARM主软件包,来控制SoC的调试硬件吗?主软件包能够很好的适应您现有的系统调试环境吗?
第二,硬件实际接触SoC中的哪一点?您只获得了一个CPU内核的触发/跟踪功能,或者芯片提供CPU、加速器、总线和外设控制器的扩展采集,跟踪以及交叉触发功能吗?第三,调试子系统会提供哪些方法来观察系统中其他芯片和器件的状态?
这些问题的答案会定义系统团队连接哪类外部测量设备工作台,在哪些工作台上能够实现他们的系统调试计划。在这么多的系统工程中,关键是尽早开始对调试进行规划——在工程的体系结构设计阶段。没有足够的数据呈现,就开始调试基于SoC的系统,这种场景很快就会很难维持下去。 |