# 代码生成


代码生成功能是将控制策略模型生成 C 代码,C 代码的内容主要包括:

  • 初始化函数:用来初始化模型数据,在调用执行仿真步的函数前调用此函数;
  • 执行仿真步的函数:每调用一次则对模型执行一个仿真步的计算;
  • 全局变量的声明与定义:与数据字典中定义的变量相对应的 C 代码变量,具体规则见数据字典 > 面板功能介绍 > 存储类型;这些变量主要用来完成模型生成的 C 代码函数与用户其它函数间的数据交互功能;
  • main 函数:一个集成和调用模型生成的 C 代码的案例,仅作为参考。

在代码生成之前,用户可以通过进入代码生成 > 代码配置来设置需要生成的代码。

下面是代码配置页面的具体介绍。

# 代码平台

代码平台页签如图所示:

输出路径:此选项指定模型生成的 C 代码文件存放的目录,可直接将路径信息粘贴到编辑框,也可单击编辑框后的按钮选择相应的文件夹。Sysplorer 会在此目录下自动新建一个文件夹用以存放生成的代码文件,并添加数字后缀用于区分。

# 代码替换

代码替换页签如图所示:

代码替换页面提供用户自定义修改数据类型的“字符串”,以便适应用户代码编写的习惯或标准,其中也提供了不同的库函数标准。用户可以通过取消勾选替换类型选项,直接使用 Sysplorer 中提供的默认类型。

类型替换:勾选替换类型复选框会显示数据类型编辑框,您可在相应的数据类型名后的编辑框中输入自定义的别名,则在生成的嵌入式 C 代码中会包含用户指定的数据类型别名定义,代码中的变量类型也会使用此别名。

浮点数替换:目前支持 C99CMSIS-DSP 两种选择,前者使用 C 语言提供的通用数学函数库来生成嵌入式 C 代码,后者则使用 DSP 库中的相应函数来替换sincosatan2sqrt四个函数,若需要使用上述四个函数之外的数学函数,则软件会自动使用 C99 中的数学函数。

# 代码设计

代码设计页签如图所示:

代码设计页面为用户提供代码生成文件组织结构;在命名规范中此页面提供不同类型或变量字符串最大长度的设置来规范化生成的代码;在逻辑运算符中,提供逻辑运算与位运算两种方式。

文件组织: Sysplorer 为模型生成的嵌入式 C 代码包含多个文件,其中momain.c是一个集成模型 C 代码的案例,其余代码文件则是模型算法代码,文件组织Compact 选项与代码文件的对应关系如下表:

文件名 Compact
momodel.c 存放函数定义以及模型仿真过程所用的各类数据的声明与定义
momodel.h 存放用户定义的数据类型别名、所需的函数接口和全局变量的前置声明(需使用数据字典
modata.c
modata.h
momodel_block.h
momodel_extern_inc.h

命名规范:命名规范对模型生成的嵌入式 C 代码中的函数名、变量名、宏名等都有作用,其中最大长度限定了各名字的单词字符长度,命名规则目前暂不支持自定义,而命名风格可支持自定义,包括有camelCase(驼峰式)、PascalCase(帕斯卡尔式)、lower_snake_case(全小写下划线式)、UPPER_SNAKE_CASE(全大写下划线式)四种命名风格。

逻辑运算符:对于 Sysplorer 模型库中的逻辑运算模块,如果您在此处将逻辑运算选定为逻辑运算,则生成的嵌入式 C 代码中也会对应逻辑运算符(如“&&”等),如果您选择了位运算,则生成的嵌入式 C 代码中会生成位运算符(如“&”等)。具体关系对应表如下:

Sysblock中组件的逻辑运算功能 逻辑运算 位运算
&& &
|| |
~
与非 使用逻辑运算符组合 使用位运算符组合
或非 使用逻辑运算符组合 使用位运算符组合
异或 ^ ^
同或 使用逻辑运算符组合 使用位运算符组合

# 代码定制

代码定制页签如图所示:

代码保护:当您选择生成数据类型溢出保护代码时,生成的嵌入式 C 代码中会包含对整型运算结果数值的溢出判断,当超过上下限时直接以最大值(超上限)或最小值(超下限)为运算结果赋值;当您选择数据除零保护代码时,在 C 代码中进行除法运算前会首先判断除数(或称之为分母)是否为零,从而避免出现除零运算。

数据类型:当您选择float 以 32 位表示时,模型中所有的浮点数都会使用单精度浮点数,否则默认使用双精度浮点数(double)。

插入自定义代码:单击展开-请保证输入内容的正确性后会展开自定义代码编辑框,您可根据编辑框前的提示在相应的“段”前后插入自己的代码,则在生成的代码文件(包括头文件和源文件)相应的“段”前后都会添加您写入的代码。需要注意的是,Sysplorer 不对这些代码做任何检查,请您保证这些代码的正确性。

对于“段”,软件按功能将不同的 C 语言指令划分为七类,每类指令在代码文件中构成的一组代码行称之为一“段”,包括:“#include”指令段、宏定义段、“typedef”指令段(定义数据类型别名)、全局变量声明段、全局变量定义段、函数声明段、函数定义段。

# 代码优化

代码优化页签如图所示:

模型入口函数:您可在此处指定生成的用于初始化模型的 C 函数和执行模型仿真步函数的函数名,并选择是否在您指定的函数名前自动添加模型名作为前缀。

数组展开阈值:当模型中包含对数组的操作时,此数值控制是否用for循环结构来执行对数组的访问,当数组元素大于此数值时则使用for循环语句,否则对数组的每个元素的访问都使用单独的 C 代码语句。

生成代码:此下拉框指定模型生成 C 代码时所用的优化方法,当使用优先代码大小时,会尽量减小生成代码的大小,但运行效率可能会降低;而选择优先代码速度时,某些计算会被内联以减少函数的调用对运行效率的负面影响,但代码量可能会较大。

# 代码报告

代码报告页签如图所示:

生成代码报告:可在此处指定代码生成结束时是否在代码生成的文件夹中生成对应的报告。

# 代码生成结构

Sysblock 生成代码主要以头文件mosecmodel.h以及源文件mosecmodel.c两个文件呈现。

其中头文件mosecmodel.h中的结构如下。

源文件mosecmodel.c中的结构如下。