使用C Caller 模块集成C代码到Simulink模型

news2024/9/23 11:20:01

可以使用 C Caller 模块将新的或现有的 C 代码集成到 Simulink 模型中。要在 Simulink 模型中创建自定义模块,C Caller 模块允许您调用在外部源代码和库中指定的外部 C 函数。C Caller 模块具有以下优势:

  • 简单 C 函数的自动集成,包括命名空间下定义的函数
  • 与 Simulink Coverage、Simulink Test 和 Simulink Design Verifier 的集成
  • 与 Simulink Coder 的集成

C Caller 模块和 C Function 模块允许您将 C 算法引入 Simulink。要对动态系统进行建模,请改用 S-Function Builder。接下来的步骤说明使用 C Caller 模块将 C 代码集成到 Simulink 中的工作流。

指定源代码和依存关系

指定包含您的 C 函数的外部源代码文件。

  1. 从 Simulink 工具条中,打开配置参数
  2. 在左窗格中,选择仿真目标
  3. 选择包含头文件,并输入具有 #include 标记的头文件的名称。

  1. 选择源文件,并输入源文件的路径和名称。如果模型和源文件在不同目录中,请在文件名之前输入包含源文件的目录。

  1. 选择包含目录,并输入存储其他编译信息(如头文件)的文件夹。

要验证您的自定义代码可以成功解析和编译,请点击验证

注意:

如果头文件声明了一个函数,但源文件未定义该函数,则默认情况下,该函数在 C Caller 模块对话框中不可见。您可以在配置参数中设置未定义函数的处理参数,以指定在这种情况下的其他行为,包括引发错误、生成桩函数或忽略该条件。

注意:

要使用 For Each 子系统中的或具有连续采样时间的 C Caller 模块,或要优化该模块在条件输入分支执行中的使用,该模块调用的自定义代码函数必须为确定性的,即始终对相同的输入产生相同的输出。通过使用仿真目标窗格中的确定性函数按函数指定参数,确定哪些自定义代码函数是确定性的。

N 维数组处理

Simulink 可以将 N 维数组数据传递给 C Caller 模块中的自定义代码函数,并从这些模块中接收数据。当您这样做时,必须指定正确的数组布局才能获得预期的结果。

您可以指定矩阵数据在 C 函数中的处理顺序。如果需要,传递给 C 函数和从 C 函数传递的矩阵数据会转换为指定的数组布局。如果未指定数组布局,矩阵数据将按照与 Simulink 数据相同的顺序通过 C 函数,并且由于行-列优先混乱,可能会出现计算错误。确保对所有 Simulink 数据使用相同的默认函数数组布局。

  • 列优先 - C 函数按列优先顺序处理输入数组数据。假设您有一个 3×3 矩阵。在 C 函数中,按以下顺序访问此矩阵:第一列、第二列和第三列。
  • 行优先 - C 函数按行优先顺序处理输入数组数据。假设您有一个 3×3 矩阵。在 C 函数中,按以下顺序访问此矩阵:第一行、第二行和第三行。
  • 任何 - C 函数与输入数组数据的布局无关。例如,如果函数只对数据执行按元素运算,就会出现这种情况。
  • 未指定 - C 函数不假定输入数组数据的布局。与任何设置相比,您只能按列优先设置生成代码。尝试按行优先设置生成代码会产生错误。
  1. 默认函数数组布局下选择一个数组布局选项。
  2. 如果您需要对代码中的某些函数应用特定的数组布局,请点击例外(按函数) 以选择这些函数。
  3. 点击应用以接受您的更改。

如果您的 C 函数只接受标量和/或向量输入,则默认函数数组布局设置不起作用。

调用 C Caller 模块并指定端口

