中国汽车工程师之家--聚集了汽车行业80%专业人士 

论坛口号:知无不言,言无不尽!QQ:542334618 

本站手机访问:直接在浏览器中输入本站域名即可 

  • 522查看
  • 0回复

[Simulink] MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程

[复制链接]


该用户从未签到

发表于 2-3-2024 09:09:36 | 显示全部楼层 |阅读模式

汽车零部件采购、销售通信录       填写你的培训需求,我们帮你找      招募汽车专业培训老师


全文约3000字,你将看到以下内容:


    生成代码的结构

    模型到代码的生成的流程

    结束语
autoMBD最近发布了《autoMBD原创技术文章合集》
合集包含156页丰富的MBD入门基础和MBDT硬件支持包的使用还包含基于MBD的电机控制算法开源项目——AMBD-MC合集配备了丰富的视频讲解
和大量的模型、文档和软件资源

如何获取请参考@所有读者:autoMBD发布《autoMBD原创技术文章合集》。

本篇文章继续介绍Simulink生成代码相关的内容,之前的内容可查看往期文章(点击可以直接跳转):

    MBD的Simulink使用技巧①:Simulink代码生成的基本概念MBD的Simulink使用技巧②:详解代码生成中的模型与代码
    MBD的Simulink使用技巧③:虚拟子系统与原子子系统的代码生成


阅前提示:本篇文章使用到的PI控制器示例模型,可以在autoMBD资源库的“临时资源分享”文件夹中找到该模型(资源序号tA22)。资源库链接的获取可以在《autoMBD原创技术文章合集》中找到(见文章开头)。

1  生成代码的结构

先复习一下,在《MBD的Simulink使用技巧②:详解代码生成中的模型与代码》中提到,一般情况下(默认配置且模型不复杂),生成的代码包含以下七个文件:


    ert_main.c模型名.c模型名.h模型名_private.h模型名_types.hrtwtypes.h
    模型名_data.c(开启Parameters可调会生成)

这么多的文件中,算法模型的核心应用代码是在“模型名.c”中实现的,其他文件更多的是实现数据结构定义、数据类型定义、变量声明、函数声明等功能。关于模型中的数据与代码中的数据定义、声明之间的详细对应关系,可以查看《MBD的Simulink使用技巧②:详解代码生成中的模型与代码》。

模型生成的应用代码,其结构由三部分组成,这三部分代码也被称为模型入口函数(Model Entry-Point Functions),具体如下:


    模型初始化函数

    模型Step函数
    模型终止函数

以示例PI控制器示例模型(资源序号tA22)为例,它生成的入口函数如下所示:

/* 模型入口函数(Model Entry-Point Functions)声明 生成于“模型名.h”*//* Model entry point functions */externvoidautoMBD_example_PI_noSubs_initialize(void);externvoidautoMBD_example_PI_noSubs_step(void);externvoidautoMBD_example_PI_noSubs_terminate(void);1.1 模型初始化函数顾名思义,模型初始化函数是用来初始化模型中的数据的,大多数情况下指的是状态变量的初始化。初始化函数在调用Step函数之前调用一次,以完数据的初始化。如果没有数据需要初始化,则可以不调用。打开PI控制器示例模型,如下所示。该模型中的离散积分模块包含状态变量,是需要初始化的。
MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程w1.jpg

PI控制器:离散积分模块包含状态变量 - From autoMBD
点击“Generate Code”生成代码,查看初始化函数:/* 默认情况:模型初始化函数 生成于“模型名.c” *//* Model initialize function */void autoMBD_example_PI_noSubs_initialize(void){/* (no initialization code required) */}但是为什么没有任何变量初始化的内容呢?这是因为离散积分模块的状态变量,初始值默认设置为“零”。默认情况下,初始值为零的变量初始化不会生成初始化代码。这里我们修改离散积分器的初始值为100,如下图所示:
MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程w2.jpg

