生成代码是基于模型设计的重要环节。在工作中经常需要手动生成一下代码来验证一些简单的问题,譬如想知道某种配置或者某种模型会生成什么形式的代码。

本文会结合一个简单的模型,描述生成嵌入式代码的最简配置流程。同时简要分析在Simulink默认配置下所生成的代码。

不同版本的Matlab生成的代码可能有少许区别,本文基于Matlab2018a环境。



文章目录

  • 1 创建模型
  • 2 代码生成配置
  • 3 代码分析
  • 3.1 *ert_main.c*
  • 3.2 *demo.h*
  • 3.3 *demo.c*
  • 3.3.1 注释
  • 3.3.2 变量定义
  • 3.3.3 step函数
  • 3.3.4 初始化函数
  • 3.4 可执行文件
  • 4 总结



1 创建模型

首先打开Simulink,随意创建一个简单的模型,如下图。

simulink怎么使用python代码 simulink 代码_matlab


一般控制策略的模型都会包括输入输出端口和内部的控制逻辑。这里建立的控制逻辑比较简单,只是把输入信号放大两倍再输出,在C代码中对应的就是简单的乘以2。

除此以外先不用对模块进行配置,观察在默认配置下,生成的代码是什么形式。

2 代码生成配置

1.Ctrl+E打开模型的配置窗口

simulink怎么使用python代码 simulink 代码_开发语言_02


2.点击左侧的Solver,右侧Type选为Fixed-step,Solver选为discrete。这是因为必须是离散的求解器才能用Embedded Coder生成代码。

simulink怎么使用python代码 simulink 代码_Simulink_03


3.点击左侧的Code Generation,把System target file选为Embedded Coder。这么配置是告诉Simulink要生成生成嵌入式C代码。

simulink怎么使用python代码 simulink 代码_matlab_04


4.点击Report,勾选Create code generation report和Open report automatically。这样,在生成完毕代码后会自动打开报告。最后点击OK即可完成配置。

simulink怎么使用python代码 simulink 代码_matlab_05


5.Ctrl+B生成代码,会在Matlab当前工作路径下生成。代码生成完毕后自动弹出如下报告,可以通过点击左侧的目录或者c文件/头文件名,查看代码。

simulink怎么使用python代码 simulink 代码_输入输出_06

3 代码分析

3.1 ert_main.c

首先,会生成一个ert_main.c的C文件。该文件含有一个主函数,调用模型的初始化函数和step函数。

simulink怎么使用python代码 simulink 代码_Simulink_07


这个主函数其实完全没有必要,因为项目团队中一般会为底层配置好操作系统和任务调度,而不需要用Simulink生成。可以通过配置Simulink不生成这个主函数,以减少生成代码所用的时间。

simulink怎么使用python代码 simulink 代码_输入输出_08

3.2 demo.h

头文件中首先是宏定义。然后通过结构体定义了输入输出变量类型,以及声明模型的初始化函数,step函数等。

simulink怎么使用python代码 simulink 代码_初始化_09


如果对输入输出的信号线进行Code Generation配置,定义好它们的Storage Class,那么输入输出信号生成代码的形式就不一定是图中的结构体,而是自定义的接口形式。

3.3 demo.c

Embedded Coder生成的C文件十分重要,它和Simulink模型中的算法紧密相关。下面详细描述C文件的内容。

3.3.1 注释

代码中默认生成了大量的注释,可以很好的帮助我们读懂代码各个部分的作用,或者关联到模型中对应的模块。

simulink怎么使用python代码 simulink 代码_开发语言_10


注释的生成也可以在Simulink自定义配置。

simulink怎么使用python代码 simulink 代码_开发语言_11

3.3.2 变量定义

接下来会定义变量,对应着模型最外层的输入输出模块。由于输入输出没有经过任何特殊配置,生成代码的时候就会按照默认的结构体的方式定义。

simulink怎么使用python代码 simulink 代码_Simulink_12


后续会研究如何配置输入输出以适应软件集成的需求。

3.3.3 step函数

step函数反映了模型的策略,完全和模型相对应。通常如果想验证某种模型生成代码的样子,只要通过查看step函数的内容即可。

simulink怎么使用python代码 simulink 代码_Simulink_13


后续研究代码生成的博客将主要分析step函数的内容。

3.3.4 初始化函数

初始化函数中包含了变量初始化和错误状态监测函数。

simulink怎么使用python代码 simulink 代码_输入输出_14


关于零初始化,可以通过勾选Data Initialization中的Remove root level I/O zero initialization取消生成。

simulink怎么使用python代码 simulink 代码_开发语言_15


关于这个rtmSetErrorStatus函数,其实没什么用处。可以通过勾选Remove error status field in real-time model data structure不生成它。

simulink怎么使用python代码 simulink 代码_matlab_16

3.4 可执行文件

Code Generation过程不仅仅生成了C文件和头文件,还“顺便”执行了一下makefile,把代码编译成了可执行文件。

simulink怎么使用python代码 simulink 代码_输入输出_17


其实并不需要做这一步,因为所有模块生成代码后会和底层软件、手写代码等一起集成,多了这么一步反而会花费更多时间生成代码。通过勾选Generate code only可以不编译。

simulink怎么使用python代码 simulink 代码_输入输出_18

4 总结

本文只是通过简单的配置来生成代码样例,这样的代码完全没法拿去和其他代码集成编译软件,还需要更多的配置才行。后面会在此基础上,讨论更多的代码生成配置,包括如何和底层代码交互,如何生成适合某个硬件的代码,如何优化代码等。