您可以在 Simulink 画布中键入 C Caller,以开始在 Simulink 中集成您的自定义 C 代码。或者,将 User-Defined Functions 库中的一个 C Caller 模块拖到画布上。双击该模块打开模块参数对话框,查看您的函数名称和端口设定。

  1. 点击“刷新”按钮  导入源代码及其依存关系。
  2. 您的 C 函数显示在函数名称下。如果没有看到完整的函数列表,请点击  重新导入源代码。
  3. 要查看源文件中的函数定义,请点击 。所选函数的源代码显示在 MATLAB® 编辑器中。如果源代码不可用,将显示头文件中的函数声明。
  4. 要更改源文件及其依存关系,或定义并选择函数数组布局,请点击自定义代码设置按钮  打开模型配置参数中的仿真目标窗格。

将 C 函数参数映射到 Simulink 端口

您可以使用 C Caller 模块中的端口设定表,或通过命令行创建 FunctionPortSpecification 对象,将源代码中的 C 函数参数映射到 Simulink 端口。在源代码中,头文件包含要连接到 Simulink 端口的 C 函数参数。

端口设定表显示您的参数的详细内容,以及它们如何连接到您在 Simulink 中的 C Caller 模块。

该表包含以下各列:

名称

指定输入和输出参数的名称。名称是源代码中的 C 函数中定义的函数参数名称。此列仅供参考。

作用域

指定 C 函数参数如何映射到 Simulink 作用域。您的参数具有根据函数定义确定的默认作用域,并且您可以根据源代码中的函数定义来更改作用域。

Simulink Scope

作用域到模块的映射

输入

模块输入端口

输出

模块输出端口

InputOutput

模块输入和输出端口

全局

不适用

参数

模块可调参数

常量

常量值

对于指针传递的参量,当该参量具有常量限定符定义(如 const double *u)时,该参量必须为 input 或 parameter 类型。如果没有常量限定符,则该参数默认为 InputOutput,您可以将其更改为 Input、Output 或 Parameter 作用域。在使用 Input 或 Parameter 作用域的情况下,请确保 C 函数不会修改指针指向的内存。如果参数是 Output 作用域,则在该函数的每次调用中,该指针指向的每个元素都应该重新分配。

C 参数

Simulink Scope

函数返回

输出

double u

输入、“参数、“常量

double *u

double u[]

double u[][2]

double u[2][3]

InputOutput(默认值)、“输出、“输入、“参数

const double *u

const double u[]

const double u[][2]

const double u[2][3]

输入(默认值)、“参数

使用 “InputOutput” 作用域映射 C 函数中指针传递的输入。对于使用 “InputOutput” 作用域创建的端口,输入和输出端口的名称相同。“InputOutput” 作用域支持重用输入和输出端口的缓冲区。这可以根据信号大小和模块布局来优化内存的使用。

要将 C 函数参数映射到 “InputOutput” 作用域,请将该变量定义为函数中的指针。

然后,在端口设定表中将作用域设置为 “InputOutput”,并将结果函数输出赋给自定义函数中的输入变量。

您可以在自定义代码中使用全局变量,将它们映射到适当的 Simulink 作用域。要在模型中使用全局变量,请从模型设置 > 配置参数 > 仿真目标中选择 Enable global variables as function interfaces。您可以将全局变量映射到 C Caller 模块上的“输入”、“输出”、“InputOutput” 或“全局”作用域。这些作用域的可用性取决于自定义代码中全局变量的使用情况。

“全局”作用域使您能够在自定义代码和 C Caller 模块之间传输数据,并允许您在计算期间对模块使用全局变量。使用“全局”作用域传输的值在模块接口上不可见。下表显示示例代码段及其默认端口和可用端口。

示例代码

Simulink Scope

double data;

void foo(void)

    {

        int temp = data; 

    }

全局变量数据只读取变量 data。可用作用域包括:

输入(默认值)

全局

double data;

void bar(void)

    {

        data = 0;

    }

数据写入全局变量。可用作用域包括:

输出(默认值)

全局

InputOutput

double data;

void foo2(void)

    {

        data = data + 1;

    }

可对全局变量读写数据。可用作用域包括:

全局(默认值)

InputOutput

输出

标签

