当 The MathWorks 在 20 多年前推出 MATLAB 科学计算软件时,批用户中有很多人都是控制系统设计人员。曾经费尽心力通过手工对矩阵求逆来设计控制器的所有人都对 MATLAB 一见钟情。
MATLAB 简化了线性控制设计,但是在实际应用中,系统很少是线性的。因此,即使在设计了控制器后,对其进行测试和调整仍然意味着需要构建系统的硬件原型,并对算法进行编码。或者,因为没有样机而无法进行测试,只有等到开发流程后期才能开展测试活动。
为了将算法应用到硬件之前验证这些算法,工程师们借助数值技术来仿真控制算法对系统(也称为“对象”)的控制行为。控制工程师们学习编写 C 或 Fortran 程序来尝试构建系统模型,借用他们认为可能会适用于其系统类型的数值积分例程,在系统模型程序中复制其控制算法,并仿真整个系统。如果要使系统完全正常工作,那么整个仿真-开发流程需要耗费大量时间并且极具挑战性。
The MathWorks 在 1990 年发布了 Simulink,一种用于对动态系统进行建模和仿真的软件环境。在控制设计中使用 Simulink 可带来两大好处。首先,该软件提供了一种直观的框图环境,可用于对算法和对象以及可能影响系统行为的非线性实际效果进行建模。其次,该软件包括一个基于一流数值积分方法创建的仿真引擎。这些功能极大地简化了控制工程师通过仿真来验证控制算法的工作。但是控制工程师们仍然必须在对算法进行编码,以在硬件样机或实际系统上测试这些算法。
大约五年后,随着 Simulink 模型自动代码生成的推出,此流程变得简单得多。对于调试和测试在原型系统中运行的代码,控制工程师们不必再担心将算法模型转换为代码时出现错误。
控制工程发展的下一步曾是个很大的挑战:产品级的代码生成。快速原型代码通常包含许多调试例程、数据收集代码、主机-目标通信代码以及用于交互测试的其他补充代码。一般而言,这些代码的优化程度不足以将其运用在可交付使用的系统中。代码生成工具经过改进后,可以生成高效率的代码,足以部署到产品级嵌入式系统中。今天,许多行业都认为从控制模型自动生成产品级代码是的做法。
Model-Based Design(基于模型的设计)
处理器速度和内存的快速增加有助于在桌面上开发建模、仿真和代码生成工具,同样也使嵌入式软件开发人员可以改进嵌入式控制器的功能和复杂性。此步骤继而推动了这样一种需求:即使用文本编辑器和调试器的传统代码开发技术不再是一种局限,未来的设计将以模型为中心。这种以模型为中心的开发方法称为 Model-Based Design(基于模型的设计)(图 1)。
图1:以模型为中心的开发方法称为 Model-Based Design(基于模型的设计)。
通过基于模型的设计,团队可根据书面需求使用模型开发其设计。由于采用了仿真引擎,因此这些模型成为“可执行的规范”。对于开发和检查规范的团队而言,“规范可执行”是个极大的好处。检查完模型后,可使用设计详细信息修改模型,以便将其转换为代码。从详细设计模型自动生成代码极大优化了实现过程,并避免了从设计到代码转换过程中引入错误的可能。
传统的嵌入式控制系统的开发过程和V 型图一致(图 2)。
图2:传统的嵌入式控制系统的开发过程和V 型图一致。
此过程使所有验证和测试都位于 V 型图右侧,即完成设计和实现之后。对于基于 C 代码的传统嵌入式控制开发流程,集成测试通常在其他形式且级别逐渐提高的测试(例如硬件在环测试以及全系统测试)之前。虽然此开发顺序有助于组织复杂的系统设计,但还是有一些缺点:该顺序直到开发末期才考虑验证和测试,而此时修复所找到的任何错误都要付出代价且耗时;用户必须实现所有组件后才能测试系统;并且该顺序未能考虑开发过程中的迭代。
通过基于模型的设计,可以将验证作为并行活动,贯穿整个开发流程(图 3)。
图3:通过基于模型的设计,可以将验证作为并行活动,贯穿整个开发流程。
在开发流程的每一步进行测试和验证,意味着可在引入错误之处发现这些错误。与传统的 V 型图流程相比,可以更快地重复、修复和验证设计。那么该如何着手实现早期验证,从而减少在开发末期花费在测试和调试设计上的时间呢?下文概述了一些做法。
模型验证和确认
基于模型的设计实现验证和确认的主要方式是通过在仿真的过程中进行测试。虽然许多组织都进行某种形式的建模,但是大多是以专门的方式应用仿真,因此无法在上实现潜在的验证好处。单靠仿真无法发现所有错误;但这是一个巨大的进步,您几乎在开始设计模型时就可以进行仿真。建模环境中的迭代快速且方便。
对各个组件进行建模非常有用,可能是完成复杂设计所必需的;然而,不要因为这种优势,就不再对将在其中运行组件的系统或环境进行建模。通过在单一环境中对整个系统进行建模,您可以快速了解组件功能与其他组件的交互方式,以及集成组件在已部署的系统或环境中的行为方式。可能会发现对组件或其他方面的遗漏需求。通过使系统模型还原为迭代一个组件时的状态,可以*估设计迭代对系统功能的影响。
与设计和开发同时进行测试有助于检测出潜在问题,并可显著减少修复这些问题的成本和时间。通过在开发模型期间考虑测试,可使设计更适合于进行测试,从而确保可对设计进行完整测试。此原则的应用范围远不止嵌入式系统领域,但是嵌入式系统开发人员却常常忽视了此原则。原因是用户以为可以在软件中完成任何事情,也可能是文档化的开发流程忽视了此原则。然而,与新型灵活的软件开发流程一样,在设计模型之前或与设计模型并行开发测试是做法。
几乎每种测试方案都涉及到某些变数:输入、对象参数、环境因素或其他要素。时间和开支通常限制了测试方案的灵活度;然而,通过在仿真环境中进行测试,您可以更加快速且并行(如果处理能力够用)地仿真测试。在仿真中探查整个参数空间还可以缩小要实时运行的关键测试的范围。
每个组织都有针对设计和实现的标准或做法。这其中有许多标准并未形成文档,但是却被关键人员铭记在心。使标准书面化并将标准检查加入模型开发流程是很简单的做法,但却可以产生巨大的影响,因为这样做可尽早减少“愚蠢”错误的数量,确保模型在团队成员之间共享时更具可读性,并且更加容易在将来进行维护。对标准进行建模可以非常简单(如验证所有输入和输出是否已连接),也可以非常复杂(如是否满足行业标准)。关键在于开发一致的检查,然后在整个组织中推动对这些检查的遵从性。
确定测试组件何时能够满足需要通常不仅是一门科学,更是一门艺术,因为您通常要根据设计或测试工程师的判断来确定。对于软件组件,许多团队使用代码覆盖率作为更客观的标准来衡量测试的完整性。您同样可以将模型覆盖率用于模型测试。覆盖率用于衡量您在测试过程中测试了模型中(或源代码中)的多少逻辑。修改的条件/决策覆盖率是一种针对覆盖率的严格衡量标准,得到广泛接受。
大多数质量标准的原则是进行文档化。把需求,流程。结果记录下来。如果不进行记录,则不可能跟踪做过的事情;不可能向别人(如客户)证明您满足了他们的需求;也不可能重复您的结果。虽然记录通常很单调乏味,但是有许多工具可通过生成标准,来帮助自动记录活动。在您以后发现问题或希望重复使用设计时,良好的记录可帮助您节省时间,这也是非常重要的。
代码验证
这些做法是在模型级别开始早期验证的良好起点。,需要实现并部署到产品化硬件上。此时,代码验证成为重点。基于模型的设计可以提供哪些帮助呢?
自动代码生成是一种非常有用的方法。通过在模型级别验证您的设计,然后直接从模型生成代码,您只需要验证模型和代码是否等效。这是一种理想状态的工作流程。在实际情况中,有时不可能从模型生成需要的所有代码。您可能使用传统流程开发了一些中间件和设备驱动程序代码,或是可能将旧有代码用于某些功能。对于这些情况,可通过一些其他的做法来验证代码。
用户几乎可以在任何位置测试硬件;然而,硬件通常没有与仿真中的测试有连接。许多因素都可能导致这种没有联系的情况:在硬件上运行测试的小组与对设计建模的小组不是同一批人,在实验室中运行的软件与设计中的软件也不相同。然而,当您在模型上运行的测试与在实验室中运行的测试相同时,您就可以确切地了解设计在实验室中的执行情况。若要验证代码是否等效于设计模型,您可以将相同的测试工具用于模型测试,来测试已编译并在嵌入式目标上运行的模型软件实现。同时对组件设计模型和嵌入式目标上的代码运行测试是一种协同仿真步骤,称为 PIL(处理器在环)测试。现在,可以使用一些工具在软件上执行测试(开发人员在主机(如 PC)上创建的测试),同时也在嵌入式处理器上运行测试。将嵌入式代码与原始模型的测试结果进行比较,可帮助您确保组件的行为在编译和后保持不变,并确保代码可正确运行。
嵌入式代码中的运行时错误特别难以发现,一旦发现后,又难以进行调试。这类例子包括溢出和下溢、被零除和其他算术错误、超出范围的数组访问、非法取消引用的指针、对非初始化数据的只读访问以及危险的类型转换等。直到近,基本上只有三种选择可用于检测嵌入式软件中的运行时错误:代码检查、静态分析器和试错法动态测试。代码检查所需的人工工作量很大,通常不适用于大型的复杂应用程序。静态分析器可发现的问题相对较少,更重要的是,无法诊断大多数源代码。动态(或“白盒”)测试要求您编写并执行大量测试用例。如果测试失败,可能难以调试问题。基于形式验证的代码验证工具可以证明不存在运行时错误,并可为代码的可靠性提供强有力的保证。当在开发流程中使用代码验证工具进行测试时,这些工具还可提供其他技术,用于发现在后期测试阶段中难以发现并需要花费很高代价进行更正的设计和实现错误。
系统建模和仿真工具(如 Simulink)可帮助优化设计和验证复杂算法的任务,而无需昂贵的硬件。摒弃手工编码、难以维护的仿真后,控制设计人员可以快速开发复杂算法和系统模型,并在将算法应用到硬件上之前测试这些算法。经过多年经验的积累,现在已形成了可提供自动代码生成的方法,以支持原型系统中的实时测试并在以后用于可部署的嵌入式代码。现在,基于模型的设计已广泛应用于各种领域,包括控制、图像处理、音频、通信和信号处理。
基于模型的设计的一个主要好处在于,我们有机会随所有其他开发步骤(尤其是在开发流程早期)一起,并行地进行严格验证和确认。基于模型的设计的采用者通过不懈的实践已发现了一系列做法,使用这些做法可以在上获得这种设计带来的好处。这些做法(特别是随模型一起开发测试并在代码和硬件上重复使用模型测试)可以显著降低开发项目由于在流程后期发现错误而导致未能达到质量或交付目标的风险。
免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。