在 Simulink 环境中编译集成的代码
工作流
要编译集成生成的代码和外部 C 或 C++ 代码的可执行程序,请依次执行下表中的任务。
任务 | 操作 | 更多信息 |
---|---|---|
1 | 选择一种编译方法。 | 编译从 Simulink 模型生成的代码的方法 (Embedded Coder) 有关示例,请参阅Build Process Workflow for Real-Time Systems (Embedded Coder)。 |
2 | 为您的外部代码配置编译过程支持。 | 为集成的代码编译过程配置参数 (Embedded Coder) |
3 | 为您的外部代码配置 S-Function 编译支持。 | 编译对 S-Function 的支持 (Embedded Coder) Use makecfg to Customize Generated Makefiles for S-Functions (Embedded Coder) 有关示例,请参阅调用可重用的外部算法代码进行仿真和代码生成 (Embedded Coder)。 |
4 | 配置编译过程以查找外部代码源、库和头文件。 | Manage Build Process File Dependencies (Embedded Coder) Control Library Location and Naming During Build (Embedded Coder) |
5 | 设置您的外部代码集成所需的自定义编译处理。 | 有关编译过程自定义工作流的信息,请参阅Customize Post-Code-Generation Build Processing (Embedded Coder)。 要自动将编译自定义应用于工具链方法编译,请参阅Customize Build Process with sl_customization.m (Embedded Coder)。 要自动将编译自定义应用于模板联编文件方法编译,请参阅使用 STF_make_rtw_hook 文件自定义编译过程 (Embedded Coder)。 |
为集成的代码编译过程配置参数
下表说明如何配置编译过程的“模型配置参数”对话框的代码生成 > 自定义代码窗格中的模型配置参数,以支持在编译过程中集成外部代码。有关外部代码的文件夹的信息,请参阅管理编译过程文件夹 (Embedded Coder)。如果您选择将外部代码放入Code generation folder 中,请参阅在编译文件夹中保留外部代码文件 (Embedded Coder)。
要执行的操作 | 选择 |
---|---|
将包含文件夹(其中包含头文件)添加到编译过程 | 代码信息 > 包含目录,然后输入文件夹的绝对路径或相对路径。 如果指定相对路径,则路径必须相对于包含模型文件的文件夹,而不是相对于编译文件夹。您指定文件夹的顺序是在其中搜索头文件、源和库文件的顺序。 |
添加要编译和链接的源文件 | 代码信息 > 源文件,然后输入文件的完整路径或仅输入文件名。 如果文件位于当前 MATLAB® 文件夹或其中一个包含文件夹中,请只输入文件名。对于您指定的每个其他源,编译过程都会为源文件所在的文件夹在模板联编文件中展开一条通用规则。例如,如果源文件位于文件夹
%.obj: buildir\inc\%.c $(CC) -c -Fo$(@F) $(CFLAGS) $< 编译过程按照列出源文件的顺序添加规则。 |
添加要链接的库 | 代码信息 > 库,然后输入库的完整路径或仅输入文件名。 如果库位于当前 MATLAB 文件夹或其中某个包含文件夹中,请只输入文件名。 |
使用与针对 MATLAB Function 模块、Stateflow® 图和 Truth Table 模块的仿真指定的相同的自定义代码设置 | 使用与仿真目标相同的自定义代码设置 此参数引用“配置参数”对话框中的仿真目标窗格。 |
使库模型能够使用库所链接到的父模型中具有唯一性的自定义代码设置 | 使用本地自定义代码设置(不从主模型继承) 此参数仅适用于包含 MATLAB Function 模块、Stateflow 图或 Truth Table 模块的库模型。 |
在编译文件夹中保留外部代码文件
默认情况下,编译过程将删除外部源文件。您可以按照下列规范保留外部源文件。
如果将 .c/.cpp
或 .h
源文件放入编译文件夹中,并且希望防止代码生成器在 TLC 代码生成过程中将其删除,请在 .c/.cpp
或 .h
文件的第一行中插入文本 target specific file
。例如:
/* COMPANY-NAME target specific file * * This file is created for use with the * COMPANY-NAME target. * It is used for ... */ ...
确保“target specific file”的拼写与前面示例中的完全相同,并且这段文本位于源文件的第一行。其他文字可以出现在这些文字之前或之后。
以这种方式标记用户文件可防止对这些文件进行后处理,避免用生成的源文件对这些文件的代码格式进行整理。在以前的版本中会发生自动缩进,以编译具有模式 model
_*.c/.cpp
(其中 *
为文本)的名称的文件夹文件。格式整理不会损坏文件,但可能会导致源代码管理软件检测到差异,这些差异可能会触发不必要的更新。
编译对 S-Function 的支持
借助用户编写的 S-Function 模块,您可以将外部代码整合到 Simulink® 开发环境中。在大多数情况下,您可以使用 S-Function 将现有外部代码与生成的代码进行集成。有几种编写 S-Function 的方法:
使用 S-Function,还可以最灵活有效地在编译过程中包含原有和自定义代码文件的编译信息。
将 S-Function 添加到编译过程有多种不同的方法。
隐式编译支持
在编译具有 S-Function 的模型时,编译过程向生成的联编文件添加规则、包含路径和源文件名。S-Function 的源文件(.h
、.c
和 .cpp
)必须与 S-Function MEX 文件位于同一文件夹中。无论是使用工具链方法还是使用模板联编文件方法进行编译,编译过程都会将此信息传播到工具链或模板联编文件中。
如果文件
与 S-Function MEX 文件位于同一文件夹中(例如sfcnname
.h
),则该文件夹将被添加到包含路径中。sfcnname
.mexext
如果文件
或sfcnname
.c
与 S-Function MEX 文件位于同一文件夹中,则编译过程会添加一个联编文件规则,以编译来自该文件夹的文件。sfcnname
.cpp当 S-Function 不与 TLC 文件内联时,编译过程必须编译 S-Function 源文件。为了确定要添加到要编译的文件列表的源文件的名称,编译过程会在 MATLAB 路径上搜索
。如果找到源文件,则编译过程会将源文件名添加到联编文件。如果在路径上找不到sfcnname
.cpp
,则编译过程会将文件名sfcnname
.cpp
添加到联编文件,无论它是否位于 MATLAB 路径上都是如此。sfcnname
.c注意
为了使 Simulink 引擎找到用于仿真和代码生成的 MEX 文件,它必须存在于 MATLAB 路径上,或存在于我们的当前 MATLAB 工作文件夹中。
为 S-Function 指定其他源文件
如果您的 S-Function 有其他源文件依存关系,则必须将其他模块的名称添加到编译过程。指定文件名:
在“S-Function 模块参数”对话框的 S-Function 模块字段中
在对
set_param
函数的调用中使用SFunctionModules
参数
例如,假设您编译具有多个模块的 S-Function。
mex sfun_main.c sfun_module1.c sfun_module2.c
然后,您可以通过执行以下操作之一将模块添加到编译过程:
在“S-Function 模块”对话框中,在 S-Function 模块字段中指定
sfun_main
、sfun_module1
和sfun_module2
。在 MATLAB 命令提示符下,输入:
set_param(sfun_block,'SFunctionModules','sfun_module1 sfun_module2')
您也可以定义一个变量来表示参数值。
modules = 'sfun_module1 sfun_module2' set_param(sfun_block,'SFunctionModules', modules)
S-Function 模块字段和 SFunctionModules
参数不支持完整的源文件路径设定。要使用该参数,代码生成器在执行联编文件时必须找到其他源文件。为了让代码生成器找到其他文件,请将它们放在与 S-Function MEX 文件相同的文件夹中。然后您可以利用隐式编译支持中所述的隐式编译支持。
准备好生成代码之后,强制代码生成器重新编译顶层模型,如Control Regeneration of Top Model Code中所述。
对于更复杂的 S-Function 文件依存关系,例如在其他位置指定源文件或者指定库或目标文件,请使用 rtwmakecfg.m
API,如Use rtwmakecfg.m API to Customize Generated Makefiles中所述。
使用 TLC 库函数
如果通过编写 TLC 文件来内联 S-Function,则可以使用 TLC 库函数 LibAddToModelSources
将源文件名添加到编译过程。有关详细信息,请参阅LibAddSourceFileCustomSection(file, builtInSection, newSection)。
注意
此函数不支持完整的源文件路径设定。该函数假定代码生成器在执行联编文件时可以找到其他源文件。
另一个有用的 TLC 库函数是 LibAddToCommonIncludes
。在 #include
语句中使用此函数以将 S-Function 头文件包含在生成的 model
.h
头文件中。有关详细信息,请参阅LibAddToCommonIncludes(incFileName)。
对于更复杂的 S-Function 文件依存关系,例如在其他位置指定源文件或者指定库或目标文件,请使用 rtwmakecfg.m
API,如Use rtwmakecfg.m API to Customize Generated Makefiles中所述。
预编译 S-Function 库
您可以使用 MATLAB 语言函数 rtw_precompile_libs
为模型预编译新的或更新的 S-Function 库(MEX 文件)。此函数使用指定的模型和库编译设定编译库并将其放置在预编译库文件夹中。
通过预编译 S-Function 库,可以优化系统编译。一旦您的预编译库存在,编译过程便可以在后续的编译中省略库编译。对于使用大量库的模型,可以显著节省编译处理的时间。
要使用 rtw_precompile_libs
,请执行下列操作:
根据您的系统平台设置库文件后缀,包括文件类型扩展名。
考虑确定平台类型,然后使用
TargetLibSuffix
参数对应地设置库后缀。例如,为 GRT 目标应用后缀时,可以将后缀设置为_std.a
(对于 UNIX® 平台)和_vcx64.lib
(对于 Windows® 平台)。if isunix suffix = '_std.a'; else suffix = '_vcx64.lib'; end set_param(my_model,'TargetLibSuffix', suffix);
有许多因素会影响预编译库后缀和扩展名。下表提供了通常选择的系统目标文件、编译器工具链以及影响您选择的后缀和扩展名的其他选项的示例。有关详细信息,请检查
matlab/rtw/c/grt
文件夹或matlab/rtw/c/ert
文件夹中的模板联编文件。TMF 文件 COMPILER _TOOL_CHAIN 值 预编译器库 (PRECOMP_LIBRARIES) 库后缀 S-Function(EXPAND _LIBRARY _NAME 值) 库后缀整数 - 仅代码(EXPAND _LIBRARY _NAME 值) 库后缀速度优化(EXPAND _LIBRARY _NAME 值) 库扩展名(EXPAND _LIBRARY _NAME 值) ert_vcx64.tmf vcx64 _rtwsfcn_vcx64 _int_ert_vcx64 _ert_vcx64 .lib ert_unix.tmf unix _rtwsfcn _int_ert _ert .a grt_vcx64.tmf vcx64 不适用 不适用 _vcx64 .lib grt_unix.tmf unix 不适用 不适用 _std .a 设置预编译库文件夹。
使用以下方法之一来设置预编译库文件夹:
设置
TargetPreCompLibLocation
参数,如Specify the Location of Precompiled Libraries中所述。在
rtwmakecfg.m
函数文件中设置makeInfo.precompile
字段。(有关详细信息,请参阅Use rtwmakecfg.m API to Customize Generated Makefiles。)
如果设置
TargetPreCompLibLocation
和makeInfo.precompile
,则TargetPreCompLibLocation
的设置优先。以下命令将模型
my_model
的预编译库文件夹设置为当前工作文件夹下的lib
文件夹。set_param(my_model,'TargetPreCompLibLocation', fullfile(pwd,'lib'));
注意
如果您为预编译库文件和目标库文件后缀都设置目标文件夹,则编译过程将在处理编译时检测是否缺少任何预编译库文件。
定义编译设定。
设置定义编译设定的结构体。下表描述您可以在结构体中定义的字段。这些字段是可选的,但
rtwmakecfgDirs
除外。字段 描述 rtwmakecfgDirs
字符向量元胞数组,用于命名包含要预编译的库的
rtwmakecfg
文件的文件夹。该函数使用rtwmakecfg
返回的makeInfo.library
的Name
和Location
元素来指定预编译库的名称和位置。如果您通过设置TargetPreCompLibLocation
参数来指定库文件夹,则该设置将覆盖makeInfo.library.Location
设置。注意:指定的模型必须包含使用由
rtwmakecfg
文件指定的预编译库的模块,因为仅在编译过程使用这些库时,TMF 到联编文件的转换才会生成库规则。libSuffix
字符向量,指定要附加到每个库名称的后缀(包括文件类型扩展名),例如 .a
或_vc.lib
。字符向量必须包含句点 (.)。您必须使用此字段或TargetLibSuffix
参数设置后缀。如果您同时使用这两种机制指定后缀,则TargetLibSuffix
设置将覆盖此字段的设置。intOnlyBuild
布尔标志。当设置为 true 时,该标志表示库将优化,以便它们仅从整数代码编译。此字段仅适用于 ERT 目标。 makeOpts
字符向量,指定要包含在 rtwMake
命令行中的选项。addLibs
结构体的元胞数组,这些结构体指定要编译的、并非由
rtwmakecfg
函数指定的库。必须使用两个字符数组形式的字段来定义每个结构体:libName
- 没有后缀的库名称libLoc
- 预编译库的位置
目标联编文件 (TMF) 可以指定其他库以及这些库的编译方式。使用此字段来预编译这些库。
以下命令设置编译设定
build_spec
,它指示要编译的文件位于当前工作文件夹下的src
文件夹中。build_spec = []; build_spec.rtwmakecfgDirs = {fullfile(pwd,'src')};
发出对
rtw_precompile_libs
的调用。该调用必须指定要为其编译预编译库的模型和编译设定。例如:
rtw_precompile_libs(my_model,build_spec);
相关主题
- 调用可重用的外部算法代码进行仿真和代码生成 (Embedded Coder)
- Place External C/C++ Code in Generated Code (Embedded Coder)
- 调用外部设备驱动程序 (Embedded Coder)
- Deploy Applications to Target Hardware (Embedded Coder)
- Deploy Generated Component Software to Application Target Platforms (Embedded Coder)