调用 C 库函数
您可以在 Stateflow® 图中通过调用 C 库函数来添加数学运算、三角计算和指数计算,或调用 C 函数。使用 C 语言作为动作语言的图可以调用 C 库函数,而无需使用任何特殊前缀或函数包装器。要在使用 MATLAB® 作为动作语言的图中调用 C 函数,请使用 coder.ceval (Simulink) 函数。有关详细信息,请参阅使用 MATLAB Function 模块集成 C 代码 (Simulink)。
要更新图使用的动作语言,请参阅修改图的动作语言。
调用 C 库函数
在使用 C 语言作为动作语言的图中,您可以调用以下 C 数学库函数:
abssincostansinhtanhacosatanatan2coshceilfloorexpfabsfmodlabsldexploglog10powrandsqrt
当您调用这些函数时,必须使用双精度值,除非所有输入参量显式为单精度。当输入参量不匹配时,图会将输入参量强制转换为预期的数据类型。例如,如果您使用整数作为输入参量调用 sin 函数,图会将该输入参量强制转换为双精度类型的浮点数。
要调用其他 C 库函数,请打开“配置参数”对话框,并在仿真目标窗格中输入适当的 #include 语句,如Configure Custom Code中所述。
注意
当图将 C 库函数的输入参量转换为浮点数时,具有类型为 int64 或 uint64 的参量的函数调用会导致精度损失。
调用 abs 函数
Stateflow 图解释 abs 函数的方式与标准 C 版本的 abs 不同,它按如下方式处理整数和浮点参量:
如果
x是int32或int64类型的整数,则标准 C 函数abs应用于x,即abs(x)。如果
x是int16或int8类型的整数,则将标准 Cabs函数应用于转换为int32类型整数的x,即abs((int32)x)。如果
x是double类型的浮点数,则将标准 C 函数fabs应用于x,即fabs(x)。如果
x是single类型的浮点数,则将标准 C 函数fabs应用于转换为double类型的x,即fabs((double)x)。如果
x是定点数,则将标准 C 函数fabs应用于转换为double类型的定点数,即fabs((double) Vx),其中 Vx是x的实际值。
如果您需要使用的 abs 函数像在标准 C 版本函数中那样工作,请将其参量或返回值强制转换为整数类型。有关详细信息,请参阅类型转换运算。
注意
如果您在自定义代码中声明一个变量,则在所有情况下都将应用标准 C abs 函数。有关将自定义代码插入图中的说明,请参阅Use Custom C or C++ Code in Stateflow Charts。
调用 min 和 max 函数
您可以通过在生成代码的顶部发出以下宏来调用 min 和 max。
#define min(x1,x2) ((x1) > (x2) ? (x2):(x1)) #define max(x1,x2) ((x1) > (x2) ? (x1):(x2))
为了允许与用户创建的名为 min() 或 max() 的图形函数兼容,生成代码中的函数使用名称 <prefix>_min。但是,如果您将 min() 或 max() 图形函数导出到模型中的其他图,则生成代码无法使用函数的修改后名称,因而会发生冲突。为避免这种冲突,请重命名 min() 和 max() 图形函数。
用应用程序实现替换数学库函数
除 labs 和 rand 之外,您可以更改代码生成器在最终生成代码中实现数学库函数的方式。要执行此操作,请将代码生成器配置为在代码生成期间应用代码替换库 (CRL)。此外,如果您有 Embedded Coder® 许可证,则可以开发自定义 CRL。
有关使用 MathWorks® 提供的 CRL 替换代码的详细信息,请参阅什么是代码替换? (Simulink Coder)和代码替换库 (Simulink Coder)。有关开发自定义代码替换库的信息,请参阅什么是代码替换自定义? (Embedded Coder)和Code You Can Replace From Simulink Models (Embedded Coder)。
调用自定义 C 代码函数
您可以在 Stateflow 图中创建自定义 C 函数,并将其用于仿真和代码生成。调用自定义函数时:
写入函数名称,后跟括号中的参量。
以可选的分号结束函数调用。
使用单引号将参数传递给用户编写的函数。
对文本字符串使用双引号。
C 函数可以返回任何数据类型。有关详细信息,请参阅Configure Custom Code。当您编写访问输入向量的 C 函数时:
使用
sizeof函数来确定输入向量的长度。例如,您的自定义函数可以包含使用
sizeof的for循环,输入:for(i=0; i < sizeof(input); i++) { ...... }如果您的自定义函数多次使用输入向量长度的值,请在函数中包含指定输入向量长度的输入参数。
例如,您可以使用
input_length作为sum函数的第二个输入,如下所示:int sum(double *input, double input_length)
要在
sum函数中包含遍历输入向量的所有元素的for循环,输入:for(i=0; i < input_length; i++) { ...... }
在转移动作中使用函数调用
此图在转移动作中使用 C 函数调用。

如果以下条件成立,则使用 arg1、arg2 和 arg3 对 fcn1 进行函数调用:
S1被激活。发生事件
e。条件
c为 true。转移目标
S2有效。
此外,从 S2 到 S3 的转移中的转移动作显示了嵌套在另一个函数调用中的函数调用示例。
在状态动作中使用函数调用
下图在状态动作中使用函数调用。

当图执行时:
发生到
S1的默认转移,S1被激活。执行
entry动作,它使用指定参量对fcn1进行函数调用。在仿真时间经过 5 秒后,
S1变为非激活,S2被激活。执行
during动作,它使用指定参量对fcn2进行函数调用。在仿真时间经过 10 秒后,
S2变为非激活,S1再次被激活。在仿真结束之前,重复步骤 2 到 5。
按引用传递参量
图动作可以按引用(而不是按值)将参量传递给用户编写的函数。例如,动作可以包含函数调用:
f(&x);
其中 f 是自定义代码 C 函数,它需要指向 x 的指针作为参量。
如果 x 是 Stateflow 层次结构中数据项的名称,则适用以下规则:
不要使用指针传递从 Simulink® 模型输入的数据项。
如果您需要按引用传递某输入项(例如数组),请将该项分配给一个局部数据项并按引用传递该局部数据项。
如果
x的数据类型为boolean,则您必须关闭模型配置参数使用位集来存储状态配置。如果
x是数组且第一个索引属性为 0,则必须使用f(&(x[0]));调用该函数。此语法会将x的第一个元素的指针传递给函数。请参阅设置数据属性。如果
x是数组且第一个索引属性为非零数字,则必须使用f(&(x[1]))调用该函数。此语法会将x的第一个元素的指针传递给函数。