主要内容

生成用于导出到外部代码库的组件源代码

如果你有嵌入式编码器®软件方面,您可以从建模组件生成功能源代码,以便在外部代码库中使用。生成的代码不包括支持调度的代码(例如,阶跃函数)。金宝app在Simulink之外控制逻辑金宝app®环境调用生成的函数代码。

建模选项

您可以为这些建模组件生成要导出的函数代码:

  • 导出功能模型(包含功能块的模型,这些功能块仅由函数调用子系统、函数调用模型块或其他导出功能模型组成,如导出函数模型概述

  • 导出函数子系统(包含函数调用子系统的虚拟子系统)

要导出代码生成器为这些建模组件生成的代码,建模组件必须满足特定的需求

对于在早期版本中设计的模型,代码生成器可以从被触发的子系统导出函数。导出功能子系统的要求也适用于从触发子系统导出功能,但有以下例外:

  • 封装您打算在顶级虚拟子系统中从中导出功能的触发子系统。

  • 被触发的子系统不必满足为包含函数调用子系统的虚拟子系统确定的需求和限制。

  • 导出使用绝对时间或经过时间的函数不适用于从被触发的子系统导出函数。

需求

  • 模型求解器必须是固定步长离散求解器。

  • 您必须配置触发函数调用子系统的每个根级import块以输出函数调用触发器。这些导入块不能连接到异步任务规范块。

  • 模型或子系统,必须在根级别只包含以下块:

    • 函数调用块(如函数调用子系统、Simulink函数、S-Functions和函数调用模型块)如果求解器模型配置金宝app参数在根级任务分配和时间选择>周期采样时间约束设为确保采样时间无关

    • 输入和输出模块(端口)

    • 常量块(包括解析为常量的块,如Add)

    • 采样时间为Inf的块

    • 合并和数据存储内存块

    • 虚拟连接块(例如,函数调用分割、Mux、Demux、总线创建器、总线选择器、信号规范和包含这些块的虚拟子系统)

    • 信号查看器块,例如作用域块(仅限导出函数子系统)

  • 当一个常量块出现在模型或子系统的顶层时,您必须设置模型配置参数优化>默认参数行为的模型或包含模型内联

  • 模型或子系统中的块必须支持代码生成。金宝app

  • 使用绝对时间或消耗时间的块必须位于周期性函数调用子系统中,并在相应的函数调用根级Inport块上指定离散采样时间。看到导出使用绝对时间或经过时间的函数

  • 跨越导出系统边界的数据信号不能是虚拟总线,不能实现为Goto-From连接。跨越导出边界的数据信号必须是标量的、混合的或非虚拟总线。

此外,对于导出函数模型,您不能为包含导出函数模型的多个实例的基于速率的模型生成代码。例如,您不能为您在模拟期间用于调度可重用导出功能模型的测试工具模型生成代码。

对于输出功能子系统,适用以下附加要求:

  • 跨越导出功能子系统边界的触发信号必须是标量的。不作为触发器的输入和输出数据信号不必是标量。

  • 当一个常量信号驱动导出功能子系统的输出端口时,该信号必须指定一个存储类。

导出使用绝对时间或经过时间的函数

如果你想用使用绝对时间或经过时间的块为建模组件导出函数代码,这些块必须在函数调用子系统中:

  • 您可以配置为定期执行

  • 使用离散的采样时间配置根级import块

为定期执行配置一个函数调用子系统:

  1. 在函数调用子系统中,右键单击触发阻断并选择块的参数从上下文菜单中。

  2. 设置参数采样时间类型周期

  3. 样品时间到函数调用启动器中指定的相同粒度(直接或通过继承)。

  4. 点击好吧应用

有关更多信息,请参见绝对时间和运行时间计算

导出功能子系统的限制

  • 子系统块参数不控制包含生成代码的文件的名称。文件名以导出子系统的名称开头。

  • 子系统块参数不控制生成代码中顶级函数的名称。每个函数名反映了触发该函数的信号的名称,或者(对于未命名的信号)反映了信号产生的块的名称。

  • 只有当函数规范设置为时,才能为c++类代码接口打包导出函数调用系统默认步进法。看到自定义生成的c++类接口。导出的函数与单线程执行兼容。为了避免共享信号的潜在数据竞争条件,请从同一执行线程调用类的所有成员。

  • 只有当函数调用启动器在加速模式下非内联金宝app时,代码生成器才支持加速模式下的SIL或PIL块。非内联启动器的例子包括Stateflow®图表。

  • 二级s函数启动块,如状态流程图或内置函数调用生成器块,必须驱动一个SIL块。

  • 您可以导出异步(示例时间)函数调用系统,但是该软件不支持异步系统的SIL或PIL块。金宝app

  • TLC功能的使用LibIsFirstInit已移除输出功能子系统。

工作流

要为导出函数生成代码,请遍历该表中列出的任务。

任务 行动 更多的信息
1 检查您对外部代码特征和集成需求的评估。 选择外部代码集成工作流
2 验证您导出的模型或子系统是否满足功能导出需求。 需求
3. 通过修改模型或子系统来满足数据接口需求。 在外部C/ c++代码和Simulink模型或生成的代码之间交换数据金宝app
4 如有必要,配置函数原型。 为Simulink函数和函数调用者块配置入口点函数接口金宝app对于基于固定步长速率的模型,为模型入口点函数配置C代码生成自定义生成的c++类接口
5 如果有必要,更新模型,将外部特定于应用程序的代码放入生成的系统函数中。 将外部C/ c++代码放在生成代码中
6 通过创建和使用测试工具模型,验证在模拟过程中功能的行为和执行是否符合预期。测试线束模型在仿真期间安排功能的执行。 配置模型、生成代码和模拟如果你有金宝app仿真软件测试™软件测试编写(金宝app仿真软件测试)
7 为代码生成配置模型或子系统。 使用嵌入式编码器®生成代码生成与外部代码外观匹配的代码,模型配置
8 生成代码和代码生成报告。 代码生成
9 检查生成的代码接口和静态代码度量。 分析生成的代码接口静态代码度量
10 构建包含导出的函数代码的可执行程序。 在Simulink环境之外构建集成代码金宝app
11 验证可执行程序的行为和执行是否符合预期。

选择集成方法

有多种方法可用于生成导出到外部开发环境的功能代码。下表比较了各种方法。选择最符合您的集成需求的方法。有关如何创建导出函数模型的详细信息,请参见导出函数模型概述。有关为函数调用子系统生成代码的更多信息,请参见生成用于导出到外部代码库的组件源代码

条件或要求 使用 更多的信息
  • 建模元素和生成代码之间的可追溯性

  • 本地输入(输入模块)和输出(输出模块)

函数调用子系统
  • 控制生成的函数原型

  • 正式输入参数(参数输入块)和输出参数(参数输出块)

  • 本地输入(输入模块)和输出(输出模块)

金宝appSimulink功能块
代码响应初始化事件 初始化函数块
代码响应重置事件 功能块
代码包括超出代码生成器默认生成的入口点函数(模型_initialize模型_step,模型_terminate 功能 s函数和代码生成
将单个模型执行框架用作测试工具,并导出为模型部分生成的代码 导出功能子系统

生成导出函数模型的C函数代码

这个例子展示了如何在不生成调度代码的情况下为模型中的单个Simulink功能块和函数调用子系统生成功能代码。金宝app

生成用于导出的函数代码:

  1. 创建一个包含导出功能的模型。

  2. 创建一个测试工具模型,在模拟期间安排功能的执行。

  3. 通过使用测试工具模型模拟包含功能的模型。

  4. 为包含函数的模型生成代码。

创建包含导出函数的模型

具有导出功能的模型必须满足模型根级的体系结构约束。在根级别,有效的块是:

  • 轮廓尺寸

  • 外港

  • 函数调用子系统

  • 金宝app仿真软件的功能

  • 转到

  • 合并

代码生成器为函数调用子系统、Simulink函数、初始化函数和重置函数块生成函数代码。金宝app对于函数调用子系统块,将块输入端口连接到断言函数调用信号的根Inport块。子系统根据它接收到的函数调用信号来执行。Si金宝appmulink函数块的执行是为了响应相应的函数调用者块或状态流图的执行。Initialize Function块在模型初始化事件上执行,Reset Function块在用户定义的重置事件上执行。

对于导出函数,建模rtwdemo_functions包含两个函数调用子系统(f1_algf2_alg)和Simuli金宝appnk函数块(f3),以输出功能。该模型还包含一个Initialize Function块(初始化函数)和Reset Function块(重置功能)。为了在模型的其他部分计算具有状态的块的初始条件,在Initialize Function和Reset Function块中使用了state Writer块。

open_system (“rtwdemo_functions”

创建包含函数调用者块的模型

使用函数调用块来调用Simulink函数块。金宝app函数调用者块可以在与Simulink函数块相同的模型中,也可以在不同的模型中。金宝app

多个函数调用块可以调用一个Simulink函数块。金宝app您可以将Function Caller块放置在函数调用子系统中。在代码生成期间,代码生成器从函数调用子系统导出一个函数。

该模型rtwdemo_caller导出一个包含函数调用者块的函数调用子系统。

open_system (“rtwdemo_caller”

为仿真创建测试线束模型

导出函数时,生成的代码不包括调度器。创建一个测试工具模型来处理仿真期间的调度。不要使用测试工具模型来生成您要部署的代码。

模型rtwdemo_export_functions是一个测试线束。模型:

  • 在函数调用者块中调度Simu金宝applink函数块rtwdemo_caller

  • 为本例中的其他模型提供函数调用信号,以调度模型内容,包括模型初始化和重置事件。

open_system (“rtwdemo_export_functions”

模拟测试线束模型

通过模拟测试工具模型,验证包含您想要导出的功能的模型是否如您所期望的那样被执行。例如,模拟rtwdemo_export_functions

sim卡(“rtwdemo_export_functions”

生成函数代码

打开嵌入式编码器然后,为要导出的函数生成代码。例如,为rtwdemo_functions

rtwbuild (“rtwdemo_functions”
启动rtwdemo_functions的代码生成过程成功完成:rtwdemo_functions的代码生成摘要:构建了顶级模型目标:模型动作重建原因===================================================================================== rtwdemo_functions生成的代码生成信息文件不存在。构建1个模型中的1个(0个已经更新的模型)构建持续时间:0小时0分钟17.53秒

审查生成的代码

检查生成的代码。

  • ert_main.c是模型的示例主程序(执行框架)。这段代码展示了如何调用导出的函数。该代码还显示了如何初始化和执行生成的代码。

  • rtwdemo_functions.c调用初始化函数,包括初始化函数,并为模型组件导出函数f1_algf2_alg,f3

  • rtwdemo_functions.h声明模型数据结构和导出的入口点函数和数据结构的公共接口。

  • f3.h是一个共享文件,声明调用接口的Simulink函数金宝appf3

  • rtwtypes.h定义生成的代码所需的数据类型、结构和宏。

编写接口代码

打开并检查代码接口报告。要为执行框架编写接口代码,请使用该报告中的信息。

  1. 通过添加指令来包含生成的头文件# include rtwdemo_functions.h# include f3.h,# include rtwtypes.h

  2. 将输入数据写入模型导入块生成的代码中。

  3. 调用生成的入口点函数。

  4. 从模型Outport块生成的代码中读取数据。

输入端口:

  • rtU。U1类型的real_T维度为1

  • rtU。U2类型的real_T维度为1

入口点函数:

  • 初始化入口点函数,空白rtwdemo_functions_initialize(空白)。在启动时,调用这个函数一次。

  • 复位入口点功能;空白rtwdemo_functions_reset(空白)。根据需要调用这个函数。

  • 导出的函数,无效的f1(空白)。根据需要调用这个函数。

  • 导出的函数,空白f2(空白)。根据需要调用这个函数。

  • 金宝app仿真软件的功能,无效f3(real_T rtu_u, real_T*rty_y)。根据需要调用这个函数。

输出端口:

  • 而无。Accumulator1类型的int8_T维度为[2]

  • 而无。Accumulator2类型的int8_T维度为[2]

  • 而无。TicToc10类型的int8_T维度为1

更多关于

接近示例模型

bdclose (“rtwdemo_export_functions”) bdclose (“rtwdemo_functions”) bdclose (“rtwdemo_caller”

为导出函数模型生成c++函数和类代码

这个例子展示了如何为包含函数调用子系统的导出-函数模型生成函数代码。代码生成器生成不包括调度代码的函数和类代码。

生成用于导出的函数代码:

  1. 创建一个包含导出功能的模型。

  2. 创建一个测试工具模型,在模拟期间安排功能的执行。

  3. 通过使用测试工具模型模拟包含功能的模型。

  4. 为包含函数的模型生成代码。

创建包含函数和c++类接口的模型用于导出

具有用于用c++模型类接口导出的函数的模型必须满足模型根级的体系结构约束。对于c++类生成,在根级别有效的块是:

  • 轮廓尺寸

  • 外港

  • 函数调用子系统

  • 转到

  • 合并

注意:带有c++类接口的导出函数调用子系统不支持Simulink函数块。金宝app金宝app

代码生成器为函数调用子系统块生成函数代码。对于函数调用子系统块,将块输入端口连接到断言函数调用信号的根Inport块。子系统根据它接收到的函数调用信号来执行。

模型rtwdemo_cppclass_functions包含函数调用子系统f1f2,f3用于导出函数。

open_system (“rtwdemo_cppclass_functions”

为仿真创建测试线束模型

导出函数时,生成的代码不包括调度器。创建一个测试工具模型来处理仿真期间的调度。不要使用测试工具模型来生成您要部署的代码。

模型rtwdemo_cppclass_export_functions是一个测试线束。在本例中,模型向其他模型提供函数调用信号,以调度模型内容。

open_system (“rtwdemo_cppclass_export_functions”

模拟测试线束模型

通过模拟测试工具模型,验证包含您想要导出的功能的模型是否如您所期望的那样被执行。例如,模拟rtwdemo_cppclass_export_functions

sim卡(“rtwdemo_cppclass_export_functions”

生成功能代码和报告

为要导出的函数生成代码和代码生成报告。例如,为rtwdemo_cppclass_functions

rtwbuild (“rtwdemo_cppclass_functions”
###启动rtwdemo_cppclass_functions的构建过程###成功完成:rtwdemo_cppclass_functions的构建过程构建摘要构建了顶级模型目标:模型动作重建原因=========================================================================================================== rtwdemo_cppclass_functions生成和编译的代码生成信息文件不存在。构建1个模型中的1个(0个已经更新的模型)构建持续时间:0小时0分钟27.849秒

审查生成的代码

从代码生成报告中,检查生成的代码。

  • ert_main.cpp是模型的示例主程序(执行框架)。这段代码展示了如何调用导出的函数。该代码还显示了如何初始化和执行生成的代码。

  • rtwdemo_cppclass_functions.cpp调用初始化函数,包括初始化函数,导出模型子系统组件的功能f1f2,f3

  • rtwdemo_cppclass_functions.h声明模型数据结构和导出的入口点函数和数据结构的公共接口。

  • rtwtypes.h定义生成的代码所需的数据类型、结构和宏。

编写接口代码

打开并检查代码接口报告。要为执行框架编写接口代码,请使用该报告中的信息。

  1. 通过添加指令来包含生成的头文件# include rtwdemo_cppclass_functions.h# include rtwtypes.h

  2. 将输入数据写入模型导入块生成的代码中。

  3. 调用生成的入口点函数。

  4. 从模型Outport块生成的代码中读取数据。

输入端口:

  • rtU。U1类型的real_T维度为1

  • rtU。U2类型的real_T维度为1

  • rtU。U3类型的real_T维度为1

入口点函数:

  • 初始化入口点函数,无效的初始化(空白)。在启动时,调用这个函数一次。

  • 导出的函数,空白t_1tic_A(空白)。根据需要调用这个函数。

  • 导出的函数,空白t_1tic_B(空白)。根据需要调用这个函数。

  • 导出的函数,空白t_1tic_C(空白)。根据需要调用这个函数。

输出端口:

  • 而无。TicToc1类型的int8_T维度为[2]

  • 而无。TicToc2类型的int8_T维度为[2]

  • 而无。TicToc10类型的int8_T维度为1

更多关于

接近示例模型

bdclose (“rtwdemo_cppclass_export_functions”) bdclose (“rtwdemo_cppclass_functions”

为导出功能子系统生成代码

为导出函数子系统生成代码:

  1. 验证为其生成代码的子系统是否满足导出需求

  2. 在“配置参数”对话框中:

    1. 设置参数系统目标文件到基于ert的系统目标文件,例如ert.tlc

    2. 如果您想要一个带有生成代码的SIL块,为了验证的目的,设置模型配置参数创建块

    3. 点击好吧应用

  3. 右键单击子系统块并选择C/ c++代码>导出函数从上下文菜单中。

    该操作创建了一个新模型,子系统.slx,它包含原始子系统的内容,并创建一个ScratchModel它包含一个模型块。这个块引用新创建的子系统.slx模型。

    构建子系统代码:子系统对话框。这个对话框不是特定于导出功能子系统的。生成代码不需要在对话框中输入信息。

  4. 点击构建建立新创建的子系统.slx模型。

    代码生成器生成代码并将其放在工作文件夹中。

    如果你设置创建块在步骤2b中,Simul金宝appink打开一个新窗口,其中包含一个表示生成代码的s函数块。该块具有与原始子系统相同的大小、形状和连接器。

代码生成和可选块创建现在已经完成。您可以像测试生成的ERT代码和s函数块一样测试和使用代码和可选块。有关可选的工作流任务,请参见指定自定义初始化函数名指定自定义描述

指定自定义初始化函数名

方法的参数为导出函数的初始化函数指定自定义名称rtwbuild命令。该命令采用以下形式:

blockHandle= rtwbuild ('子系统', 'Mode', 'ExportFunctionCalls',…“ExportFunctionInitializeFunctionName”、“fcnname”)

fcnname函数名。例如,如果您指定名称“myinitfcn”,构建过程发出类似于以下代码:

/*模型初始化函数*/无效myinitfcn(无效){…}

指定自定义描述

您可以在import块的“块属性”对话框中输入导出函数的自定义描述。

  1. 右键单击驱动要为其导出代码的子系统的控制端口的import块。

  2. 选择属性

  3. 一般选项卡,在描述字段,输入描述性文本。

在函数导出期间,您输入的文本将被发送到import块头中生成的代码中。例如,如果您打开示例程序rtwdemo_exporting_functions并在“Block Properties”对话框中输入port的描述信息t_1tic_A,代码生成器生成的代码类似于:

/* *导出函数的输出和更新:t_1tic_A * *导出函数的自定义描述*/ void t_1tic_A(void){…}

优化导出功能子系统生成的代码

要优化为导出函数子系统生成的代码,请为跨越子系统边界的每个输入信号和输出信号指定一个单独的存储类。

对于导出的每个函数调用子系统:

  1. 右键单击子系统。

  2. 从上下文菜单中选择块参数(子系统)

  3. 选择代码生成选项卡。

  4. 函数包装汽车

  5. 点击好吧应用

相关的话题