这个示例展示了如何从控制算法模型生成C代码,并将该代码与现有的外部应用程序代码集成。在完整的应用程序中,由三个模块组成,算法模块必须通过全局变量与其他模块交换数据。在本例中,您将生成的代码配置为与现有的外部变量交互,在外观和组织上类似于外部代码,并符合特定的编码需求。
将当前文件夹设置为可写位置。
复制脚本prepare_ext_code
到当前文件夹并运行脚本。脚本将外部代码文件复制到几个文件夹中。
尝试拷贝文件(fullfile (matlabroot,“例子”,“ecoder”,“主要的”,“prepare_ext_code.m”),...“prepare_ext_code.m”,“f”);抓结束运行(“prepare_ext_code.m”);
在当前文件夹中打开ext_code_main.c
.这段应用程序代码描述了一个具有简单调度算法的嵌入式系统虽然
循环)和三个模块,它们的算法在每个执行周期中运行:ex_ext_inputs_proc
,ex_ext_ctrl_alg
和ex_ext_outputs_proc
.
类型(“ext_code_main.c”)
在共享
文件夹,检查ex_ext_projTypes.h
。该文件定义了两种自定义数据类型(类型定义
)模块中的数据所使用的。
类型(fullfile (“共享”,“ex_ext_projTypes.h”))
在io_驱动程序
文件夹,检查ex_sensor_accessors.c
.这个文件定义了函数,get_fromSensor_flow
和get_fromSensor_temp
,返回由流量传感器和温度传感器记录的原始数据。对于本例,函数为控制算法返回平凡的正弦刺激。
类型(fullfile (“io_drivers”,“ex_sensor_accessors.c”))
在ex_ext_inputs_proc
文件夹,检查ex_ext_inputs_proc.c
.的ex_ext_inputs_proc
模块读取传感器数据(通过调用访问器函数),过滤数据,并将其存储在两个全局变量中,PROC_INPUT_FLOW
和PROC_INPUT_TEMP
。这些全局变量在文件中定义ex_ext_proc_inputs.c
并宣布在ex_ext_proc_inputs.h
.
类型(fullfile (“ex_ext_inputs_proc”,“ex_ext_inputs_proc.c”))
这个模块中的过滤算法和其他两个模块中的算法需要状态数据,这些数据必须在应用程序的执行周期之间保持。每个模块将相关的状态数据存储为全局变量。例如,在ex_ext_inputs_proc
模块,ex_ext_inputs_proc.c
定义了这些变量:
flowFilterIn_state_data
tempFilterIn_state_data
flowFilterIn\u tmp\u数据
tempFilterIn_tmp_data
空的ex_ext_ctrl_alg
文件夹是生成代码的占位符。这个ex_ext_ctrl_alg
模块必须对过滤流量和温度测量进行PID控制。稍后,您将检查此代码的需求,这些需求基于其他模块中的代码。
在ex_ext_outputs_proc
文件夹,检查ex_ext_outputs_proc.c
。此模块从名为的全局变量读取PID输出信号CONTR_SIG_FLOW
和控制信号温度
.的ex_ext_ctrl_alg
模块(生成的代码)必须定义这些变量ex_ext_outputs_proc
然后,模块对这些信号进行过滤,并将过滤后的值传递给代表执行器设备驱动程序的函数(例如,阀门和加热器灯丝)。
类型(fullfile (“ex_ext_outputs_proc”,“ex_ext_outputs_proc.c”))
中定义了执行器函数io_驱动程序
文件中的文件夹ex_执行器_访问器
.
图中显示了预期的流经系统的数据流。该图还显示了定义和声明跨模块边界的数据(全局变量)的代码文件。
打开示例模型ex_ext_ctrl_alg
.
open_system (“ex_ext_ctrl_alg”)
模型中的模块实现所需的PID控制算法。模型使用基于ERT的系统目标文件的默认代码生成设置(ert.tlc
).
的功能来完成应用程序ex_ext_ctrl_alg
模块,从该模型生成的代码必须:
使用自定义数据类型dataPath_flow_T
和dataPath_temp_T
从外部文件ex_ext_projTypes.h
.
从全局变量中读取过滤过的传感器数据PROC_INPUT_FLOW
和PROC_INPUT_TEMP
.生成的代码不能定义这些变量,因为模块ex_ext_inputs_proc
定义它们,并在中声明它们ex_ext_proc_inputs.h
.
将PID控制信号写入全局变量CONTR_SIG_FLOW
和控制信号温度
。生成的代码必须定义这些变量,并在名为ex_ext_ctrl_sigs.h
.然后ex_ext_outputs_proc
模块可以从中读取原始控制信号。
遵循控制外部应用程序的变量命名标准。例如,生成的代码必须将状态数据存储在名称以_资料
.此外,对于本例,局部函数变量的名称必须以_本地的
.
遵守管理每个外部文件中代码组织的标准。例如,每个文件都包含由注释分隔的部分,这些部分聚合类似的代码构造,例如类型定义、变量声明和函数定义。
为了使您和其他人能够在执行期间与控制算法交互,对于本例,您还配置生成的代码以定义和声明常量
全局变量命名PARAM_setpoint_flow
和PARAM_setpoint_temp
,表示PID控制器设定值。这些定义必须出现在一个名为ex_ext_ctrl_params.c
声明必须出现在名为ex_ext_ctrl_params.h
.
将当前文件夹设置为共享
文件夹中。
使用函数金宝appSimulink.ImportTexternalTypes
生成金宝appSimulink.AliasType
表示自定义数据类型的对象dataPath_flow_T
和dataPath_temp_T
.
cd (“共享”)S金宝appimulink.ImportTexternalTypes(“ex_ext_projTypes.h”);
对象出现在基本工作区中。
在ex_ext_ctrl_alg
模型,在建模选项卡上,单击模型数据编辑器.
在模型数据编辑器中,用于表示的导入块PROC_INPUT_FLOW
,设置数据类型来dataPath_flow_T
.
用于表示的import块PROC_INPUT_TEMP
,设置数据类型来dataPath_temp_T
.
选择信号选项卡。
在模型中,选择每个Constant块的输出信号。在模型数据编辑器中,设置数据类型来继承:通过反向传播继承
.有了这个设置,每个Constant块从紧靠下游的块(在本例中是Sum块)继承其输出数据类型。
或者,要在命令提示符处配置数据类型,请使用这些命令。
set_param (“ex_ext_ctrl_alg/In1”,“OutDataTypeStr”,“dataPath_flow_T”) set_param (“ex_ext_ctrl_alg / In2”,“OutDataTypeStr”,“dataPath_temp_T”) set_param (“ex_ext_ctrl_alg/Flow Setpt”,“OutDataTypeStr”,...“继承:通过反向传播继承”) set_param (“ex_ext_ctrl_alg/Temp Setpt”,“OutDataTypeStr”,...“继承:通过反向传播继承”)
更新框图。图中显示,由于数据类型的继承和传播,模型中的信号使用自定义数据类型。
配置模型以生成访问和定义正确的全局变量的代码,例如PROC_INPUT_FLOW
和控制信号温度
.
在模型数据编辑器中,选择港口/外港选项卡,并设置改变看法下拉列表到密码
.
选择与两个导入块对应的行。
对于任意一行,集合存储类来ImportFromFile
和头文件来ex_ext_proc_inputs.h
.使用存储类ImportFromFile
,每个import块将作为全局变量出现在生成的代码中。然而,生成的代码并不定义变量,而是包括(# include
)中的变量声明ex_ext_proc_inputs.h
.
对于与输出端口块对应的行,设置:
存储类来ExportToFile
头文件来ex_ext_ctrl_sigs.h
定义文件来ex_ext_ctrl_sigs.c
与ExportToFile
,生成的代码定义了全局变量。
或者,要在命令提示符处配置信号,请使用这些命令。
temp = 金宝appSimulink.Signal;temp.CoderInfo.StorageClass =“习俗”;temp.CoderInfo.CustomStorageClass =“ImportFromFile”;temp.CoderInfo.CustomAttributes.HeaderFile =“ex_ext_proc_inputs.h”;portHandles = get_param (“ex_ext_ctrl_alg/In1”,“portHandles”);outportHandle = portHandles.Outport;set_param (outportHandle“信号对象”portthandles = get_param(“ex_ext_ctrl_alg / In2”,“portHandles”);outportHandle = portHandles.Outport;set_param (outportHandle“信号对象”,copy(temp))temp.CoderInfo.CustomStorageClass=“ExportToFile”;temp.CoderInfo.CustomAttributes.HeaderFile =“ex_ext_ctrl_sigs.h”;temp.CoderInfo.CustomAttributes.DefinitionFile =“ex_ext_ctrl_sigs.c”;设置参数(“ex_ext_ctrl_alg/Out1”,“信号对象”,复制(临时))设置参数(“ex_ext_ctrl_alg/Out2”,“信号对象”,复制(临时))
将存储类应用于块参数,例如恒定值参数,则必须创建参数对象,例如金宝app仿真软件。参数
.您可以使用模型数据编辑器来创建参数对象。
选择参数选项卡并设置改变看法来设计
.
在模型中,选择标记为的常量块流量设定
.
在模型数据编辑器中,设置价值来PARAM_setpoint_flow
.
旁边PARAM_setpoint_flow
,点击动作按钮(有三个垂直的点)并选择创造.
在“创建新数据”对话框中,设置价值来金宝appSimulink.Parameter (3)
.
集位置来模型工作空间
并点击创造.
在PARAM_setpoint_flow
属性对话框,设置存储类来常量
.
集头饰来ex_ext_ctrl_params.h
和DefinitionFile来ex_ext_ctrl_params.c
.
对于另一个常量块,使用模型数据编辑器创建金宝app仿真软件。参数
对象命名PARAM_setpoint_temp
与价值2
.
或者,要在命令提示下配置块,请使用以下命令。
PARAM_setpoint_flow = 金宝appSimulink.Parameter (3);PARAM_setpoint_flow.CoderInfo。StorageClass =“习俗”;PARAM_setpoint_flow.CoderInfo。CustomStorageClass =“常量”;PARAM_setpoint_flow.CoderInfo.CustomAttributes。HeaderFile =“ex_ext_ctrl_params.h”;PARAM_setpoint_flow.CoderInfo.CustomAttributes。DefinitionFile =“ex_ext_ctrl_params.c”;参数设置点温度=复制(参数设置点流量);参数设置点温度值=2;mdlwks=获取参数(“ex_ext_ctrl_alg”,“ModelWorkspace”);assignin (mdlwks“参数设置点流量”复制(PARAM_setpoint_flow)) assignin (mdlwks“PARAM_setpoint_temp”,复制(PARAM_setpoint_temp)) set_param (“ex_ext_ctrl_alg/Flow Setpt”,“价值”,“参数设置点流量”) set_param (“ex_ext_ctrl_alg/Temp Setpt”,“价值”,“PARAM_setpoint_temp”)明确临时PARAM_setpoint_flowPARAM_setpoint_tempmdlwksportHandlesoutportHandle
在外部代码中,不参与模块接口的内部数据(如函数中的状态数据和局部变量)符合命名方案。在模型中,配置生成代码中显示的内部数据,以模拟这些命名方案。
在“模型配置参数”对话框中,检查代码生成>标识符窗格中指定命名方案的值时标识符的格式控制:
$ R
表示模型的名称,ex_ext_ctrl_alg
.
$ N
表示方案应用到的每个模型元素的名称,例如信号、块状态或标准数据结构。
M美元
表示代码生成器为避免名称冲突而插入的名称混乱文本。对于大多数命名规则来说,这个标记是必需的。
集全局变量来R N_data美元美元
.此设置控制全局变量的名称,例如表示状态数据的名称。的命名方案$R$N\u数据\u$M
最接近外部代码中状态变量使用的模式。
集当地的临时变量和局部块输出变量来$N_本地$M
.
或者,要在命令提示符处设置配置参数,请使用这些命令。
set_param (“ex_ext_ctrl_alg”,“CustomSymbolStrGlobalVar”,' R N_data美元美元) set_param (“ex_ext_ctrl_alg”,'自定义SYMBOLSTRTMPVAR',“N_local M美元”) set_param (“ex_ext_ctrl_alg”,“CustomSymbolStrBlkIO”,“N_local M美元”)
配置模型中的状态数据,使其作为单独的全局变量而不是标准DWork结构的字段出现在生成的代码中。启用Code透视图。在应用程序库中,单击嵌入式编码器.
在框图下面代码映射>数据默认值,内部数据行,在存储类列选择ExportedGlobal
.
或者,要配置这个默认存储类,请在命令提示符下使用以下命令:
coder.mapping.create (“ex_ext_ctrl_alg”);coder.mapping.defaults.set (“ex_ext_ctrl_alg”,“InternalData”,...“存储类”,“ExportedGlobal”);
将当前文件夹设置为ex_ext_ctrl_alg
文件夹中。
cd(完整文件(“. .”,“ex_ext_ctrl_alg”))
在命令提示符处,导航到包含内置代码生成模板的文件夹ert_code_template.cgt
.默认情况下,当您使用系统目标文件生成代码时ert.tlc
,此模板控制组织,并在一定程度上控制代码在每个生成文件中的外观。
currentFolder = pwd;cd (fullfile (matlabroot,“工具箱”,“环球套票”,“目标”,“ecoder”))
复制ert_code_template.cgt
将文件保存到剪贴板。
返回到ex_ext_ctrl_alg
文件夹为了避免覆盖剪贴板,您可以使用回来按钮。
cd(当前文件夹)清除currentFolder
将文件粘贴到ex_ext_ctrl_alg
文件夹。将文件重命名为ex_my_code_template.cgt
.
打开该文件并将其内容替换为以下代码。
类型(fullfile (matlabroot“例子”,“ecoder”,“数据”,“ex_my_code_template.cgt”))
这个新模板更符合外部文件的组织。例如,模板将类似的代码构造组织为指定的部分(由注释分隔),并且在模板的顶部只指定关于每个生成文件的最小信息。
在模型中,选择>代码生成>模板.
下代码模板和数据模板,将四个配置参数设置为ex_my_code_template.cgt
.
或者,要复制文件并设置参数,请在命令提示下使用以下命令。
拷贝文件(fullfile (matlabroot,“例子”,“ecoder”,“数据”,“ex_my_code_template.cgt”),...“ex_my_code_template.cgt”,“f”) set_param (“ex_ext_ctrl_alg”,“ERTSrcFileBannerTemplate”,“ex_my_code_template.cgt”) set_param (“ex_ext_ctrl_alg”,“ERTHdrFileBannerTemplate”,“ex_my_code_template.cgt”) set_param (“ex_ext_ctrl_alg”,“ERTDataSrcFileTemplate”,“ex_my_code_template.cgt”) set_param (“ex_ext_ctrl_alg”,“ERTDataHdrFileTemplate”,“ex_my_code_template.cgt”)
因为外部代码已经定义了主要的
函数,选择配置参数>只生成代码和明确的配置参数>生成主程序示例.
set_param (“ex_ext_ctrl_alg”,“GenCodeOnly”,“上”) set_param (“ex_ext_ctrl_alg”,“GenerateSamplerMain”,“关闭”)
从模型生成代码。
rtwbuild (“ex_ext_ctrl_alg”)
在代码生成报告中,检查生成的文件。该规范符合要求。例如,ex_ext_ctrl_sigs.c
定义控制输出信号,CONTR_SIG_FLOW
和控制信号温度
.
文件= fullfile (“ex_ext_ctrl_alg_ert_rtw”,“ex_ext_ctrl_sigs.c”);rtwdemodbtype(文件,“dataPath_flow_T CONTR_SIG_FLOW;”,...“dataPath_temp_T CONTR_SIG_TEMP;”, 1, 1)
设定点参数显示在ex_ext_ctrl_params.c
.
文件= fullfile (“ex_ext_ctrl_alg_ert_rtw”,“ex_ext_ctrl_params.c”);rtwdemodbtype(文件,'const dataPath_flow_T PARAM_setpoint_flow = 3.0;',...'const dataPath_temp_T PARAM_setpoint_temp = 2.0;', 1, 1)
该文件ex_ext_ctrl_alg.c
定义全局变量来存储状态数据。变量遵循您指定的命名方案。代码类似如下:
数据路径临时外部集成器状态数据g;数据路径、流量、外部、积分器、状态数据;数据路径临时文本控制过滤器状态数据D;数据路径(数据流)ex(外部)ctrl(控制)Filter(过滤)State(状态)数据;
在同一个文件中,模型执行函数,ex_ext_ctrl_alg_step
,创建本地函数变量以存储临时计算。变量遵循指定的命名方案。代码类似于以下代码:
dataPath_flow_T Diff_local;dataPath_flow_T FilterCoefficient_local;dataPath_temp_T Diff1_local;dataPath_temp_T FilterCoefficient_locali;
一些全局变量和局部变量名称包含额外的混乱字符,以防止名称冲突。这些额外的字符对应于M美元
在命名方案中指定的标记。
生成的代码文件位于生成的文件夹中ex_ext_ctrl_alg_ert_rtw
和slprj
.您必须配置文件管理系统和构建工具才能使用这些文件夹和文件。