基于时间的调度和代码生成
计算状态的采样时间和模块
Simulink® 模型中模块的采样时间指定模块何时产生输出,如果合适,在仿真或生成的代码执行期间会更新其内部状态。模块的内部状态包括(但不限于)Simulink 计算和记录的连续和离散状态。对于定义离散状态的模块,Simulink 计算每个时间步的状态值。定义连续状态的模块依靠数值积分来计算内部状态值。一个模型可以包括连续模块、离散模块或同时包含连续模块和离散模块。包括这两种类型的模块的模型是混合系统。
通常,您可以使用连续模块以变步长积分形式对方程进行建模,以便控制仿真的准确性。MathWorks® 不推荐在您打算生成生产代码的模型中使用连续模块,尤其是对于安全关键型应用。连续模块依靠数值积分来计算连续状态,这会影响软件执行的确定性和生成代码的执行速度的数值准确性。在实现所需结果后,您可以将连续模块转换为离散模块(请参阅离散化),离散模块具有可预测的步数,因为您知道定步长。
Embedded Coder® 默认情况下不支持使用连续模块,也不支持配置为使用服务代码接口的模型。
如果您使用 Embedded Coder(例如,如果系统目标文件设置为 ert.tlc
)从包含连续模块的模型生成代码,请选择模型配置参数支持: 连续时间 (Embedded Coder)。
有关在您打算从中生成代码的模型中使用连续和离散模块的详细信息,请参阅以下页:
有关连续和离散模块库中的模块列表,请参阅Continuous和离散。
支持代码生成的模块描述如何获取有关 Simulink 内置模块和产品特定模块集模块的信息,您可以在用于代码生成的模型中使用这些模块。
如果要从模型中生成行优先代码,请参阅Unsupported Blocks for Row-Major Code Generation。
如果您要为包含连续模块的启动变体模块的变体选择项生成代码,请参阅Run Executables for Variant Blocks Without Recompiling Code for Changing Active Choices Using Startup Activation Time (Embedded Coder)。
要使自定义系统目标文件支持连续时间,您必须按照自定义系统目标文件中所述修改系统目标文件。
多速率系统和速率转换
通过设置控制模块计算和执行速度的模块采样时间,您可以对单速率和多速率离散系统以及连续-离散混合系统进行建模。Simulink 为设计多速率系统提供了相当大的灵活性。为了使多速率模型按照预期实时运行,模型必须处理配置为使用不同采样时间的模块之间的速率转换。
默认情况下,如果模型包含未受保护的速率转换,则 Simulink 引擎会在仿真期间返回错误。使用诊断模型配置参数多任务数据传输指定 Simulink 引擎在检测到无效转换后是否显示警告并返回错误。
为避免速率转换错误,请在配置为使用不同采样时间的模块之间插入 Rate Transition 模块。您可以显式插入 Rate Transition 模块,也可以配置模型,以便 Simulink 引擎在图更新期间检测不匹配的速率转换,并为您插入隐藏的 Rate Transition 模块。要指示 Simulink 引擎插入模块,请选择模型配置参数自动处理数据传输的速率转换。
为了理解检测和处理速率转换的重要性,请考虑 Simulink 仿真与实时程序执行的差异。
模型仿真期间的速率转换
在仿真模型之前,Simulink 引擎根据模块的拓扑依赖关系对模型中的模块进行排序。这包括将虚拟子系统扩展到它们所包含的各个模块中,以及将模型展平为单个列表。完成此步骤后,每个模块将按顺序执行。
此过程的关键是模块的排序。生成的输出直接取决于模块输入的模块(即具有直接馈通的模块)只有在为其提供输入的驱动模块执行后才会执行。
实时程序执行期间的速率转换
实时程序与 Simulink 仿真的不同之处在于实时程序必须以实时方式同步执行模型代码。每次计算都会导致一定的计算延迟。这意味着采样间隔不能缩短或延长(因为它们可能在 Simulink 仿真中),从而导致执行效率降低。当多个任务可能同时访问相同的数据时,需要进行速率转换。
请考虑以下时序图。
在图中,标有 t0
、t1
和 t2
的垂直线表示采样时间命中点。蓝色区域表示由 Simulink 引擎执行。空白区域显示处理器闲置的时间。
从时间 t1
到时间 t2
的采样间隔中发生了处理效率低下的情况。您不能压缩该间隔来提高执行速度,因为根据定义,采样时间是以实时方式计时的。
您可以通过在多任务模式下为模型配置代码生成来规避这种低效情况。多任务模式为任务指定不同的优先级,以分别执行具有不同采样率的模型代码部分。请参阅任务模式。
离散化
离散化是用离散的等效模块替换连续模块的过程。如果模型包括连续模块,并且您准备生成生产代码或执行硬件在环 (HIL) 仿真,请考虑这些用来对模型进行离散化的选项。
如果您有版本 5.2 或更高版本的 Control System Toolbox™ 许可证,请使用 Simulink 模型离散化器执行以下操作:
识别模型中的连续模块。
将模块参数从连续更改为离散。
将离散化设置应用于连续模块。
创建包含多个离散化候选项和原始连续模块的可变子系统。
在离散化候选项之间切换,并评估模型仿真结果。
有关示例,请参阅使用模型离散化器离散化模型。
如果您有 Control System Toolbox 或 System Identification Toolbox™ 许可证,请使用
c2d
函数离散化某个状态,然后将离散状态放入模型中。
任务模式
对于配置为使用定步长求解器的模型,代码生成器支持周期性采样时间的两种任务模式(执行模式):单任务模式和多任务模式。在仿真期间,模型仅在单任务模式下执行。有关如何在这两种模式之间切换的信息,请参阅Configure Tasking Mode。
单任务模式
在单任务模式下设置模型可能会:
简化模型。
减慢执行速度。
在单任务模式下,模型的基本采样率定义的时间间隔必须足以在该时间间隔内执行模型(即模型中的所有模块)的一个时间步。
以下时序图显示使用单任务模式时固有的低效情况。
在图中,标有 t0
到 t4
的垂直线表示采样时间命中点。蓝色区域表示由 Simulink 引擎执行。空白区域显示处理器闲置的时间。
有关单任务执行和示例的详细信息,请参阅Tasking Modes and Execution Order。
多任务和伪多任务模式
当周期性任务在多任务模式下执行时,默认情况下,采样率最快的模块作为优先级最高的任务执行,次最快的模块作为高优先级次的任务执行,依此类推。处理高优先级任务之间的可用时间用于处理较低优先级的任务。这会提高程序执行效率。
当任务是异步而非周期性任务时,采样率和任务优先级之间可能没有关系;具有最高优先级的任务不需要具有最快的采样率。您可以使用 Async Interrupt 和 Task Sync 模块来指定异步任务优先级编号。您可以通过选中或清除模型配置参数优先级值越高,任务优先级越高来切换优先级编号的含义(即,是较高还是较低的优先级编号对应于较高优先级的任务)。
在包含实时操作系统的多任务环境中,您可以定义单独的任务并为它们分配优先级。对于没有实时操作系统的裸机目标硬件,您无法创建单独的任务。然而,生成的应用程序模块通过使用重叠中断和对上下文切换进行编程来实现有效的多任务执行方案。
这意味着一个中断可能在另一个中断正在进行时发生。发生这种情况时,当前中断会被抢占,浮点单元 (FPU) 上下文会被保存,优先级较高的中断会执行优先级较高(即采样率较快)的代码。一旦完成,控制权将返回给被抢占的中断服务例程 (ISR)。
在下面的两个时序图中:
标有
t0
到t4
的垂直实线表示采样时间命中点。蓝色区域表示由 Simulink 引擎执行。
空白区域表示处理器闲置的时间。
斜纹区域表示较高优先级任务进行了任务抢占。
带向下箭头的垂直虚线表示将 CPU 的控制权释放给较低优先级的任务。
带向上箭头的垂直虚线表示优先级较高的任务进行了抢占。
此图显示在多任务环境中如何处理多速率系统中任务的执行时序。
下图显示如何使用重叠中断来实现伪多任务。在这种情况下,中断 0 要在中断 1、2 和 3 执行完毕才会返回。暗线表示中断的执行路径
注意
使用多任务的多速率模型不能引用使用单任务的多速率模型。
有关多任务执行和示例的信息,请参阅Tasking Modes and Execution Order。
任务注意事项
单任务程序需要较长的采样间隔,因为每个时钟周期内都必须执行所有计算。这可能导致可用 CPU 时间的使用效率低下。
如果模型很大并且有许多以不同速率执行的模块,多任务模式可以提高程序的效率。
如果模型主要采用某一种速率,只有少数模块以较慢的速率执行,则多任务可能会降低性能。任务切换所产生的开销可能大于执行较慢模块所需的时间。在这种情况下,以用得最多的速率执行所有模块更为高效。
如果模型可以从多任务执行中受益,则添加 Rate Transition 模块(或指示 Simulink 引擎修改模型)以生成预期的结果。