指示 Simulink 模块中对应参数的标签。默认情况下,参数标签与参数名称相同,除非您更改它。更改作用域以配置端口标签的选项。

作用域

Simulink 端口标签

输入、“输出

端口名称

InputOutput

输入和输出端口中的端口名称

全局

端口名称和全局变量名称

参数

参数名称

常量

常量值的表达式。

使用输入参数名称的 size 表达式,例如 size(in1,1)

类型

指定参数的数据类型。C 函数中的数据类型必须与 Simulink 中的等效数据类型匹配。下表显示您可以在 C Caller 模块中使用的受支持的 C 数据类型,以及等效的 Simulink 数据类型。

C 参数数据类型

Simulink 数据类型

有符号字符/无符号字符

int8/unit8

char

int8 或 uint8,具体取决于编译器

int/unsigned int*

int32/unit32

short/unsigned short*

int16/unit16

long/unsigned long*

int32/uint32 或 int64/unit64,取决于操作系统

long long/unsigned long long*

int64/uint64

float

单精度

双精度

双精度

int8_t/uint8_t*

int8/uint8

int16_t/unit16_t*

int16/unit16

int32_t/unit32_t*

int32/uint32

int64_t/unit64_t*

int64/uint64

bool

布尔

typedef struct {…} AStruct**

Bus: AStruct

typedef enum {..} AnEnum**

Enum: AnEnum

* 如果 C Caller 采用整数类型,例如 int16_t,您可以将其修改为具有匹配的基类型的定点类型,例如修改为 fixdt(1, 16, 3)。

** C Caller 同步按钮提示您将 C 函数使用的结构体或枚举类型导入为 Simulink 总线和枚举类型。

大小

指定参数中的数据维度。

C 参数维度

Simulink 端口维度

double u

标量 (1)

double u[]

double u[][2]

继承 -1(默认值)

如果该参量用于输出端口,则必须指定其大小,并且该大小无法继承,除非该参量映射到 “InputOutput作用域,或模型配置参数在单独进程中仿真自定义代码处于选中状态。

double *u

继承 -1(默认值)

如果该参量用于输出端口,则必须指定其大小,并且该大小无法继承,除非该参量映射到 “InputOutput作用域,或模型配置参数在单独进程中仿真自定义代码处于选中状态。

对于全局变量,大小是标量 (1)

double u[2][3]

大小为 [2, 3]

创建 FunctionPortSpecification 对象并编辑 C Caller 模块属性

要以编程方式更改端口设定表属性,您可以创建 FunctionPortSpecification 对象并修改其属性。要为模型中的所选 C Caller 模块创建 FunctionPortSpecification 对象,请在命令行中键入:

CPrototype 属性是只读属性,它显示 C 函数输入变量的声明。InputArgument 和 ReturnArgument 属性创建了 FunctionArgument 对象,您可以根据上面为端口设定表定义的规则进一步编辑其属性。

要修改 C Caller 模块中的全局参数,请使用 getGlobalArg 创建 GlobalArguments 对象的句柄并修改其属性。

创建自定义 C Caller 库

建议创建一个库模型来对 C Caller 模块进行分组并保持模型组织良好。还可以将数据字典链接到库以保留代码中定义的自定义类型。当您有多个模型或一个使用自定义 C 代码的模型引用层次结构时,使用库模型尤其有用。

  1. 打开一个新库模型。在仿真选项卡上,选择新建 > 
  2. 建模选项卡上,在设计下,点击仿真自定义代码
  3. 根据您的代码,在语言选项中选择 C 或 C++,并确保导入自定义代码框已选中。
  4. 按照指定源代码和依存关系中的说明添加源文件及其依存关系。
  5. 创建 C Caller 模块来调用 C 函数。
  6. 要将库模型中的模块插入 Simulink 模型,只需将该模块拖到模型中即可。

您也可以使用 Simulink 代码导入器从自定义代码创建 C Caller 模块库。

调试自定义代码

通过启动外部调试器并在自定义代码中设置断点,您可以从 Simulink 内部调试您的代码。

