使用C代码集成C调用者块
您可以将新的或现有的C代码集成到Simulink中金宝app®使用C调用者块。若要在Simulink模型中创建自定义块,请使用金宝appC调用者block允许你调用在外部源代码和库中指定的外部C函数。的优点C调用者块:
简单C函数的自动集成
集成金宝app仿真软件覆盖™,金宝app仿真软件测试™,金宝appSimulink设计验证器™
集成金宝app仿真软件编码器™
的C调用者Block和C函数block允许您将C算法带入Simulink。金宝app要对动态系统建模,请使用s函数生成器代替。方法将C代码集成到Simulink中的工作流金宝appC调用者块。
请注意
C99是C语言的标准版本,支持自定义C代码集成到Simulink中。金宝app金宝app
指定源代码和依赖项
指定包含C函数的外部源代码文件。
从Simu金宝applink工具条中打开配置参数.
在左侧窗格中,选择模拟目标.
选择包括头信息,输入头文件的名称
# include
标签。目录和文件路径可以是模型目录或当前工作目录的绝对和相对文件路径。看到指定自定义代码的相对路径(Stateflow).
提示
在您输入信息之后源文件下一步,您可以单击从源文件自动填充要使用源文件中包含的信息自动填充头文件名。
选择源文件并输入源文件的路径和名称。如果模型和源文件在不同的目录下,则在文件名前输入包含源文件的目录。
选择包括目录,并输入存储附加构建信息(例如头文件)的文件夹。
要验证可以成功解析和构建自定义代码,请单击验证.
请注意
如果头文件声明了一个函数,但源文件没有定义该函数,默认情况下,该函数在C调用者块对话框。您可以设置未定义的函数处理参数,以指定这种情况下的其他行为,包括抛出错误、生成存根函数或忽略条件。
请注意
使用C调用者对于每个子系统或具有连续采样时间,或优化块在条件输入分支执行中的使用,块调用的自定义代码函数必须是确定性的,即始终为相同的输入产生相同的输出。属性确定哪些自定义代码函数是确定的确定的功能而且由函数指定参数模拟目标窗格。有关条件输入分支执行示例,请参见使用C调用者块与条件执行.
N-D阵列处理
金宝appSimulink可以将N-D数组数据传递给自定义代码函数C调用者块,并从这些块中接收数据。这样做时,必须指定正确的数组布局以实现预期的结果。看到默认函数数组布局而且函数异常.为使用数组数据的示例C调用者块,看到在Simulink中使用自定义图像过滤器算法作为可重用块金宝app而且使用C Caller块调用遗留查找表函数.
您可以指定在C函数中处理矩阵数据的顺序。传递给C函数和传递给C函数的矩阵数据在必要时转换为您指定的数组布局。如果未指定数组布局,则矩阵数据将以与Simulink数据相同的顺序通过C函数传递,并且由于行与列的重大不一致可能会发生计算错误。金宝app确保对所有Simulink数据遵循相同的默认函数数组布局。金宝app
列为主C函数按列主序处理输入数组数据。假设你有一个3 × 3矩阵。在C函数中,该矩阵按以下顺序访问:第一列、第二列和第三列。
行C函数按行长顺序处理输入数组数据。假设你有一个3 × 3矩阵。在C函数中,按以下顺序访问这个矩阵:第一行、第二行和第三行。
任何—C函数不关心输入数组数据的布局。例如,如果函数只对数据执行元素操作,就会出现这种情况。
未指定—C函数不假设输入数组数据的布局。相比之下任何设置时,只能在列-主设置中生成代码。试图在行主行设置中生成代码会产生错误。看到阵列布局(金宝app仿真软件编码器).仅在需要与旧型号兼容时选择此选项。
要了解有关Simulink中行主数组和列主数组布局的更多信息,请参见金宝app默认函数数组布局.
下选择数组布局选项默认函数数组布局.
如果需要将特定数组布局应用于代码中的某些函数,请单击函数异常选择这些函数。
点击应用接受您的更改。
如果您的C函数只接受标量和/或向量输入,则默认函数数组布局设置无效。
调用C调用者阻塞和指定端口
您可以通过输入启动您的自定义C代码集成到Simulink金宝appC调用者
在Simuli金宝appnk画布中。或者,拖动C调用者块从用户定义函数库转移到画布上。双击该块,打开块参数对话框,查看功能名称和端口规格。
单击Refresh按钮导入源代码及其依赖项。
您的C函数显示在下面函数名.如果没有看到完整的函数列表,请单击重新导入源代码。
要查看源文件中的函数定义,请单击.所选函数的源代码在MATLAB中显示®编辑器。如果源代码不可用,则显示头文件中的函数声明。
若要更改源文件及其依赖项,或定义和选择函数数组布局,请单击自定义代码设置按钮打开模拟目标窗格中的“模型配置参数”。
将C函数实参映射到金宝app港口
属性可以将源代码中的C函数参数映射到Simulink端口金宝app端口规范表中的C调用者块或通过创建FunctionPortSpecification
对象通过命令行。在源代码中,头文件包括要连接到Simulink端口的C函数参数。金宝app
extern void mean_filter(const unsigned char* src, unsigned char* dst, unsigned int width, unsigned int height, unsigned int filterSize);
的端口规范表格显示了你的论点的细节,以及它们是如何与你的论点相联系的C调用者block在Sim金宝appulink中。
该表有这些列:
的名字
指定输入和输出参数的名称。的名字是在源代码中定义的C函数中的函数参数或参数名。本专栏仅供参考。
范围
指定C函数参数如何映射到Simulink作用域。金宝app根据函数定义,参数具有默认作用域,并且可以根据源代码中的函数定义更改作用域。
金宝app模型范围 | 块映射的范围 |
---|---|
输入 |
块输入端口 |
输出 |
块输出端口 |
输入输出 |
阻塞输入输出端口 |
全球 |
不适用 |
参数 |
块可调参数 |
常数 |
恒定值 |
对于通过指针传递的实参,当实参具有常量限定符定义时,例如Const double *u
时,实参只能是输入或形参。当没有常量限定词时,实参为输入输出
默认情况下,您可以将其更改为输入
,输出
,或参数
范围。对于输入
或参数
范围,确保C函数不修改指针所指向的内存。如果参数是输出
范围,此指针所指向的每个元素都应该在函数的每次调用中重新赋值。
C参数 |
金宝app模型范围 |
---|---|
函数返回 |
|
|
输入 ,参数 ,常数 |
|
输入输出 (默认),输出 ,输入 ,参数 |
|
|
使用输入输出
作用域来映射C函数中指针传递的输入。创建的端口输入输出
范围的输入和输出端口具有相同的名称。的输入输出
作用域允许为输入和输出端口重用缓冲区。这可以根据信号大小和块布局优化内存使用。
将C函数参数映射到输入输出
作用域,将变量定义为函数中的指针。
extern void mean_filter(unsigned char* src, unsigned int width, unsigned int height, unsigned int filterSize);
然后设置作用域为输入输出
在端口规范表,并将结果函数输出分配给自定义函数中的输入变量。
您可以在自定义代码中使用全局变量,将它们映射到适当的Simulink作用域。金宝app要在模型中启用全局变量,请选择启用全局变量作为函数接口从模型设置>配置参数>模拟目标.你可以把全局变量映射到输入
,输出
,输入输出
或全球
的范围C调用者块。这些作用域的可用性取决于自定义代码中全局变量的使用情况。
一个全球
范围使您能够在自定义代码和C调用者块,并允许您在块上的计算期间使用全局变量。使用全球
作用域在块接口上不可见。下表显示了示例代码片段及其默认端口和可用端口。
示例代码 | 金宝app模型范围 |
---|---|
双数据;Void foo(Void) {int temp = data;} |
全局变量数据只读取变量
|
双数据;Void bar(Void) {data = 0;} |
数据被写入全局变量。可用的范围是:
|
双数据;Void foo2(Void) {data = data + 1;} |
在全局变量上读取和写入数据。可用的范围是:
|
标签
指示Simulink块中相应参数的标签。金宝app默认情况下,参数标签与参数名称相同,除非您更改了它。改变范围配置端口标签的选项。
范围 | 金宝appSimulink端口标签 |
---|---|
|
端口名称 |
输入输出 |
输入和输出端口中的端口名称 |
全球 |
端口名称和全局变量名称 |
|
参数名称 |
|
常量值的表达式。 例如,使用输入参数名的大小表达式 |
类型
指定参数的数据类型。C函数中的数据类型必须匹配Simulink中的等效数据类型。金宝app类中所支持的C数据类型金宝appC调用者块,以及等效的Simulink数据类型。金宝app
参数数据类型 | 金宝appSimulink数据类型 |
---|---|
Signed char/unsigned char | int8 / unit8 |
字符 | Int8或uint8,取决于编译器 |
int /无符号整型* | int32 / unit32 |
短/无符号短* | int16 / unit16 |
长/无符号长* | Int32 /uint32或int64/unit64,取决于操作系统 |
Long Long /unsigned Long Long* | int64 / uint64 |
浮动 | 单 |
双 | 双 |
int8_t / uint8_t* | int8 / uint8 |
int16_t / unit16_t* | int16 / unit16 |
int32_t / unit32_t* | int32 / uint32 |
int64_t / unit64_t* | int64 / uint64 |
保龄球 | 布尔 |
struct{…** | 总线:AStruct |
类型定义枚举{..} AnEnum** | 枚举:AnEnum |
*如果C调用者采用整数类型,例如int16_t,您可以将其修改为具有匹配基类型的定点类型,例如fixdt(1,16,3)。 * *的C调用者sync按钮提示您将C函数使用的结构或枚举类型导入为Simulink总线和枚举类型。金宝app |
大小
指定参数中的数据维。
C参数维度 | 金宝appSimulink端口尺寸 |
---|---|
|
标量( |
|
继承( 如果参数是用于输出端口的,则必须指定其大小并且不能继承,除非该参数映射到 |
|
继承( 如果参数是用于输出端口的,则必须指定其大小并且不能继承,除非该参数映射到 对于全局变量,size为标量( |
|
大小是 |
创建一个FunctionPortSpecification
对象和编辑C调用者块的属性
改变端口规范表属性,可以通过编程方式创建FunctionPortSpecification
对象并修改其属性。要创建FunctionPortSpecification
对象。C调用者块,在命令行中输入:
myCCallerConfigObj = get_param(gcb,“FunctionPortSpecification”)
myCCallerConfigObj =带有属性的FunctionPortSpecification: CPrototype: 'real_T add(real_T u1, real_T u2);' InputArguments: [1×2 Simulink.Cus金宝apptomCode。FunctionArgument] ReturnArgument: [1×1 金宝appSimulink.CustomCode.]FunctionArgument] GlobalArguments: [1×0 Simulink.CustomCode.FunctionArgument]
CPrototype
属性是只读的,并且显示C函数输入变量的声明。的InputArgument
而且ReturnArgument
属性创建FunctionArgument
对象,您可以根据为其定义的规则进一步编辑其属性端口规范表上面。看到FunctionPortSpecification
了解更多。
类中的全局实参C调用者块的句柄GlobalArguments
对象使用getGlobalArg
并修改其属性。
创建一个自定义C调用程序库
建议创建一个库模型来对您的C调用者块和保持你的模型有组织。还可以将数据字典链接到库,以保存代码中定义的自定义类型。当您有多个模型或使用自定义C代码的模型引用层次结构时,使用库模型尤其有用。
打开一个新的库模型。在模拟选项卡上,选择新>图书馆.
在建模选项卡,在设计,点击模拟自定义代码.
选择
C
或c++
在语言选项,具体取决于您的代码,并确保导入自定义代码框选中。请按照指定源代码和依赖项添加源文件及其依赖项。
创建C调用者块来调用C函数。
要将块从库模型插入到Simulink模型,只需将块拖到模型中。金宝app
的库也可以创建C调用者块的自定义代码使用Simulink代码导入器。金宝app看到使用Simulink代码导入器导入自定义C/ c++代码金宝app.
调试自定义代码
通过启动外部调试器并在自定义代码中设置断点,您可以在Simulink中调金宝app试代码。有关更多信息,请参见调试自定义C/ c++代码.
从模型生成代码
的C调用者金宝app支持代码生成。在从模型生成的代码中,每次执行一个C调用者block对应于对与该block相关的外部C函数的调用。为了构建生成的代码,使用代码生成>自定义代码“模型配置参数”窗格中必须填充有关自定义代码的正确信息。看到模型配置参数:代码生成自定义代码(金宝app仿真软件编码器).
限制
全局变量—作为函数输入输出的全局变量不支持多维数组。金宝app
初始化/终止自定义代码设置-如果您需要为您的自定义代码分配和释放内存,请在初始化函数而且终止函数字段的自定义代码设置,或使用C函数块。
复杂数据支持金宝app- - -C调用者block不支持Simulin金宝appk中的复杂数据类型。金宝app
变量参数- C语言不支持变量参数,例如:金宝app
sprintf(char *str, const char *format,…)
.c++语法- - -C调用者block不直接支持原生c++金宝app语法。您需要编写一个C函数包装器来与c++代码进行接口。
测试包含的模型C调用者块,看到测试集成C代码(金宝app仿真软件测试).
请注意
如果模型具有自定义代码,则在模型更新或运行后,将slprj
由于加载自定义代码模拟可执行文件,文件夹可能被锁定。文件夹被锁定后,无法删除。卸载可执行文件并解锁slprj
文件夹,使用清晰的墨西哥人
命令。看到清晰的
.