修改离散积分器的初始值为100 - From autoMBD
重新生成代码,可以看到离散积分器的状态变量的初始化已经有了,如下所示:
/* 有非零变量初始化:模型初始化函数 生成于“模型名.c” *//* Model initialize function */voidautoMBD_example_PI_noSubs_initialize(void){/* InitializeConditions for DiscreteIntegrator: '<Root>/Discrete-Time Integrator' */  autoMBD_example_PI_noSubs_DW.DiscreteTimeIntegrator_DSTATE = 100.0;}
当然,用户也可以通过修改配置,关闭零初始值变量的优化选项,让初始值为零的数据初始化也生成代码,修改配置的方法如下所示:

MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程w3.jpg

不勾选零初始化数据优化选项 - From autoMBD

再重新生成代码,新的初始化函数如下所示:
/* 不开启零初始化优化选项:模型初始化函数 生成于“模型名.c” *//* Model initialize function */voidautoMBD_example_PI_noSubs_initialize(void){/* Registration code */
/* initialize error status */  rtmSetErrorStatus(autoMBD_example_PI_noSubs_M, (NULL));
/* states (dwork) */  (void) memset((void *)&autoMBD_example_PI_noSubs_DW, 0,sizeof(DW_autoMBD_example_PI_noSubs_T));
/* external inputs */  (void)memset(&autoMBD_example_PI_noSubs_U, 0, sizeof               (ExtU_autoMBD_example_PI_noSub_T));
/* external outputs */  autoMBD_example_PI_noSubs_Y.PI_Ctrl = 0.0;
/* InitializeConditions for DiscreteIntegrator: '<Root>/Discrete-Time Integrator' */  autoMBD_example_PI_noSubs_DW.DiscreteTimeIntegrator_DSTATE = 100.0;}可以看到初始化函数多了很多内容,所有零初始值变量和非零初始值变量都被保留了下来。并且对于特殊结构体的变量初始化,使用的是C的标准库函数memset()实现的。不过不建议关闭零初始值变量的优化选项,一般变量的内存区域初始值已经为零,不需要再初始化,关闭该优化选项会降低代码的执行效率。
1.2 模型Step函数
Step函数即模型本身,Step函数实现模型算法的一个步长运算。由于嵌入式系统一般是实时系统,且步长固定,所以Step函数要放在一个周期中断ISR里,被周期性的调用运算。

调用Step函数的周期中断ISR要满足以下两点:


    周期中断ISR的步长要和模型中设置的步长保存一致;
    在一个周期内,必须保证所有的运算任务能够完成。

Step函数和模型的运算功能是完全相同的,读者可以自行查看PI控制器示例模型生成的Step函数,与PI控制器模型做对比,了解它是如何实现模型的运算过程的。

Tips:用户完全不用担心生成的代码功能和模型不一致,把Step函数当作模型本身即可。

在ert_main.c的注释中,详细介绍了Step函数的使用方法,大多数开发者可能不太习惯阅读注释,但ert_main.c中的注释值得详细阅读。ert_main.c中关于Step函数的代码,如下所示:
/* 详细阅读注释 了解Step函数的使用方法 *//* * Associating rt_OneStep with a real-time clock or interrupt service routine * is what makes the generated code "real-time".  The function rt_OneStep is * always associated with the base rate of the model.  Subrates are managed * by the base rate from inside the generated code.  Enabling/disabling * interrupts and floating point context switches are target specific.  This * example code indicates where these should take place relative to executing * the generated code step function.  Overrun behavior should be tailored to * your application needs.  This example simply sets an error status in the * real-time model and returns from rt_OneStep. */voidrt_OneStep(void);voidrt_OneStep(void){static boolean_T OverrunFlag = false;
/* Disable interrupts here */
/* Check for overrun */if (OverrunFlag) {    rtmSetErrorStatus(autoMBD_example_PI_noSubs_M, "Overrun");return;  }
  OverrunFlag = true;
/* Save FPU context here (if necessary) *//* Re-enable timer or interrupt here *//* Set model inputs here */
/* Step the model */  autoMBD_example_PI_noSubs_step();
/* Get model outputs here */
/* Indicate task complete */  OverrunFlag = false;
/* Disable interrupts here *//* Restore FPU context here (if necessary) *//* Enable interrupts here */}
/* Attach rt_OneStep to a timer or interrupt service routine with * period 0.001 seconds (the model's base sample time) here.  The * call syntax for rt_OneStep is * *  rt_OneStep(); */ert_main.c中给出是Step函数的一种使用示范,它将Step函数进行了一层封装形成rt_OneStep()函数,添加了错误状态检查功能。用户可以参考它,也可以不参考,直接使用Step函数。
在《autoMBD原创技术文章合集》的《第十七篇 把模型嵌入代码》中,详细展示了如何在自己的代码中集成Step函数。获取文章合集的方法见文章开头。