从模型生成代码

C Caller 支持代码生成。在从您的模型生成的代码中,C Caller 模块的每次执行对应于对与该模块相关联的外部 C 函数的一次调用。为了编译生成的代码,模型配置参数的代码生成 > 自定义代码窗格必须填充有关自定义代码的正确信息。

限制

  • 初始化/终止自定义代码设置 - 如果您需要为自定义代码分配和取消分配内存,请在自定义代码设置的初始化函数终止函数字段中插入 allocate 和 deallocate,或者使用 C Function 模块。
  • 复数数据支持 - C Caller 模块不支持 Simulink 中的复数数据类型。
  • 变量参数 - 不支持 C 语言中的变量参数,例如 int sprintf(char *str, const char *format, ...)。
  • C++ 语法 - C Caller 模块不直接支持原生 C++ 语法。您需要编写 C 函数包装器来与 C++ 代码对接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1906539.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

同声传译的app有哪些?分享5个旅行者的多语言翻译伙伴

许多人可能并不了解什么是同声传译。其实,同声传译是一种高效的语言服务,它使得不同语言的人们能够在会议、谈判、演讲等场合中实现即时交流。 今天,本文将向您介绍几款能够实现同声传译的实用工具,帮助您更深入地了解同声传译的…

做外贸干一行爱一行,还是干一行厌一行?

记得年轻的时候,每每和同龄人不同行业聊天的时候,大家普遍的感觉就是:自己这一行太苦了,以后有孩子了干什么都不能让他做自己这一行。 和在银行上班的同学聊天,他们最大的苦恼是需要每天开发客户, 让客户在…

如何利用股指期货代替买股票?

