文档

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

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

建模选项

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

  • 导出函数模型(模型包含功能块,仅由函数调用子系统、函数调用模型块或其他导出函数模型组成,如中所述)导出功能模型(万博1manbetx模型)

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

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

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

  • 封装被触发的子系统,您打算从中导出顶级虚拟子系统中的函数。

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

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

需求

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

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

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

    • 函数调用块(如函数调用子系统,Simulink函数,s -函数和函数调用模型块,如果求解器参数万博1manbetx任务和采样时间选项>周期采样时间约束设置为确保采样时间独立

    • 导入和输出块(端口)

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

    • 块的采样时间为Inf

    • 合并和数据存储内存块

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

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

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

  • 模型或子系统中的块必须支持代码生成。万博1manbetx

  • 使用绝对时间或流逝时间的块必须位于周期函数调用子系统内,并在相应的函数调用根级导入块上指定离散采样时间。看到导出使用绝对时间或运行时间的函数

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

此外,对于导出函数模型,数据日志记录和信号查看器块(例如Scope块)不允许在根级别或函数调用块中。

对于export-function子系统,需要满足以下附加要求:

  • 穿过导出函数子系统边界的触发信号必须是标量。不充当触发器的输入和输出数据信号不必是标量。

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

导出使用绝对时间或运行时间的函数

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

  • 配置为定期执行

  • 您可以用一个离散的采样时间来配置根级别的import块

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

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

  2. 采样时间类型字段中,指定周期

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

  4. 点击好吧应用

有关更多信息,请参见绝对时间和消耗时间计算(万博1manbetx仿真软件编码器)。

导出功能子系统的限制

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

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

  • 代码生成器不能为导出功能子系统导出可重用代码。的代码接口打包价值可重用的功能不适用于导出功能子系统。

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

  • 只有当它的函数调用启动器在加速模式下是万博1manbetx非内联的,代码生成器才支持SIL或PIL块在加速模式下。非内联启动器的例子包括statflow®图表。

  • Level-2 S-function启动器块,例如statflow chart或内置的Function-Call Generator块,必须驱动SIL块。

  • 您可以导出异步(采样时间)函数调用系统,但是软件不支持异步系统的SIL或PIL块。万博1manbetx

  • 该软件不支持导出功能子系统的mat文件日志记万博1manbetx录。忽略启用mat文件日志记录的规范。

  • TLC功能的使用LibIsFirstInit已为导出功能子系统删除。

工作流

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

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

选择集成方法

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

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

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

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

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

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

万博1manbetxSimulink功能块
代码响应初始化事件 函数块
代码响应重置事件 功能块
代码包含的入口点函数超出了代码生成器默认生成的函数(模型_initialize模型_step,模型_terminate 功能 手写S-Function和TLC文件
使用单一模型执行框架作为测试工具,并导出为模型的部分生成的代码 导出功能子系统

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

这个例子展示了如何在不生成调度代码的情况下,为模型中的各个Simulink函数块和函数调用子系统生成函数代码。万博1manbetx

使用实例生成导出函数代码:

  1. 创建一个包含导出函数的模型。

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

  3. 通过使用测试集束模型来模拟包含功能的模型。

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

创建包含导出函数的模型

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

  • 轮廓尺寸

  • 外港

  • 函数调用子系统

  • 万博1manbetx仿真软件的功能

  • 转到

  • 合并

代码生成器为函数调用子系统和Simulink函数块以及初始化和重置函数块生成函数代码。万博1manbetx对于函数调用子系统块,您将块输入端口连接到断言函数调用信号的根输入块。子系统根据它接收到的函数调用信号执行。Si万博1manbetxmulink函数块的执行响应于相应的函数调用方块或状态流程图的执行。初始化函数块在模型初始化事件上执行,重置函数块在用户定义的重置事件上执行。

对于导出函数,请使用modelrtwdemo_functions包含两个函数调用子系统(f1_alg而且f2_alg)和Simuli万博1manbetxnk函数块(f3)用于导出函数。该模型还包含一个初始化函数块(初始化函数)和复位功能块(重置功能).为了在模型的其他部分计算具有状态的块的初始条件,在Initialize和Reset Function块中使用state Writer块。

open_system (“rtwdemo_functions”

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

使用函数调用方块调用Simulink函数块。万博1manbetx函数调用者块可以与Simulink函数块处于相同的模型中,也可以处于不同的模型中。万博1manbetx

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

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

open_system (“rtwdemo_caller”

为仿真创建测试线束模型

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

模型rtwdemo_export_functions是一个测试装备。模型:

  • 使用函数调用者块调度Simu万博1manbetxlink函数块rtwdemo_caller

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

open_system (“rtwdemo_export_functions”

模拟测试束模型

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

sim卡(“rtwdemo_export_functions”

生成功能代码和报告

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

rtwbuild (“rtwdemo_functions”
###开始模型的构建过程:rtwdemo_functions成功完成模型的代码生成:rtwdemo_functions

检查生成的代码

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

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

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

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

  • f3.h是声明Simulink函数调用接口的共享文件吗万博1manbetxf3

  • 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(空白).根据需要调用此函数。

  • 万博1manbetx仿真软件的功能,void 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函数块。万博1manbetx万博1manbetx

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

模型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

检查生成的代码

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

  • 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它包含一个Model块。这个块引用新创建的子系统.slx模型。

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

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

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

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

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

指定自定义初始化函数名

属性的参数,可以为导出函数的初始化函数指定自定义名称rtwbuild命令。命令格式如下:

blockHandle= rtwbuild ('子系统', '模式','ExportFunctionCalls',..“ExportFunctionInitializeFunctionName”、“fcnname')

fcnname函数名。例如,如果您指定了名称“myinitfcn”时,构建过程会发出类似于:

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

指定自定义描述

您可以使用导入块的“块属性”对话框,为导出函数输入自定义描述。

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

  2. 选择属性

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

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

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

优化导出函数子系统生成的代码

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

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

  1. 右键单击子系统。

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

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

  4. 函数包装汽车

  5. 点击好吧应用

相关的话题

这个话题有用吗?