Main Content

本页翻译不是最新的。点击此处可查看最新英文版本。

在 C 语言状态图中调用 C 库函数

Simulink® 模型中的 Stateflow® 图具有一个动作语言属性,该属性定义状态和转移动作的语法。图的画布左下角的图标表示该图的动作语言。

  • MATLAB® 作为动作语言。

  • C 语言作为动作语言。

调用 C 库函数

您可以调用 C 数学库函数的以下子集:

abs* **

acos**

asin**

atan**

atan2**

ceil**

cos**

cosh**

exp**

fabs

floor**

fmod**

labs

ldexp**

log**

log10**

pow**

rand

sin**

sinh**

sqrt**

tan**

tanh**

 

* Stateflow abs 函数有自己的内置功能,超越了与其相当的标准 C 函数的功能。有关详细信息,请参阅调用 abs 函数

** 您也可以将对 C 数学库的调用替换为该函数子集的应用程序特定实现。有关详细信息,请参阅用应用程序实现替换数学库函数

当您调用这些函数时,除非所有输入参量都显式设置为单精度,否则应用双精度。当发生类型不匹配时,会将输入参量强制转换为预期类型以替换原始参量。例如,如果使用整数参量调用 sin 函数,则将输入参量强制转换为类型 double 的浮点数以替换原始参量。

注意

由于 C 库函数的输入参量首先转换为浮点数,因此具有类型为 int64uint64 的参量的函数调用会导致精度损失。

如果您调用上面未列出的其他 C 库函数,请打开“配置参数”对话框,并在仿真目标窗格中输入适当的 #include 语句,如 Configure Custom Code 中所述。

调用 abs 函数

对 Stateflow abs 函数的解释超出了标准 C 版本,包含所有类型的整数和浮点参量,如下所示:

  • 如果 xint32int64 类型的整数,则标准 C 函数 abs 应用于 x,即 abs(x)

  • 如果 xint16int8 类型的整数,则将标准 C abs 函数应用于转换为 int32 类型整数的 x,即 abs((int32)x)

  • 如果 xdouble 类型的浮点数,则将标准 C 函数 fabs 应用于 x,即 fabs(x)

  • 如果 xsingle 类型的浮点数,则将标准 C 函数 fabs 应用于转换为 double 类型的 x,即 fabs((double)x)

  • 如果 x 是定点数,则将标准 C 函数 fabs 应用于转换为 double 类型的定点数,即 fabs((double) Vx),其中 Vxx 的实际值。

如果您要使用严格意义上的标准 C abs 函数,则将其参量或返回值转换为整数类型。请参阅类型转换运算

注意

如果您在自定义代码中声明 x,则在所有情况下都将应用标准 C abs 函数。有关将自定义代码插入图中的说明,请参阅Reuse Custom Code in Stateflow Charts

调用 min 和 max 函数

您可以通过在生成的代码顶部自动发出以下宏来调用 minmax

#define min(x1,x2) ((x1) > (x2) ? (x2):(x1))
#define max(x1,x2) ((x1) > (x2) ? (x1):(x2))

为了与名为 min()max() 的用户图形函数保持兼容性,生成的代码使用以下格式的改造名称:<prefix>_min。但是,如果将 min()max() 图形函数导出到模型中的其他图,则这些函数的名称将不再以生成的代码中的改造名称发出,因而会发生冲突。为避免这种冲突,请重命名 min()max() 图形函数。

用应用程序实现替换数学库函数

您可以对代码生成器进行配置,以更改它为数学库函数生成的代码,使之符合应用程序的要求。要执行此操作,请将代码生成器配置为在代码生成期间应用代码替换库 (CRL)。如果您有 Embedded Coder® 许可证,则可以开发并应用自定义代码替换库。

有关使用 MathWorks® 提供的代码替换库替换代码的详细信息,请参阅什么是代码替换? (Simulink Coder)代码替换库 (Simulink Coder)。有关开发自定义代码替换库的信息,请参阅What Is Code Replacement Customization? (Embedded Coder)Code You Can Replace From Simulink Models (Embedded Coder)

调用自定义 C 代码函数

您可以指定用于 C 语言状态图的自定义代码函数以进行仿真和 C 代码生成。有关详细信息,请参阅Configure Custom Code

在图中调用自定义 C 函数的指导原则

  • 使用名称、任意参量(置于括号内)以及分号(可选)来定义函数。

  • 使用单引号将参数传递给用户编写的函数。例如 func('string')

  • 一个动作中可以嵌套多个函数调用。

  • 动作可以调用返回标量值的函数(对于 MATLAB 函数,为 double 类型;对于用户编写的 C 函数,为任何类型)。

编写访问输入向量的自定义 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++) {
    ......
    }

转移动作中的函数调用

下图显示了使用转移动作表示法的函数调用的示例格式。

Chart that contains transition actions with calls to custom code functions fcn1 and fcn2.

如果以下条件成立,则使用 arg1arg2arg3fcn1 进行函数调用:

  • S1 被激活。

  • 发生事件 e

  • 条件 c 为 true。

  • 转移目标 S2 有效。

S2S3 的转移中的转移动作显示了嵌套在另一个函数调用中的函数调用。

状态动作中的函数调用

下图显示了使用状态动作表示法的函数调用的示例格式。

Chart that contains state actions with calls to custom code functions fcn1 and fcn2.

该图的执行过程如下所示:

  1. 当到 S1 的默认转移发生时,S1 被激活。

  2. 执行 entry 动作,使用指定参量对 fcn1 进行函数调用。

  3. 在仿真时间经过 5 秒后,S1 变为非激活,S2 被激活。

  4. 执行 during 动作,使用指定参量对 fcn2 进行函数调用。

  5. 在仿真时间经过 10 秒后,S2 变为非激活,S1 再次被激活。

  6. 在仿真结束之前,重复步骤 2 到 5。

按引用传递参量

Stateflow 动作可以按引用(而不是按值)将参量传递给用户编写的函数。特别是,动作可以传递指向值的指针而不是值本身。例如,动作可能包含以下调用:

f(&x);

其中 f 是自定义代码 C 函数,它需要指向 x 的指针作为参量。

如果 x 是在 Stateflow 层次结构中定义的数据项的名称,则适用以下规则:

  • 不要使用指针传递从 Simulink 模型输入的数据项。

    如果您需要按引用传递某输入项(例如数组),请将该项分配给一个局部数据项并按引用传递该局部数据项。

  • 如果 x 的数据类型为 boolean,则您必须关闭代码生成器选项 使用位集来存储状态配置

  • 如果 x 是数组且其第一个索引属性设置为 0(请参阅设置数据属性),则必须按如下所示调用函数。

    f(&(x[0]));

    这会将 x 的第一个元素的指针传递给函数。

  • 如果 x 是数组且其第一个索引属性设置为非零数字(例如 1),则必须按以下方式调用函数:

    f(&(x[1]));

    这会将 x 的第一个元素的指针传递给函数。