主要内容

从Simulink函数块生成可重入代码金宝app

如果你使用嵌入式编码器®,通过将算法表示为有作用域的Simulink函数块,可以生成可重用的、可重入的代码。金宝app何时从Simulink函数块生成可重入代码的示例是,当一个函数在模型中的函数调用者之间或客户机/服金宝app务器应用程序中共享状态时。通过在导出函数模型中使用共享Simulink Function块的多个实例,可以生成高度模块化的代码。金宝app代码生成器生成函数代码,并将对函数的每次使用或调用与特定于实例的数据关联起来。功能的范围取决于您是将功能放在模型的根级别还是子系统中。

代码生成器生成可重入函数代码,当你配置:

调用由作用域Simulink function块表示的函数,从函数定义级别的上一金宝app级、同一级别或从函数定义级别下一级调用。您可以将函数作用域限定在原子子系统或非虚拟子系统中,但是函数调用可访问性被限制在层次结构的同一级别或更低级别。函数名不必是唯一的。

确定需求

在设计模型之前和设计模型时,请考虑:

  • 每个函数需要多少个实例?

  • 是否需要将函数的调用点限制在包含函数定义的模型中?

  • 您是否需要一个函数与本地环境中的信号进行接口,但对调用者隐藏这些信号?

  • 函数之间需要直接通信吗?

  • 函数需要连接到外部I/O吗?

  • 你需要记录函数输出吗?

创建模型

使用示例模型组件rtwdemo_comp了解如何使用Simulink函数块生金宝app成可重入的C代码。使用范例模型rtwdemo_comp_cpp如果你更喜欢生成c++代码。打开模型并检查模型层次结构。

模型的顶层包括一个函数调用子系统和一个引用模型的两个实例。

参考模型,rtwdemo_func_dinteg,由定义函数的Simulink 金宝appFunction块组成multiinstfunc和子系统subsys_calc

子系统由Simulink函数块组成。金宝app这个Simulink Fun金宝appction块的使用说明了如何将该块定义的函数的范围限制到包含子系统的模型。代码生成器生成的函数代码func_calc并将对函数的每次调用与特定于实例的数据关联起来。数据包括状态,比如存储在内存中的数据。

定义函数金宝app的Simulink函数块multiinstfunc使用函数调用程序块来调用函数func_calc.该Simu金宝applink Function块还表明它可以通过import和Outport块连接到块的本地环境中的信号。

在模型的顶层rtwdemo_comp,函数调用子系统使用函数调用者块调用函数的两个实例multiinstfunc.代码生成器生成函数代码,并将每个调用与特定于实例的数据关联起来。

配置模型和模型元素

配置Simulink金宝app功能块

通过配置“触发器端口”功能块金宝app的参数,配置Simulink功能块。代码生成器从Simulink函数块生成可重入代码:金宝app

  • 配置具有相同函数名的块实例。

  • 设置块参数功能可见性作用域

在本例中,引用模型的两个实例中的Simulink function块的函数名金宝apprtwdemo_func_dinteg指定为multiinstfunc

配置函数调用块

配置Function Caller块。对于每个块,设置块参数函数原型.开始输入原型。例如,键入y.基于模型中的函数定义的原型选项出现在选择列表中。选择对应于每个函数调用的原型。

对于本例,原型的配置如下:

  • 在函数调用子系统中,函数调用者的原型被配置为y = Instance1.multiinstfunc(u)而且y = Instance2.multiinstfunc(u).的实例n前缀唯一地标识每个函数调用,并将调用与其自己的数据集关联起来。

  • 函数中的函数调用者multiinstfunc是否配置了原型Y = subsys_calc.func_calc(u).前缀subsys_calc标识包含函数定义的子系统。

对于本例,输入和输出参数规范和采样时间保留默认设置。

子系统配置

示例模型中的子系统不需要配置更改。当您在子系统中包含Simulink F金宝appunction块时,代码生成器

  • 将函数限定在包含子系统的模型中。

  • 将子系统视为一个原子单元。

配置参考模型

配置包含Simulink Function块的引用模型:金宝app

  • 在“块参数”对话框中,设置参数模型名称到引用的模型文件名。对于本例,模型名称为rtwdemo_func_dinteg.slx

  • 设定模型配置参数每个顶级模型允许的实例总数多个

  • 要为参考模型生成c++类接口,请设置模型配置参数语言c++和参数代码接口打包c++类