>>返回个人博客总目录



生成代码是基于模型设计的重要环节。在工作中经常需要手动生成一下代码来验证一些简单的问题,譬如想知道某种配置或者某种模型会生成什么形式的代码。

本文会结合一个简单的模型,描述生成嵌入式代码的最简配置流程。同时简要分析在Simulink默认配置下所生成的代码。

不同版本的Matlab生成的代码可能有少许区别,本文基于Matlab2018a环境。


文章目录

  • 1 创建模型
  • 2 代码生成配置
  • 3 代码分析
  • 3.1 *ert_main.c*
  • 3.2 *demo.h*
  • 3.3 *demo.c*
  • 3.3.1 注释
  • 3.3.2 变量定义
  • 3.3.3 step函数
  • 3.3.4 初始化函数
  • 3.4 可执行文件
  • 4 总结


1 创建模型

首先打开Simulink,随意创建一个简单的模型,如下图。

simulink怎么使用python代码 simulink 代码_matlab


一般控制策略的模型都会包括输入输出端口和内部的控制逻辑。这里建立的控制逻辑比较简单,只是把输入信号放大两倍再输出,在C代码中对应的就是简单的乘以2。

除此以外先不用对模块进行配置,观察在默认配置下,生成的代码是什么形式。

2 代码生成配置

1.Ctrl+E打开模型的配置窗口

simulink怎么使用python代码 simulink 代码_开发语言_02


2.点击左侧的Solver,右侧Type选为Fixed-step,Solver选为discrete。这是因为必须是离散的求解器才能用Embedded Coder生成代码。

simulink怎么使用python代码 simulink 代码_Simulink_03


3.点击左侧的Code Generation,把System target file选为Embedded Coder。这么配置是告诉Simulink要生成生成嵌入式C代码。

simulink怎么使用python代码 simulink 代码_matlab_04


4.点击Report,勾选Create code generation report和Open report automatically。这样,在生成完毕代码后会自动打开报告。最后点击OK即可完成配置。

simulink怎么使用python代码 simulink 代码_matlab_05


5.Ctrl+B生成代码,会在Matlab当前工作路径下生成。代码生成完毕后自动弹出如下报告,可以通过点击左侧的目录或者c文件/头文件名,查看代码。

simulink怎么使用python代码 simulink 代码_输入输出_06

3 代码分析

3.1 ert_main.c

首先,会生成一个ert_main.c的C文件。该文件含有一个主函数,调用模型的初始化函数和step函数。

simulink怎么使用python代码 simulink 代码_Simulink_07


这个主函数其实完全没有必要,因为项目团队中一般会为底层配置好操作系统和任务调度,而不需要用Simulink生成。可以通过配置Simulink不生成这个主函数,以减少生成代码所用的时间。

simulink怎么使用python代码 simulink 代码_输入输出_08

3.2 demo.h

头文件中首先是宏定义。然后通过结构体定义了输入输出变量类型,以及声明模型的初始化函数,step函数等。

simulink怎么使用python代码 simulink 代码_初始化_09


如果对输入输出的信号线进行Code Generation配置,定义好它们的Storage Class,那么输入输出信号生成代码的形式就不一定是图中的结构体,而是自定义的接口形式。

3.3 demo.c

Embedded Coder生成的C文件十分重要,它和Simulink模型中的算法紧密相关。下面详细描述C文件的内容。

3.3.1 注释

代码中默认生成了大量的注释,可以很好的帮助我们读懂代码各个部分的作用,或者关联到模型中对应的模块。

simulink怎么使用python代码 simulink 代码_开发语言_10


注释的生成也可以在Simulink自定义配置。

simulink怎么使用python代码 simulink 代码_开发语言_11

3.3.2 变量定义

接下来会定义变量,对应着模型最外层的输入输出模块。由于输入输出没有经过任何特殊配置,生成代码的时候就会按照默认的结构体的方式定义。

simulink怎么使用python代码 simulink 代码_Simulink_12


后续会研究如何配置输入输出以适应软件集成的需求。

3.3.3 step函数

step函数反映了模型的策略,完全和模型相对应。通常如果想验证某种模型生成代码的样子,只要通过查看step函数的内容即可。

simulink怎么使用python代码 simulink 代码_Simulink_13


后续研究代码生成的博客将主要分析step函数的内容。

3.3.4 初始化函数

初始化函数中包含了变量初始化和错误状态监测函数。

simulink怎么使用python代码 simulink 代码_输入输出_14


关于零初始化,可以通过勾选Data Initialization中的Remove root level I/O zero initialization取消生成。

simulink怎么使用python代码 simulink 代码_开发语言_15


关于这个rtmSetErrorStatus函数,其实没什么用处。可以通过勾选Remove error status field in real-time model data structure不生成它。

simulink怎么使用python代码 simulink 代码_matlab_16

3.4 可执行文件

Code Generation过程不仅仅生成了C文件和头文件,还“顺便”执行了一下makefile,把代码编译成了可执行文件。

simulink怎么使用python代码 simulink 代码_输入输出_17


其实并不需要做这一步,因为所有模块生成代码后会和底层软件、手写代码等一起集成,多了这么一步反而会花费更多时间生成代码。通过勾选Generate code only可以不编译。

simulink怎么使用python代码 simulink 代码_输入输出_18

4 总结

本文只是通过简单的配置来生成代码样例,这样的代码完全没法拿去和其他代码集成编译软件,还需要更多的配置才行。后面会在此基础上,讨论更多的代码生成配置,包括如何和底层代码交互,如何生成适合某个硬件的代码,如何优化代码等。