1.3 模型终止函数

模型终止函数在完全退出Step函数后,调用一次。但终止函数在绝大多数情况下都是空的,如下所示:
/* 默认终止函数 生成于“模型名.c”*//* Model terminate function */voidautoMBD_example_PI_noSubs_terminate(void){/* (no terminate code required) */}用户也可以在终止函数中添加自定义执行代码,方法如下所示:

MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程w4.jpg

在终止函数中添加自定义执行代码 - From autoMBD
新生成的终止函数如下所示:/* 添加自定义终止函数执行内容 *//* Model terminate function */voidautoMBD_example_PI_noSubs_terminate(void){/* user code (Terminate function Body) */
/* Just a test */double temp = 0;  temp++;}
2  模型到代码的生成的流程
当用户点击”Generate Code“之后,模型是怎么一步一步变成C代码的呢?这里将对这一过程进行一个简单的介绍。

从模型到代码的生成过程,可以用下面的流程图表示:

MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程w5.jpg

模型到代码生成流程 - From autoMBD

从上图可以看到,模型生成代码可以分为三个阶段:


    模型编译

    代码生成
    可执行文件生成(非必须)

2.1 模型编译

模型编译的输入即为模型本身,通过一个代码生成翻译器(Code generation interpreter),对模型中的模块、信号、参数、Stateflow等进行检查,输出一个后缀名为rtw的文件:模型.rtw。

该文件是一个中间文件,独立于编程语言,描述了相应模型文件中的模块、输入、输出、参数、状态、存储以及其他模型组件和属性。是目标语言编译器(Target Language Compiler,TLC)的输入。

在默认情况下,该rtw文件会在生成代码后被自动清除,但也可以修改配置使其保留下来,方法如下:

MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程w6.jpg

修改配置保留rtw文件 - From autoMBD

修改配置后,在模型同级目录的“模型名_ert_rtw”文件夹内,可以找到该文件:

MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程w7.jpg

生成的rtw文件 - From autoMBD

读者可以尝试阅读该文件,了解该文件的结构和内容。该文件具体的语法规则,可以在MATLAB帮助文档中搜索关键词“rtw”,阅读相关的说明文档,这里不再深入介绍。

2.2 代码生成

上一阶段生成的rtw文件,作为系统目标文件(即ert.tlc脚本,在《MBD的Simulink使用技巧①:Simulink代码生成的基本概念》中介绍了它的作用)的输入文件,通过TLC编译器,以及Simulink内置的TLC函数库,将该rtw文件中的所有信息逐个编译成目标语言(C语言)程序,输出生成的代码。

换句话说,TLC编译器执行的是ert.tlc脚本,该脚本的输入为rtw文件,输出为生成的C代码。

特别提示一点,除了系统目标文件的ert.tlc脚本,有的模块还有自己的模块tlc脚本。系统目标文件描述的是整个模型如何生成代码,用户一般不能修改该文件,而模块自己的tlc脚本则描述了该模块如何生成代码。

所以,要创建一个自己的模块,并且能在Simulink中自动生成代码,学习TLC是必不可少的。由于目前我对TLC掌握的很少,这里不再深入介绍TLC,将来有机会再单独开一个系列详细介绍TLC。

2.3 可执行文件生成

该阶段是一个可选项,不是必须的步骤。该阶段即对生成的C代码进行编译,生成可执行文件,或者二进制文件。该过程也可以由用户来定义,从而适配不同的编译器、调试器。