可选地,您可以自定义模型入口点函数接口。您可以指定入口点函数名。对于执行(步骤)入口点函数,可以配置函数名和参数。自定义入口点函数接口可以最大限度地减少对与生成代码集成的现有外部代码的更改。本例使用缺省函数接口。看到为Simulink函数和函数调用方块配置入口点函数接口金宝app(嵌入式编码)

配置Top Model

配置模型组件的顶层模型。如果您希望模型组件(即顶层模型)可重用,请设置模型配置参数代码接口打包可重用的功能.如果生成c++代码,可以将此参数设置为c++类.在任何一种情况下,也:

  • 设定模型配置参数多实例代码错误诊断错误

  • 设定模型配置参数传递根级I/O为部分模型数据结构

可选地,您可以自定义模型入口点函数接口。您可以指定入口点函数名。对于执行(步骤)入口点函数,可以配置函数名和参数。自定义入口点函数接口可以最大限度地减少对与生成代码集成的现有外部代码的更改。本例使用缺省函数接口。看到为Simulink函数和函数调用方块配置入口点函数接口金宝app(嵌入式编码)

生成和检查C代码

为模型生成C代码。

  • 多实例Simulink函数块的函数代码金宝app

    在引用模型中放置具有作用域的Simulink F金宝appunction块(该引用模型在另一个模型中多次使用)时,代码生成器将函数代码放在模型.c文件中引用的模型。对于本例,代码生成器放置的函数代码为multiinstfuncslprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg.c

    real_T rtwdemo_func_dinteg_multiinstfunc(RT_MODEL_rtwdemo_func_dinteg_T * const rtwdemo_func_dinteg_M, const real_T rtu_u) {real_T rtb_TmpLatchAtInOutport1;real_T rtb_TmpLatchAtIn2Outport1;real_T rty_y_0;rtb_TmpLatchAtInOutport1 = *rtwdemo_func_dinteg_M->rtwdemo_func_dintegrtextInport.rtu_In1;rtb_TmpLatchAtIn2Outport1 = *rtwdemo_func_dinteg_M->rtwdemo_func_dintegrtextInport.rtu_In2;* rtwdemo_func_dinteg_M - > rtwdemo_func_dintegrtextOutport。rty_Out2 = 2.0 * rtb_TmpLatchAtInOutport1;rtwdemo_func_dinteg_func_calc(rtwdemo_func_dinteg_M, rtb_TmpLatchAtIn2Outport1, rtwdemo_func_dinteg_M->rtwdemo_func_dintegrtextOutport.rty_Out1);rty_y_0 = rtwdemo_func_dinteg_M->dwork.DiscreteIntegrator_DSTATE;rtwdemo_func_dinteg_M - > dwork。离散积分状态+= 0.1 * rtu_u; return rty_y_0; }
  • 在子系统中定义的Simulink函数块的金宝app函数代码

    代码生成器将您在子系统中定义的Simulink function块的函数代码放在金宝app模型.c包含子系统的模型的文件。对于本例,代码生成器放置的函数代码为func_calcslprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg.c

    void rtwdemo_func_dinteg_func_calc(RT_MODEL_rtwdemo_func_dinteg_T * const rtwdemo_func_dinteg_M, real_T rtu_u, real_T *rty_y) {rtwdemo_func_dinteg_M->dwork。calcMem = rtwdemo_func_dinteg_M->dwork.UnitDelay_DSTATE;*rty_y = rtwdemo_func_dinteg_M->dwork.UnitDelay_DSTATE;rtwdemo_func_dinteg_M - > dwork。UnitDelay_DSTATE = rtu_u * 0.07;}
  • 结构,为可重用函数存储多实例数据

    代码生成器使用与实时模型类似的结构(RT_MODEL)数据结构,以存储与可重用函数相关的多实例数据。中的代码生成器定义结构slprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg.h

    typedef struct rtwdemo_func_dinteg_tag_RTM RT_MODEL_rtwdemo_func_dinteg_T;
  • 多实例引用模型的初始化代码

    对于包含相同作用域的Simulink Function块的引用模型的每个实例,代码生成器生成初始化和启动函数代码。金宝app中定义的初始化代码的单个副本slprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg.c

    void rtwdemo_func_dinteg_Start(RT_MODEL_rtwdemo_func_dinteg_T *const rtwdemo_func_dinteg_M, const real_T *rtu_In1, const real_T *rtu_In2, real_T *rty_Out2, real_T *rty_Out1) {rtwdemo_func_dinteg_M->rtwdemo_func_dintegrtextInport。rtu_In1 = rtu_In1;rtwdemo_func_dinteg_M - > rtwdemo_func_dintegrtextInport。rtu_In2 = rtu_In2;rtwdemo_func_dinteg_M - > rtwdemo_func_dintegrtextOutport。rty_Out2 = rty_Out2;rtwdemo_func_dinteg_M - > rtwdemo_func_dintegrtextOutport。rty_Out1 = rty_Out1;} void rtwdemo_func_dinteg_initialize(const char_T **rt_errorStatus, RT_MODEL_rtwdemo_func_dinteg_T *const rtwdemo_func_dinteg_M) {{rtmSetErrorStatusPointer(rtwdemo_func_dinteg_M, rt_errorStatus);}}

    初始化代码是为包含相同Simulink Function块的引用模型的每个实例调用的。金宝app那个代码在文件中rtwdemo_comp.c在build文件夹中。

    ……rtwdemo_func_dinteg_initialize (rtmGetErrorStatusPointer (rtwdemo_comp_M) (& (rtwdemo_comp_M - > Instance1)));rtwdemo_func_dinteg_initialize (rtmGetErrorStatusPointer (rtwdemo_comp_M) (& (rtwdemo_comp_M - > Instance2)));rtwdemo_func_dinteg_Start((&(rtwdemo_comp_M->Instance1)), & rtu ->In2, & rtu ->In3, & rty ->Out2, & rty ->Out3);rtwdemo_func_dinteg_Start((&(rtwdemo_comp_M->Instance2)), & rtu ->In4, & rtu ->In5, & rty ->Out4, & rty ->Out5);}
  • 顶层模型入口点函数声明

    模型头文件rtwdemo_comp.h包括走读生顶级模型初始化、终止和执行(运行)入口点函数的声明。

    rtwdemo_comp_初始化(RT_MODEL_rtwdemo_comp_T *const rtwdemo_comp_M);(RT_MODEL_rtwdemo_comp_T *const rtwdemo_comp_M);
  • 引用模型入口点函数声明

    头文件slprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg.h包括走读生引用模型入口点函数的声明。

    extern void rtwdemo_func_dinteg_initialize(const char_T **rt_errorStatus, RT_MODEL_rtwdemo_func_dinteg_T *const rtwdemo_func_dinteg_M);extern real_T rtwdemo_func_dinteg_multiinstfunc(RT_MODEL_rtwdemo_func_dinteg_T * const rtwdemo_func_dinteg_M, const real_T rtu_u);extern void rtwdemo_func_dinteg_Start(RT_MODEL_rtwdemo_func_dinteg_T *const rtwdemo_func_dinteg_M, const real_T *rtu_In1, const real_T *rtu_In2, real_T *rty_Out2, real_T *rty_Out1);