当我们深入探讨中金所上市的三个股指期货——IF(沪深300股指期货)、IC(中证500股指期货)和IH(中证50股指期货)时,我们可以从多个角度来分析它们的特点和优势。 市场特点分析 IH(上…

科研绘图系列:R语言径向柱状图(Radial Bar Chart)

介绍 径向柱状图(Radial Bar Chart),又称为雷达图或蜘蛛网图(Spider Chart),是一种在极坐标系中绘制的柱状图。这种图表的特点是将数据点沿着一个或多个从中心向外延伸的轴来展示,这些轴通常围绕着一个中心点均匀分布。 特点: 极坐标系统:数据点不是在直角坐标系中展…

Qt json和xml操作

学习目标: 认识json和xml读写操作 前置环境 运行环境:qt creator 4.12 学习内容 XML XML(Extensible Markup Language)是一种标记语言,是一种用于描述数据结构的语言。它非常适合用于存储和传输数据。 XML 的主要特点如下: 可扩展性:XM…

TypeSscript 学习(一)

一、为什么使用 TypeScript 因为 js 是一种 弱类型语言 编写代码比较灵活 但是当项目比较大时 这种灵活不利于维护 我们用 TypeScript 这种强类型的语言 比较利于维护 二、语法 1.类型推断 ts 通过我们写的内容 知道变量的类型 定义 str 为 abc 以后 str 只能存 字符串…

element-ui操作表格行内容如何获取当前行索引?

需求&#xff1a; 根据每个用户的提交次数、撤回次数&#xff0c;动态计算出实际次数&#xff0c;并且提交次数不能小于撤回次数 <template><div><el-table:data"tableData"style"width: 80%"border><el-table-columnprop"date&…

俄罗斯VK与Yandex,谁的优势更胜一筹?

俄罗斯VK和Yandex作为该国两大重要的网络平台&#xff0c;各自具有独特的优势。 VK是一个社交媒体巨头&#xff0c;以其庞大的用户基础著称。 这个平台不仅拥有超过数亿的注册用户&#xff0c;而且这些用户在平台上的活跃度极高&#xff0c;每天都会产生海量的内容与互动。 …

优优嗨聚集团:餐饮新纪元,揭秘餐饮合作背后的双赢奥秘

在竞争激烈的餐饮市场中&#xff0c;单打独斗早已不再是主流&#xff0c;而餐饮合作却成为了一种新的趋势。那么&#xff0c;餐饮合作究竟有哪些优势&#xff0c;能够吸引众多餐饮从业者纷纷投身其中呢&#xff1f;本文将为您揭秘餐饮合作背后的双赢奥秘。 一、资源共享&#x…

go-redis 封装事件-client封装模型、批量数据处理的导出器设计

一、redis-go的封装实践-client模型 // Copyright 2020 Lingfei Kong <colin404foxmail.com>. All rights reserved. // Use of this source code is governed by a MIT style // license that can be found in the LICENSE file.package storageimport ("context&q…

(19)夹钳(用于送货)

文章目录 前言 1 常见的抓手参数 2 参数说明 前言 Copter 支持许多不同的抓取器&#xff0c;这对送货应用和落瓶很有用。 按照下面的链接&#xff08;或侧边栏&#xff09;&#xff0c;根据你的设置了解配置信息。 Electro Permanent Magnet v3 (EPMv3)Electro Permanent M…

老胡的周刊(第149期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 mesop[2] Mesop 是一个基于 Python 的 UI 框…

【机器学习】——决策树模型

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

基于Java+SpringMvc+Vue技术的在线学习交流平台的设计与实现---60页论文参考

博主介绍&#xff1a;硕士研究生&#xff0c;专注于Java技术领域开发与管理&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架构思想、较扎实的技术功底和资深的项目管理经…

vulhub-activemq(CVE-2016-3088)

在 Apache ActiveMQ 5.12.x~5.13.x 版本中&#xff0c;默认关闭了 fileserver 这个应用&#xff08;不过&#xff0c;可以在conf/jetty.xml 中开启&#xff09;&#xff1b;在 5.14.0 版本后&#xff0c;彻底删除了 fileserver 应用。【所以在渗透测试过程中要确定好 ActiveMQ …

Avalonia 常用控件四 Text Controls

1、AutoCompleteBox <StackPanel Margin"20"><TextBlock Margin"0 5">选择一种动物</TextBlock><AutoCompleteBox x:Name"animals" FilterMode"StartsWith"/><!--AutoCompleteBox:Items:要匹配的项目列表。…

Redis集群篇

目录 传送门前言一、Redis主从复制二、Redis哨兵模式&#xff08;自动选举老大的模式&#xff09;三、Redis集群架构&#xff08;最佳&#xff09;四、Redis缓存穿透和雪崩&#xff08;面试高频&#xff09; 传送门 SpringMVC的源码解析&#xff08;精品&#xff09; Spring6的…

唤醒知识循环,共筑绿色阅读梦——探索旧书回收小程序的无限可能

在这个信息爆炸的时代&#xff0c;书籍作为知识与智慧的载体&#xff0c;其重要性不言而喻。然而&#xff0c;随着电子阅读的兴起和书籍更新换代的加速&#xff0c;大量旧书被束之高阁&#xff0c;甚至面临被遗弃的命运。这不仅是对宝贵文化资源的浪费&#xff0c;也是对环境保…

51单片机嵌入式开发:5、按键、矩阵按键操作及protues仿真

按键、矩阵按键操作及protues仿真 1 按键介绍1.1 按键种类1.2 按键应用场景 2 按键电路3 按键软件设计3.1 按键实现3.2 按键滤波方法3.3 矩阵按键软件设计3.4 按键Protues 仿真 4 按键操作总结 提示 1 按键介绍 1.1 按键种类 按键是一种用于控制电子设备或电路连接和断开的按…

UGC与AI引领的下一个10年,丝芭传媒已经准备好

丝芭传媒最近传来的消息&#xff0c;都跟技术相关。 基于自研AI大模型“Paro&#xff08;心乐舞河&#xff09;”的AIGPT及AIGC生成工具APP“鹦鹉人”开启用户内测。2023年3月技术测试的图形化智能社交基座“美踏元宇宙”&#xff0c;也将开放首轮用户内测。 此外&#xff0c…