由于MATLAB并不是IDE,它的代码调试功能很弱,所以生成的可执行文件一般只有下载的功能,这里不做进一步介绍。

3  结束语

为了收集读者对《autoMBD原创技术文章合集》的反馈,特地举行反馈征集活动。在8月31日之前,所有读者可以向作者反馈阅读和使用《autoMBD原创技术文章合集》的好评、差评、想法、感受或建议,参与到活动中。

反馈征集活动的规则如下:


    所以读者可以私信autoMBD作者,获取《autoMBD原创技术文章合集》全文;
    即日起,到2022-08-31为止,读者可以通过autoMBD的账号(知乎账号或微信公众号任选其一),向autoMBD作者反馈关于《文章合集》的阅读和使用的想法、感受和建议,反馈的内容不限,长度不限;每一位参与反馈的读者,都可以获得免费获得无水印的《autoMBD原创技术文章合集》,无需赞赏;
    在活动结束的三日内,将从反馈信息大于30字的读者中,随机抽取一位读者(随机抽取的过程录制视频并公开),赠送价值99元的米家保温杯弹盖版。

特别提示,最终奖品米家保温杯弹盖版是MATLAB的纪念版。是我上次参加MATLAB  EXPO活动时,由MathWorks官方赠送的,瓶身刻有MathWorks的Logo。

米家保温杯弹盖版的官图如下所示:

MBD的Simulink使用技巧④:详解生成代码的结构与代码的生成流程w8.jpg
希望读者能踊跃参与,给予我有价值的反馈信息,与我一同改进和提高《autoMBD原创技术文章合集》的质量。


该用户从未签到

发表于 15-3-2025 05:12:03 | 显示全部楼层
关于Simulink生成代码的结构与生成流程,我将从汽车工程师的角度为您进行专业解答。Simulink生成的代码结构清晰,主要包括初始化模块、主循环模块以及中断服务模块等。生成代码的流程包括模型建立、参数配置、代码生成器设置及代码生成等步骤。关于MBD技术文章合集,内容详尽,包括MBD入门基础、硬件支持包使用等,且配备了视频讲解和丰富的资源。如需获取此合集,建议访问autoMBD官方网站或相关渠道获取详细信息。更多Simulink使用技巧,如之前的文章内容,可以在官方文档或专业论坛中查看往期文章进行学习。希望这些信息对您的学习和工作有所帮助。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 15-3-2025 05:12:03 | 显示全部楼层
针对您的帖子,以下为汽车工程师专业的回复:

关于Simulink中MBD的生成代码结构与流程,内容详实且专业。生成代码的结构通常包括初始化模块、主循环、中断服务及配置参数等部分。模型到代码的生成流程,一般涉及模型建立、配置设置、代码生成器调用及优化等步骤。结束语方面,随着MBD技术的深入应用,其在汽车领域的作用愈发重要。关于《autoMBD原创技术文章合集》,对于想要深入了解MBD技术的读者来说,无疑是一份宝贵的资源。获取方式建议查阅官方渠道或关注相关社交媒体账号。本篇文章将继续介绍Simulink生成代码相关内容,若需了解往期内容,可查阅系列文章的往期内容。希望以上信息对您有所帮助。

以上回复遵循了汽车工程师的专业风格和要求,供参考。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 15-3-2025 05:12:03 | 显示全部楼层
关于Simulink生成代码的结构与生成流程,我作为一名汽车工程师对MBD技术有一定了解,对此给出以下专业回复:

一、生成代码的结构:Simulink生成的代码结构清晰,主要包括模型文件、参数配置、算法实现等部分。代码以模块化方式组织,易于阅读和维护。

二、模型到代码的生成流程:首先,根据汽车系统的需求建立Simulink模型;其次,通过Simulink代码生成器将模型转换为可执行的代码;最后,对生成的代码进行调试和优化。在此过程中,应关注参数配置和算法实现的选择,以确保生成的代码满足实际需求。

关于《autoMBD原创技术文章合集》,此合集内容丰富,涵盖了MBD技术的多个方面。获取方式可参见文中提到的途径。往期文章同样值得一读,可点击查阅。如需深入了解Simulink生成代码相关内容,建议阅读本合集及其他相关资料,结合实践加深理解。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 15-3-2025 05:12:03 | 显示全部楼层
以下是一位汽车工程师对帖子内容的回复:

针对Simulink的MBD模型生成代码,以下内容简要概述其核心结构和生成流程:

一、生成代码的结构:Simulink生成的代码结构清晰,主要包括模型初始化代码、主循环代码、中断服务函数等部分。这些代码模块化的设计便于理解和维护。

二、模型到代码的生成流程:在Simulink环境中建立MBD模型后,通过配置参数和选项,可以自动将模型转化为C或C++代码。流程主要包括模型准备、配置代码生成器、生成代码及优化等步骤。

关于autoMBD发布的《autoMBD原创技术文章合集》,其内容详尽,包含MBD入门基础、硬件支持包使用以及基于MBD的电机控制算法开源项目等。通过丰富的视频讲解、模型和文档资源,为使用者提供了全面的学习和实践机会。获取方式可参见帖子中的提示。

继续深入了解Simulink生成代码相关内容,建议查阅往期文章以获取更全面的知识。

以上回复供参考,由于篇幅所限,具体细节和案例可进一步探讨。
回复 支持 反对

使用道具 举报



该用户从未签到

发表于 15-3-2025 05:12:02 | 显示全部楼层
根据您的要求,针对上述帖子内容,我以汽车工程师及专业文风回复如下:

关于Simulink中MBD的生成代码相关介绍:

一、生成代码的结构:
在Simulink中,基于MBD(Model-Based Design)生成的代码结构清晰,层次分明。通常包括模型初始化、系统定义、算法执行及错误处理等模块。代码重视可读性和可维护性,便于后期修改和拓展。

二、模型到代码的生成流程:
1. 构建模型:在Simulink中建立符合需求的系统模型。
2. 配置参数:根据实际需求配置模型参数。
3. 代码生成:利用Simulink的自动生成代码功能,将模型转化为代码。
4. 验证与优化:对生成的代码进行验证与优化,确保性能满足要求。

关于《autoMBD原创技术文章合集》:该合集内容丰富,涵盖了MBD的入门基础、硬件支持包的使用以及基于MBD的电机控制算法开源项目等。配备了视频讲解、模型、文档和软件资源,是学习和实践MBD技术的宝贵资源。

如欲获取该合集,请参照提供的链接或联系方式。

本篇文章将继续深入探讨Simulink生成代码的内容,欢迎查阅往期文章以作参考。
回复 支持 反对

使用道具 举报


  • TA的每日心情
    无聊
    1-7-2015 18:46
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 15-3-2025 05:12:03 | 显示全部楼层
    好的,针对您提供的帖子内容,作为一名汽车工程师和Simulink使用者,我将以专业的角度回复如下:

    关于Simulink中MBD生成代码的结构与生成流程:

    一、生成代码的结构:Simulink生成的代码通常具有良好的结构化设计,遵循模块化思想,包括主函数、子函数、中断服务等。代码注释详尽,易于理解。

    二、模型到代码的生成流程:在Simulink中建立模型后,通过配置参数,选择适当的代码生成器,生成C或C++代码。这个过程需要设定一些参数如数据类型、算法优化等,以得到适应实际需求的代码。

    关于《autoMBD原创技术文章合集》:此合集内容丰富,涵盖了MBD的入门基础、硬件支持包的使用等,是学习和实践MBD的宝贵资源。获取方式可参见帖子中的提示。

    本篇文章将详细解析Simulink生成代码的结构和流程,建议读者关注并深入学习。往期文章也包含了大量有价值的信息,可点击链接查看。

    以上回复,供您参考。如有更多问题,欢迎交流。
    回复 支持 反对

    使用道具 举报

    快速发帖

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    QQ|手机版|小黑屋|Archiver|汽车工程师之家 ( 渝ICP备18012993号-1 )

    GMT+8, 14-7-2025 11:54 , Processed in 0.744571 second(s), 39 queries .

    Powered by Discuz! X3.5

    © 2001-2013 Comsenz Inc.