生成和检查c++代码

为模型生成c++代码。

  • 多实例Simulink函数块的函数代码金宝app

    在引用模型中放置具有作用域的Simulink F金宝appunction块(该引用模型在另一个模型中多次使用)时,代码生成器将函数代码放在模型. cpp文件中引用的模型。对于本例,代码生成器放置的函数代码为multiinstfuncslprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg_cpp.cpp

    real_T rtwdemo_func_dintegModelClass::multiinstfunc(const real_T rtu_u) {real_T rtb_TmpLatchAtInOutport1;real_T rtb_TmpLatchAtIn2Outport1;real_T rty_y_0;rtb_TmpLatchAtInOutport1 = *rtwdemo_func_dinteg_cprtrtu_In1;rtb_TmpLatchAtIn2Outport1 = *rtwdemo_func_dinteg_cprtrtu_In2;*rtwdemo_func_dinteg_crtrty_Out2 = 2.0 * rtb_TmpLatchAtInOutport1;rtwdemo_func_dinteg_c_func_calc (rtb_TmpLatchAtIn2Outport1 rtwdemo_func_dinteg_crtrty_Out1);rty_y_0 = rtwdemo_func_dinteg_cpprtDW.DiscreteIntegrator_DSTATE;rtwdemo_func_dinteg_cpprtDW。离散积分状态+= 0.1 * rtu_u; return rty_y_0; }
  • 在子系统中定义的Simulink函数块的金宝app函数代码

    代码生成器将您在子系统中定义的Simulink function块的函数代码放在金宝app模型. cpp对于包含子系统的模型。对于本例,代码生成器放置的函数代码为func_calcslprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg_cpp.cpp

    void rtwdemo_func_dintegModelClass::rtwdemo_func_dinteg_c_func_calc(real_T rtu_u, real_T *rty_y) {rtwdemo_func_dinteg_cpprtDW。calcMem = rtwdemo_func_dinteg_cpprtDW.UnitDelay_DSTATE;*rty_y = rtwdemo_func_dinteg_cpprtDW.UnitDelay_DSTATE;rtwdemo_func_dinteg_cpprtDW。UnitDelay_DSTATE = rtu_u * 0.07;}
  • 结构,为可重用函数存储多实例数据

    代码生成器使用与实时模型类似的结构(RT_MODEL)数据结构,以存储与可重用的功能.中的代码生成器定义结构slprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg_cpp.h

    typedef结构rtwdemo_func_dinteg_cpp_tag_RTM rtwdemo_func_dinteg_cp_RT_MODEL;
  • 多实例引用模型的初始化代码

    对于包含相同作用域的Simulink Function块的引用模型的每个实例,代码生成器生成初始化和启动函数代码。金宝app中定义的初始化代码的单个副本slprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg_cpp.cpp

    void rtwdemo_func_dintegModelClass::start(real_T *rtu_In1, real_T *rtu_In2, real_T *rty_Out2, real_T *rty_Out1) {rtwdemo_func_dinteg_cprtrtu_In1 = rtu_In1;rtwdemo_func_dinteg_cprtrtu_In2 = rtu_In2;rtwdemo_func_dinteg_crtrty_Out2 = rty_Out2;rtwdemo_func_dinteg_crtrty_Out1 = rty_Out1;}……void rtwdemo_func_dintegModelClass::initializeRTM() {(void) memset((void *)((&rtwdemo_func_dinteg_cpprtM)), 0, sizeof(rtwdemo_func_dinteg_cp_RT_MODEL));}

    初始化代码是为包含相同Simulink Function块的引用模型的每个实例调用的。金宝app那个代码在文件中rtwdemo_comp_cpp.cpp在build文件夹中。

    ……Instance1MDLOBJ0.initializeRTM ();Instance1MDLOBJ0.setErrorStatusPointer (rtmGetErrorStatusPointer ((rtm)));Instance1MDLOBJ0.initialize ();Instance2MDLOBJ1.initializeRTM ();Instance2MDLOBJ1.setErrorStatusPointer (rtmGetErrorStatusPointer ((rtm)));Instance1MDLOBJ0.start (rtu。In2 rtu。In3,而无。Out2 &rtY.Out3);Instance2MDLOBJ1.start (&rtwU。In4 &rtwU。把鱼,而无。Out4 &rtY.Out5); }
  • 顶级模型类声明

    模型头文件rtwdemo_comp_cpp.h包括顶层模型的类声明。

    类rtwdemo_compModelClass{公共:ExtU rtU;ExtY而无;无效的初始化();空运行();rtwdemo_compModelClass ();~ rtwdemo_compModelClass ();RT_MODEL * getRTM();private: RT_MODEL rtM;rtwdemo_func_dintegModelClass Instance1MDLOBJ0;rtwdemo_func_dintegModelClass Instance2MDLOBJ1; };
  • 引用模型类声明

    头文件slprj / ert / rtwdemo_func_dinteg / rtwdemo_func_dinteg_cpp.h包括引用模型的类声明。

    类rtwdemo_func_dintegModelClass{公共:real_T multiinstfunc(const real_T rtu_u);void start(real_T *rtu_In1, real_T *rtu_In2, real_T *rty_Out2, real_T *rty_Out1);rtwdemo_func_dintegModelClass ();~ rtwdemo_func_dintegModelClass ();rtwdemo_func_dinteg_cp_RT_MODEL * getRTM();空白initializeRTM ();void setErrorStatusPointer(char_T **rt_errorStatus);private: rtwdemo_func_dinteg_cpp_DW rtwdemo_func_dinteg_cpprtDW;const real_T *rtwdemo_func_dinteg_cprtrtu_In1;const real_T *rtwdemo_func_dinteg_cprtrtu_In2; real_T *rtwdemo_func_dinteg_crtrty_Out2; real_T *rtwdemo_func_dinteg_crtrty_Out1; rtwdemo_func_dinteg_cp_RT_MODEL rtwdemo_func_dinteg_cpprtM; void rtwdemo_func_dinteg_c_func_calc(real_T rtu_u, real_T *rty_y); };

限制

这些代码生成限制适用于包含Simulink Function块的多个实例的导出函数模型。金宝app

  • 您必须设置模型配置参数传递根级I/O为部分模型数据结构

  • 生成的代码只与单线程执行兼容。要避免共享信号数据的竞争条件,请从相同的执行线程调用函数代码的实例。

  • 你不能:

    • 如果导出函数模型包含模型变量,则生成代码。

    • 从状态流调用生成的代码®图表。

    • 开启外部模式数据交换接口。

相关的话题