首页 > 新闻中心 > > 正文

应用硬件和软件协同验证缩短嵌入式系统开发周期

更新时间: 2005-10-27 00:00:00来源: 粤嵌教育浏览量:3747

  协同验证是一种相对较新的技术,它可以使软件开发人员尽早接触到硬件设计部分。而在该技术出现以前,嵌入式系统开发人员常常要等到硬件样机做出之后才能编写软件,再把它放在系统上运行。随着当今项目开发周期的缩短和复杂程度增加,迫使开发人员必须寻找新的途经,以便尽早开始编写和调试软件。本文以喷墨打印机控制器为例,介绍软硬件协同验证的一种实际应用。

    协同验证就是在嵌入式系统模型上执行目标系统软件,而该嵌入式系统则是在一个模拟器中运行。软件执行时有一个专门的处理器模型通过普通的软件调试器与硬件和软件联系,使软件开发人员能看到二者的运行情况。为了提高性能,协同验证使用了周期隐藏技术,以便在硬件模拟中去除总线访问时间。周期隐藏虽然极大地提高了模拟的性能,却会使硬件和软件模拟失去同步,这对于依赖硬件定时器的验证系统而言是一个严重的缺陷,使用实时多任务操作系统时这一点尤为明显。事实上,许多开发人员认为在模拟硬件中运行实时操作系统(RTOS)是不可能的。

    美国In-System Design公司的开发人员使用协同验证技术对喷墨打印机控制器(一个系统级芯片)用的VxWorks操作系统进行早期测试,测试使用Mentor Graphics的无缝协同验证环境(Seamless CVE)和其它工具验证硬件-软件接口,并对RTOS在任务间的切换性能进行了研究。 

    硬件-软件协同验证

    协同验证技术将一个专用处理器模型和一个运行于逻辑模拟器中的嵌入式系统模型结合在一起。硬件开发人员使用硬件描述语言(HDL)创建嵌入式系统模型,然后将可执行目标-系统软件的镜像文件加载到嵌入式系统模型存储器中,就像在实际系统样机上那样运行,也就是把软件放在一个“虚拟”的在线电路模拟器上运行,这样就能在得到物理样机以前对软件进行测试。

    协同验证中的嵌入式处理器模型有三个主要功能:首先当然是在执行指令时它必须能够模拟出处理器的动作,做到这一点常用的方法是使用指令集模拟器;其次,它应使软件设计人员能够观察和改变硬件和软件的状态,一般是通过图形化调试器;,它要能够与硬件进行交流,总线接口模型可提供这一功能。总线接口模型将处理器总线周期活动转换成引脚状态变更序列,在逻辑模拟器中模仿处理器总线的动作,总线接口模型还要能处理硬件设计中产生的复位、中断和其它异步事件(图1)。

    协同验证将处理器模型和设计模型的其余部分联系起来,使它们能够协调运行,工作时一般从逻辑模拟器和软件调试器开始,在硬件和软件之间建立起通信联系。设计人员首先启动逻辑模拟,使设计运行起来,然后载入软件的可执行镜像文件(通常用软件调试器),再在调试器上进行硬件和软件模拟。设计人员通过软件调试器观察处理器、寄存器及存储器的内容和变动情况,逻辑模拟器和软件调试器具有各自环境下所能提供的所有调试功能。

    带有处理器和存储器全功能模型的完整描述硬件设计虽然可以全部放在一个逻辑模拟器中运行,并从该设计的存储器中执行代码,但这样做太慢了。实际的设计一般情况下每秒钟运行5条指令,通过简单的数学计算我们可以算出8个小时只能运行约144,000条指令。看一看大多数系统所含软件的大小就可知道,这种执行速度做什么都显得太慢,仅能验证很小一段代码。此外,只使用逻辑模拟器也无法得到软件内部的调试可视性。

    增强模拟性能

    所有成功的协同验证都利用了“周期隐藏”技术来改进性能,并且只执行软件中起作用的部分。周期隐藏在主机系统存储器阵列中直接处理某些存储器的通信,而不通过逻辑模拟器。结果表明大多数总线周期都可以被抑止掉,并不会影响模拟的精度。让我们看一个取指令的例子:当逻辑模拟器运行取指令时,需要将一个总线周期传输给存储器控制逻辑和存储器单元,存储器然后把内容回传给处理器,后者将它们解释成下一条指令。为执行一个取指令操作,逻辑模拟器必须处理数以百计的模拟事件,这将消耗主机大量计算时间,然而取指令在硬件上并不会造成明显的状态变化,因此可从逻辑模拟器中安全地将其省略掉。

    为进行协同验证,在硬件模拟外部设置一个简单数据阵列,用以保持嵌入式软件存储器镜像文件,这样可使指令集模拟器以更快的速度取出操作码,同时不影响模拟结果。指令集模拟器处理操作码并确定需要产生什么样的数据移动和总线周期,它将该信息传送给协同验证工具,后者决定是在数据阵列(“软件”区)中还是在逻辑模拟内部的模型存储器(“硬件”区)中进行处理。

    如果是硬件区,总线接口模型将从引脚接口驱动一系列信号转换至逻辑模拟器中模拟总线周期。在读周期里,数据随任意中断或其它总线周期处理过程中可能形成的禁止命令返回至指令集模拟器。如果我们将代码空间放在软件区中,也就是说它处在一个能快速访问指令集模拟器的存储器阵列中,这时硬件模拟只需要处理三个总线周期。大多数参考数据也可以屏蔽掉,此时还可以将硬件总线周期数减少到两个。

    那么有多大比例的总线周期可从硬件模拟中隐藏掉呢?经验显示,嵌入式软件产生的总线周期99.9%以上都能从硬件中屏蔽掉。直接访问硬件模拟外部存储器阵列的总线周期比逻辑模拟快10,000倍,假设一个程序产生1,000个总线周期,并且I/O周期相对于取指令和数据周期之比为1:1000,那么协同验证要执行999个代码和参考数据,速率为每秒钟100,000次转换,同时一个I/O周期每秒钟发生5次转换。这就要在I/O周期(硬件模拟)上加0.2秒,代码和参考数据(软件模拟)上加0.00999秒,总运行时间为209.99毫秒。

    很容易看到,逻辑模拟器是一个瓶颈,因为它占用了95%以上的时间。指令集模拟器相对也比较慢,但协同验证本身的运行速度还要慢10倍以上。和一般人设想相反,用执行模式较快的软件来替代指令集模拟器并不能对协同验证性能作实质性的改变,即使在我们例子中将指令集模拟器性能提高1,000倍,其结果在总的工作时间上也只提高了不到5%(从209.99毫秒到200.00999毫秒)。

    我们可以得出结论,为了使协同验证更为有效,大多数总线周期必须从硬件中屏蔽掉。幸好嵌入式代码使我们能做到这一点,可将性能提高100倍。但它依赖于这样一个事实,即硬件和软件多数时候是对事件而不是对时间同步。像实时多任务操作系统之类硬件和软件时间同步非常重要,此时实际验证过程就需要用一些方法来处理周期隐藏所带来的时间“偏差”。

    隐藏周期问题

    如上所述,由于所屏蔽的存储器转换类型并不影响被模拟硬件的状态,所以协同验证中隐藏总线周期对逻辑模拟几乎或根本就没有影响。但是假设设计要依靠由系统时钟驱动的硬件定时器,那么当协同验证禁止大多数总线周期的硬件模拟活动时时钟将不再计时,定时器与运行在指令集模拟器中的软件就会严重失去同步。

    协同验证工具至少需要做两件事来补偿“时间偏差”。首先,必须仔细计算失去的总线周期时间,要考虑给定指令所用到的周期数,以及高速缓冲存储器的时序、流水线效应、总线获取次数和其它因素;第二,协同验证工具应能对硬件设计中的定时器寄存器进行更新,并使逻辑模拟在任何重要事件发生时都立即做出响应,如像定时器发出的中断等。

    模拟所需定时精度取决于要验证的是什么。为使运行系统定时器保持状态,我们可为每个总线周期假设一个时钟数,然后简单地对总线周期计数,这可使我们得到一个准确度约为10%或20%的粗略估算值。但为了具体描述系统性能,本例中的中断等待时间需要更为准确的定时模型。我们用的是基于ARM的处理器,其模型包括用于内部流水线的定时模型,它同时考虑了等待状态和总线获取次数等情况。因为我们的处理器没有数据高速缓冲存储器,所以就没有考虑高速缓冲存储器。除了计算隐藏周期时间外,我们还必需确保定时器触发中断时,硬件没有处在“隐藏”的总线周期内。这里的硬件设计是一个喷墨打印机用SoC控制器,使用PCL 3输入子集并创建打印用光栅影像,它由一个ARM嵌入式处理器和ASIC逻辑组成,后者完成视帧-处理逻辑、存储器控制逻辑和外部接口。外部接口包括串行、并行和USB接口,以及机械部分控制器(PMC)和前面板接口(图2)。

    首先运行设计中的板级支持软件包(BSP),这是一个用于第三方镜像应用的API(包括ASIC接口驱动器),同时运行风河公司的VxWorks操作系统。为描述整体系统功能并观察协同验证工具的效果,我们创建了几个小任务在RTOS中运行。

    协同验证的目的是调试BSP及验证系统是否能引导至VxWorks上。为做到这一点,需要证明中断控制器及其驱动器以及串行口和定时器都工作正常,此外还要观察协同验证中任务的创建和调度情况,并判断运行应用级代码时性能是否足够。

    无缝CVE运行协同验证无需改变系统软件。能够运行实际的目标-系统软件是很重要的,我们做了一些更改以便在没有作硬件设计的地方也能工作,同时还对软件进行修改以提高系统性能,为了使系统引导速度更快还将几个存储器测试缩短或省掉。将VxWorks标志打印至通用异步收发器(UART)要用一小段代码,会占几分钟模拟时间,因此运行一次后也将其省掉;同时还修改UART驱动器,使其输出一个可从总线上探测到的地址,并略去检查所有可能波特率的UART测试;我们引用在大量存贮区域填零的C运行-时间库,不使用调试宏初始化这些存储器。

    运行协同验证时硬件设计也需要作一些修改。我们用ARM提供的协同验证模型替代处理器,这只需要增加一个新的VHDL结构和改变双线配置即可。另外还需要用协同验证模型代替几个存储器,该模型在逻辑模拟中不使用会降低速度的总线周期即能使软件调试器访问硬件存储器,并使协同验证工具从硬件和软件的角度对存储器得出的结论都一致。该方法非常直观,不到的时间就能完成。

    硬件定时器可以与软件同步,只要在定时器HDL描述中增加几个函数调用,即可用软件同步时间更新定时器状态。我们改动了约40行HDL源代码并在几小时内完成了任务。

    ,在硬件中还要增加一个总线监视器,用来监视地址0x31000000处的写入周期,也即在UART修改过的地址,从RTOS来的调试输出就写在这里。该项工作用ModelSim逻辑模拟器TCL/TK扩展语言编写,总线监视器在Sun工作站上打开一个窗口,使我们看到RTOS执行时的输出数据。 

    硬件-软件同步

    在得到正确模拟结果之前,先要解决几个时间同步问题。显然,硬件定时器需要不断更新,同时也要在所谓的“原子交换”期间保持同步,“原子交换”是一种相对于硬件和软件而言非常小但必须执行的存储器交换。设计中有几个直接存储器存取(DMA)通道传送数据进出系统,我们要确保硬件有足够的时间(或者模拟时钟周期)完成所有DMA传输。,性能分析需要时间同步,而我们也对测量系统中断等待时间很感兴趣。

    设计中包含三个定时器,用于追踪硬件时间和产生操作系统计时周期(16毫秒)。假设典型的隐藏与不隐藏周期之比为1000比1,则软件在操作系统计时到达之前将经过约16秒钟,我们希望将硬件操作系统计时减少为16微秒并且一切正常。当然如果某个任务所需要的硬件运行时间大于16微秒,系统就会失效,而这也是经常会发生的。将操作系统计时定为16微秒迫使任务调度算法采用“运行-完成”方式。由于我们许多任务只是简单地一直运行下去,并且为了正确地验证系统任务也需要运行一段时间,所以这里不支持“运行-完成”模型,我们的任务转换模型为优先级抢先方式,同样优先级的任务采用轮流方式。

    系统复位时,装有系统引导复位代码的ROM位于地址0x0处,但是VxWorks和嵌入式ARM处理器异常表运行也要用到这个地址的RAM,因此作为引导过程的一部分,我们将ROM从0x0移至0x800000,而将RAM从0x800000移至0x0,交换完成之后我们再执行ROM中的代码。为了正确交换存储器而不影响软件,硬件和软件必须处于不完全同步状态,且协同验证工具必须能够在模拟期间重新配置存储器区域。

    性能验证

    软件通过将指针和计数器值写入DMA控制器的寄存器中建立DMA传输,它假定由硬件完成操作过程。为执行操作,硬件要运行一定数目的总线周期,但如果协同验证屏蔽了大量周期,DMA操作就可能无法完成。有鉴于此,协同验证工具必须能够在DMA传输期间停止周期隐藏。我们可以在软件中设置中断点以便在DMA开始时停止周期隐藏;在硬件中则设置监视DMA完成的断点,到时候使周期隐藏重新作用。这样DMA就不需要手工干预就能正确运行了。

    我们的设计按协同验证进行配置,并在Sun Ultra Sparc 60工作站上作了一系列测试,该工作站装有2个360MHz处理器、2G RAM和Solaris 2.6操作系统。所有软件工具均来自Mentor Graphics公司:硬件模拟器为ModelSim Version 5.4、软件指令组模拟器/调试器为XRAY Version 4.4、协同验证工具为Seamless CVE Version 4.0。软件用C、C++和ARM汇编语言编写,使用VHDL和Verilog两种版本的寄存器-转移级设计模型。时钟节拍

    从复位到创建个VxWorks任务耗时约18分钟,其中硬件初始化和自诊断占用了大部分时间。这时逻辑模拟器定时为1.6毫秒,系统的操作系统计时每16毫秒触发一次。我们估计采用硬件时钟连续运行模拟(即不直接进行定时器更新)而达到个操作系统计时点大约需要150分钟(两个半小时),而达到第二个操作系统计时点差不多要3个小时。如果能直接更新定时器对隐藏的总线周期计数,我们就可抽出空的RTOS循环而不用在速度很慢的逻辑模拟器上慢慢爬行了。改造完成后操作系统计时的触发速率可达每分钟4次。

    我们创建并运行两个任务,以便在RTOS于任务间切换时测量它的性能。任务很简单,就是写一个字符给UART,然后在工作站的窗口上将这个字符显示出来,当字符送至UART时,任务就停止计时。通过监视字符的显示情况,可测出系统在任务间切换时的性能。我们的结论是每秒钟可以有16次切换。

    在另一个实验中,我们将操作系统时段定为10个计时周期,总时间为160毫秒,然后让RTOS在两个简单任务间切换,每个任务在一个时段内进行一个220,000次的简单循环。将代码分解开后,我们看到任务内部的循环含有11条指令,而总数约为2,200万条指令,模拟结果发现每170秒钟可完成一个时段。

免费预约试听课