ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Simulink代码生成全流程:从仿真模型到嵌入式C代码落地实践

Simulink代码生成全流程:从仿真模型到嵌入式C代码落地实践 从“跑通仿真”到“跑通产品”差的这一步恰恰是Simulink最具价值、也最容易被低估的地方。很多工程师第一次接触Simulink时感受往往是“拖几个模块连上线点运行看到波形觉得挺方便”。但如果只是这样Simulink本质上就是个稍微高级一点的画图工具。真正让Simulink在工业界占据不可替代地位的是它背后那条完整的链路——从模型设计、仿真验证到自动生成可部署的C/C代码再到硬件在环测试和产品落地。这也正是“MATLAB Simulink仿真及代码生成技术”这个方向最有含金量的部分。不过从仿真模型到可运行代码之间并不是点一个按钮就万事大吉。模型怎么建才能生成高效代码配置哪些参数才能满足嵌入式环境生成代码之后怎么验证它和仿真行为一致这些问题如果不搞清楚生成的代码要么跑不起来要么跑起来行为不对甚至比手写代码更难调试。这篇文章希望帮你把这条链路打通。我们会从Simulink代码生成的核心原理讲起梳理建模时需要遵守的规则然后通过一个完整的PID控制示例逐步演示从模型到C代码的生成过程最后补充常见问题和工程实践经验。读完之后你会对“用Simulink做嵌入式开发”这件事有一个清晰的整体认知也知道从哪一步开始动手最稳妥。1. 这篇文章真正要解决的问题先聊一个很多团队都会遇到的真实场景。你接手了一个电机控制项目需求是尽快出一个可运行的底层控制原型。传统做法是先写C代码烧到板子上用示波器看波形发现不对再改代码重新编译。这个循环看起来直接但有一个问题——算法本身还不确定甚至控制策略都没定下来时你根本不知道该写什么代码。PID参数用多少前馈补偿加到什么程度饱和之后怎么处理这些问题在纯代码层面来回试效率非常低。换一个思路用Simulink搭一个电机控制模型先用仿真把控制算法调通波形看清楚了、参数试明白了再通过代码生成一键转成C代码。这样做的好处是算法设计和嵌入式实现被分开了算法问题在仿真阶段就能暴露和修正嵌入式阶段只需要关注代码集成和硬件适配。这就是Simulink代码生成技术真正解决的问题它不是帮你把C代码写得更好而是帮你绕过“从算法到实现”的翻译过程把误差降到最低。但这里有一个关键判断必须说清楚Simulink代码生成适合的是“模型化程度高、控制逻辑复杂、需要反复迭代验证”的项目而不是所有嵌入式场景的银弹。如果你只是写个简单的LED闪烁、按键扫描手写几行C代码比搭一个Simulink模型再生成代码快得多。Simulink代码生成的优势在于算法复杂、需要仿真标定、需要模型复用、需要快速原型验证。这类项目里模型是核心资产代码只是模型的一种输出形式。看完这篇文章你会知道Simulink代码生成的基本原理和工作流程。建模时需要遵守哪些规则才能生成高质量代码。如何配置环境、配置模型、生成代码并验证结果。实际项目中容易踩的坑以及对应的排查思路。2. Simulink代码生成的核心原理与适用场景2.1 从建模仿真到代码生成Simulink做了什么Simulink本身是一个基于框图的建模和仿真环境。你拖拽的每一个模块本质上都对应了一段计算逻辑。比如Gain模块就是一个乘法Sum模块就是一个加法PID Controller模块则是一个完整的控制算法。在仿真模式下Simulink会用解释执行的方式把模块之间的连线关系翻译成数值计算流程按采样时间推进最终得到信号随时间变化的波形。代码生成做的事情则是把同样的模块关系翻译成确定性的C语言源代码。Simulink编译器确切地说是Embedded Coder在较新版本中称为Simulink Coder会根据你选择的“代码生成目标”优化生成代码的结构、数据存储方式和函数接口。有一个常见的误解需要纠正“只要在Simulink里画出模型点生成代码出来的C代码就能直接在单片机上跑。”这句话只对了一部分。模型能不能生成可用的嵌入式代码取决于你建模时是否遵守了代码生成规则。比如是否使用了定步长求解器而不是变步长求解器。是否避免了不支持的模块比如某些可视化Scope模块不是生成代码目标的一部分。是否对数据进行了类型指定而不是放任Simulink自己推断。是否将子系统配置为原子子系统让生成的代码有清晰的函数边界。2.2 仿真模型与实现模型的区别在Simulink中模型可以分两个层次看仿真模型目标是“复现物理逻辑”可以包含Scope、Display这类可视化模块也可以用连续时间、变步长求解器只要能算出正确结果就行。实现模型目标是“生成嵌入式代码”必须满足代码生成约束比如定步长、离散时间、无动态内存分配、数据类型明确。很多新手直接在仿真模型上点“Generate Code”结果报错或者生成的代码无法在目标芯片上编译。原因就是没有把模型从“仿真形态”转换到“实现形态”。换一个类比来理解仿真模型像是导演手里的分镜脚本重点是讲清楚故事可以用各种花哨的表现手法实现模型像是摄影棚的拍摄清单必须考虑光线、机位、演员调度这些实际限制。二者可以共用核心故事线但实现层的约束完全不同。2.3 代码生成的分层机制Simulink代码生成不是一蹴而就的它分成多个层次层次名称作用模型层Simulink模型描述系统逻辑和控制算法配置层Code Generation 配置决定生成代码的风格、目标和优化策略模板层TLCTarget Language Compiler将模块关系翻译为目标代码高级用户可定制支持包层硬件支持包为特定芯片或开发板生成适配代码和驱动对大多数使用者而言不需要深入TLC定制但需要理解代码生成结果受模型结构和配置参数双重影响。模型结构决定了算法的边界配置参数决定了代码的形态是函数化还是内联是静态内存还是动态内存是否优化了速度或内存。2.4 适用的项目类型从实际工程看以下场景最适合使用Simulink代码生成控制算法开发电机控制、机器人控制、飞行器控制、汽车底盘控制。控制算法天然适合用框图表达而且需要反复调参和仿真验证。信号处理与通信算法滤波器设计、调制解调算法、编解码器。用Simulink可以快速验证算法性能再生成代码部署到DSP或FPGA。复杂系统级设计多子系统协同需要系统和子系统级别分别验证。快速原型与硬件在环仿真模型可以快速跑在实时仿真机上与真实硬件闭环验证。反过来下面这些场景通常不太适合简单逻辑控制代码量很小且逻辑固定。算法已经非常成熟不需要再做仿真验证。目标平台资源极其受限且编译器对生成代码支持不好。团队里没有人理解生成代码的结构后续维护困难。3. 环境准备与前置条件动手之前先确保你的开发环境是完整的。很多代码生成失败的问题根源不是模型搭错了而是环境缺了某个组件。3.1 必需组件要完成Simulink代码生成至少需要以下几个组件MATLAB与Simulink这是基础环境。版本没有硬性要求但建议使用比较新的稳定版本。需要注意不同版本的界面和配置项名称可能略有差异本文演示的是通用流程。MATLAB Coder / Simulink Coder或Embedded Coder这是代码生成的核心工具箱。Embedded Coder在传统版本中提供了更多嵌入式优化和硬件适配功能如果你的目标平台是工业级MCU建议确认授权中包含它。C编译器MATLAB代码生成过程中需要调用C编译器来编译生成的源码校验其可编译性。常见选择是MinGW-w64编译器MATLAB自带的Add-On即可安装或Microsoft Visual Studio。目标硬件支持包可选如果目标是特定芯片比如STM32系列、Arduino、Raspberry Pi等需要安装对应的硬件支持包。支持包会提供设备驱动模块和适配代码显著降低集成成本。3.2 验证环境是否就绪打开MATLAB在命令行窗口运行以下命令可以查看当前已安装的工具箱列表确认Simulink Coder或Embedded Coder是否已经存在ver(simulink) ver(rtw) % 老版本中Simulink Coder的模块名是Real-Time Workshop ver(embeddedcoder)如果代码生成相关的工具箱没有安装执行生成代码操作时会直接报错。这时候需要回到MATLAB Add-On Explorer附加功能资源管理器中搜索并安装对应工具箱。3.3 配置C编译器安装好MinGW-w64之后需要让MATLAB使用它作为默认编译器。在命令行执行mex -setup运行后会弹出一个交互选择界面列出系统上所有可用的编译器。选择你安装的MinGW-w64或其他编译器即可。这一步是新手最容易忽略的地方。如果跳过了编译器设置后续调用代码生成时经常会遇到“No supported compiler was found”这样的报错。3.4 确认目标硬件信息如果最终目标是某个具体的MCU建议先确认以下信息芯片的内核架构ARM Cortex-M、Cortex-A、RISC-V等。芯片厂商是否提供MATLAB支持包。所用代码生成配置是否支持该架构比如是否需要配置字节序、整数类型宽度。是否有对应编译器链常见如ARM GCC、IAR、Keil。这些信息对后续配置代码生成目标至关重要。不同芯片的寄存器操作和外设驱动差异很大如果缺少支持包就需要自己做驱动集成这会显著增加开发工作量。4. 核心流程拆解从仿真模型到C代码把Simulink模型转换成C代码核心流程可以分成五个环节。下面的过程来自实践经验总结每个环节都有容易出现偏差的地方。4.1 第一步建立“可实现”的模型很多人在搭建模型时随手用连续时间模块、变步长求解器最后生成代码时被各种限制卡住。建议从最开始就建立一个“面向代码生成”的模型。需要遵守的规则包括使用定步长求解器在模型配置参数的Solver选项中Type选择Fixed-stepSolver选择一个适合离散系统的算法比如discrete无连续状态。模型尽量离散化连续模块如积分器、传递函数在代码生成时会转换为离散近似你需要明确采样时间。尽量直接使用离散模块能简化这个问题。子系统使用原子子系统右键子系统模块选择Block Parameters在Treat as atomic unit选项前打勾。这样生成的代码中子系统对应一个独立函数结构更清晰便于测试和集成。明确数据类型对信号线和模块参数显式指定数据类型避免Simulink自动推断出不确定的整数类型或浮点类型。4.2 第二步配置模型参数打开模型的Configuration Parameters配置参数对话框这是代码生成的“总控制台”。关键配置项包括Solver求解器Type选择Fixed-stepSolver选择discrete或合适的定步长算法Fixed-step size根据系统需求设置比如0.0011ms周期。Hardware Implementation硬件实现选择目标芯片的设备类型。这个配置影响生成代码中的基本数据类型宽度比如int是16位还是32位char是否有符号。Code Generation代码生成System target file系统目标文件选择合适的配置比如ert.tlcEmbedded Real-Time target适合嵌入式快速原型。Language选择C或C。Generate code only可选如果不需要自动编译可以只生成代码。这里真正容易踩坑的地方是Hardware Implementation中的设备类型必须与实际目标芯片匹配。如果目标芯片是32位ARM而配置默认选择了通用32位系统往往问题不大但如果是16位DSP这一项配置错会导致生成代码中的整型宽度完全错误程序跑起来数据全乱。4.3 第三步建立信号与接口映射生成代码与外部程序比如主循环、驱动层、操作系统之间的通信是通过模型的输入输出接口完成的。在Simulink中这对应模型的Inport和Outport模块。它们的名称会成为生成C函数的参数名。因此Inport/Outport命名要简洁、有业务含义比如speed_ref、current_fb、pwm_out。接口类型要和外部代码约定好比如ADC采集回来的数据是uint16那么Inport就显式设置为uint16。如果需要在代码中记录中间变量可以定义Simulink信号对象Signal Object或在模型中加To Workspace模块但To Workspace只适合仿真不适合生成代码。4.4 第四步生成代码在模型窗口的App选项卡中点击Embedded Coder或Simulink Coder进入代码生成界面。点击Generate Code按钮稍等片刻模型会自动生成C代码和头文件。生成的代码结构大致如下model_name.c // 核心算法实现 model_name.h // 公共接口声明 model_name_types.h // 数据类型定义 model_name_private.h // 模型内部私有定义 rtwtypes.h // Simulink基础数据类型定义其中model_name.c中的model_name_step()函数是整个模型的核心周期性调用它系统就会按照模型逻辑执行一次。4.5 第五步集成与验证生成的代码不会自动跑起来需要你自己编写一个调用框架周期性地调用model_name_step()函数并给模型提供输入数据。这一步最好先在PC端验证生成代码的逻辑正确性确认无误后再移植到目标硬件。很多团队急于直接烧板子出了问题很难定位是算法问题还是驱动问题规范的流程应当是先在PC侧做软件在环测试。5. 完整示例PID控制器建模与代码生成下面通过一个简单的温控系统PID控制器走一遍完整流程。这个例子麻雀虽小五脏俱全涵盖建模、配置、生成和验证全过程。5.1 模型结构模型结构如下Inporttemp_fb温度反馈double类型、temp_ref温度目标值double类型。核心算法PID Controller模块配置为离散PID采样时间1ms。Outportheat_ctrl加热控制量double类型。5.2 建立模型在Simulink中新建模型按上述结构绘制模型图。关注以下细节两个Inport模块分别命名为temp_fb和temp_ref。PID Controller模块位于Simulink Continuous库在模型库浏览器中搜索PID Controller即可拖入。Outport命名为heat_ctrl。为了后续代码结构清晰把整个PID控制算法放进一个原子子系统。在模型窗口内选中PID Controller模块和Outport模块右键选择Create Subsystem from Selection。然后打开子系统配置为原子子系统。5.3 配置模型参数在模型窗口菜单栏选择Model Settings或Configuration Parameters逐项配置SolverType选择Fixed-stepSolver选择discreteFixed-step size设置为0.001。Code Generation System target file选择ert.tlc。Code Generation Language选择C。Hardware Implementation Device vendor / type选择目标芯片类型。如果只是PC验证可以先选Generic 32-bit Embedded Processor。完成上述配置后模型基本具备“可生成代码”的条件。5.4 用命令行配置并生成代码除了在图形界面点击操作也可以用MATLAB脚本完成配置。这个方式更适合批量生成和自动化集成。% 文件路径generate_pid_code.m % 打开模型 model pid_thermal_model; open_system(model); % 获取模型配置参数对象 cfg getActiveConfigSet(model); % 配置为定步长离散求解器步长1ms set(cfg, SolverType, Fixed-step); set(cfg, Solver, FixedStepDiscrete); set(cfg, FixedStep, 0.001); % 配置代码生成目标 set(cfg, SystemTargetFile, ert.tlc); set(cfg, GenCodeOnly, on); % 执行代码生成 slbuild(model);在MATLAB命令行中执行generate_pid_code如果一切正常命令行会输出代码生成日志并在当前目录下生成pid_thermal_model_ert_rtw文件夹里面就是生成的C代码。5.5 调用生成代码的示例生成的代码中核心入口函数是pid_thermal_model_step()。下面是一个在PC端调用它的示例/* 文件路径main_pc.c */ #include stdio.h #include pid_thermal_model.h int main(void) { /* 输入反馈与目标值 */ double temp_fb 20.0; double temp_ref 60.0; double heat_ctrl 0.0; /* 初始化模型 */ pid_thermal_model_initialize(); /* 模拟10秒步长1ms共10000个周期 */ for (int i 0; i 10000; i) { /* 调用核心步进函数 */ pid_thermal_model_step(temp_ref, temp_fb, heat_ctrl); /* 这里可以插入真实的传感器采样和加热器执行逻辑 */ if (i % 1000 0) { printf(step%d, temp_ref%.2f, temp_fb%.2f, heat_ctrl%.2f\n, i, temp_ref, temp_fb, heat_ctrl); } } pid_thermal_model_terminate(); return 0; }这里的关键是理解生成函数的签名。根据Inport和Outport数量以及数据类型的不同step函数可能有多种形式实际以生成的头文件声明为准。5.6 编译并验证在MATLAB命令行中也可以用以下方式快速编译PC端程序% 切换到生成代码目录 cd(pid_thermal_model_ert_rtw); % 使用mex编译或者直接用系统gcc编译 system(gcc -I. -o main_pc main_pc.c pid_thermal_model.c);运行生成的可执行文件./main_pc预期输出是一串逐周期打印的控制量数据heat_ctrl会随着温度反馈接近目标值而变化。如果前后两次打印之间的数值在逐渐收敛说明PID算法工作正常。6. 运行结果与效果验证6.1 如何判断代码生成成功代码生成成功的标志不只是“没有报错”。更严格的判断标准是生成代码的行为必须与仿真模型一致。在Simulink里跑一次仿真记录输出波形然后运行生成代码的程序记录同样的输入输出序列。对比两条曲线如果高度吻合说明代码生成是正确的。这就是所谓“仿真与实现的一致性验证”。如果在对比中发现问题优先检查以下环节采样时间是否一致。仿真中的采样时间决定了算法的离散化频率生成代码里周期调用间隔必须匹配。数据类型是否一致。仿真中默认double嵌入式中如果改成float精度差异会累积。初始化顺序是否一致。生成代码的initialize函数如果漏调用或者在其之前就调用了step输出就会异常。6.2 使用Simulink外部模式进行实时验证只做PC端验证还不够真实硬件环境下传感器噪声、执行器非线性都会影响结果。这时可以使用Simulink的外部模式External Mode功能。外部模式的工作方式很实用模型编译后部署到目标硬件Simulink上位机通过通信接口串口、以太网等与目标硬件实时连接。你可以在Simulink界面中在线修改模型中的参数比如PID的Kp、Ki、Kd参数会立即下发到硬件端并以Scope方式实时观测反馈波形。外部模式的价值在于它把仿真和实物测试连接了起来。原来调参需要反复烧写Flash现在可以在线调试效率提高很多。启用外部模式的方法模型配置中Code Generation Interface External mode勾选Enable在支持该功能的目标上。模型上方下拉框将Normal改为External。点击Run按钮模型会先编译下载到目标然后通过通信通道与目标交互。不过要注意外部模式依赖硬件支持包和底层驱动不同芯片的配置差别很大。建议先阅读对应硬件支持包的官方文档确认其支持外部模式。6.3 软件在环测试SIL软件在环测试Software-in-the-LoopSIL是验证生成代码的一种非常高效的手段。它的原理是把生成代码编译成独立的可执行库在PC上与Simulink原模型并联运行对比两者的输出。MATLAB中启用SIL测试非常简单。在模型工具条中选择“SIL”按钮或通过配置参数Simulink会自动编译生成代码为SIL模块并把原模型被替换为SIL模块后的仿真结果与原始结果进行对比。你能看到哪个信号的差异超过容差从而定位问题。SIL测试不需要任何额外硬件是代码生成后第一时间执行的“体检”。在实际项目里强烈建议把SIL测试作为代码交付前的固定步骤。7. 常见问题与排查思路下面整理了几个Simulink代码生成中最常遇到的坑以及对应的解决思路。问题现象可能原因排查方式解决方案点击Generate Code后报“No supported compiler was found”MATLAB没有可用的C编译器在命令行执行mex -setup查看已安装编译器安装MinGW-w64并设置为默认编译器提示“Unsupported variable-step solver”模型使用了变步长求解器无法生成嵌入式代码检查Configuration Parameters Solver改为Fixed-step求解器选择离散算法生成代码后目标芯片编译失败Hardware Implementation配置错误或目标芯片不支持生成代码检查Device vendor/type是否匹配正确配置芯片型号安装硬件支持包生成代码中老是出现奇怪的变量名信号线没有命名Simulink自动生成了临时名称检查模型中各条信号线是否有名字为关键信号线显式命名或用Signal Object定义属性报“Symbol xx not found”错误模型中的某个模块不支持代码生成或缺少对应支持包查阅模块文档确认代码生成支持情况替换为支持代码生成的等价模块或自定义模块生成的C代码和仿真结果不一致采样时间、初始化顺序或数据类型不一致做SIL测试对比输出曲线统一配置采样时间和数据类型确认initialize被调用MATLAB版本在代码生成阶段报“Error 9”类错误常见于编译器路径、许可证校验或MATLAB安装问题查看完整错误堆栈确认是否在编译阶段、配置阶段或许可证阶段报错更新编译器配置、检查许可证状态或切换到MATLAB默认支持环境重试生成代码体积过大Flash不够代码内联了过多模块逻辑或启用了不必要的调试信息检查Code Generation Optimization设置开启代码复用Code reuse、函数打包Function packaging和优化级别配置Modelsim联合仿真时波形始终为红线数据类型不匹配或信号采样时间配置错误仿真驱动状态未建立检查模型输入数据类型和仿真实体时钟连接统一数据位宽与采样时间确认初始化/复位时序MATLAB运行在虚拟机上速度很慢虚拟机未启用GPU加速或CPU直通Simulink仿真计算密集查看MATLAB性能监控报告优先使用物理机跑重型仿真或给虚拟机分配更多核心与内存排查问题时有一个通用原则先看日志再猜原因。MATLAB命令行和代码生成报告会提供大量细节。很多“玄学”错误最终都指向配置错误或环境缺失。8. 最佳实践与工程建议8.1 模型架构设计模型是活动资产不是一次性画完就结束的图纸。建议从第一天就按照“模块化、接口化”的原则搭建。每个功能模块使用独立的原子子系统子系统内不混杂其他业务逻辑。子系统之间的信号线明确命名名称与代码中变量名保持一致。尽量把纯算法与硬件相关逻辑分离。算法层模型可以完整仿真硬件相关模块只在小范围内存在。复杂项目中使用Simulink模型引用Model Reference管理多模型协作而不是把所有模块堆在一个大模型里。8.2 原子子系统与函数封装代码生成时原子子系统的价值是它把子系统映射为独立的函数。对应的step函数会调用这些子函数代码结构接近手写模块化C代码可读性远好于将所有逻辑内联成一个大函数。在原子子系统的配置中可以指定函数名规则、函数复用选项。合理配置这些选项可以控制生成代码中函数的大小和调用深度便于后续单元测试和静态分析。8.3 使用Simulink信号对象明确数据属性Simulink信号对象Signal Object可以让你对信号线关联具体的数据类型、初始值、存储类别。比如定义s Simulink.Signal; s.DataType single; s.InitialValue 0; s.CoderInfo.StorageClass ExportedGlobal;然后把这个信号对象绑定到模型中的某条信号线上生成代码时这条信号线就会成为全局变量供外部代码直接访问。这在调试和集成时非常方便但要注意控制全局变量的数量不能滥用。8.4 代码集成与数据交换生成代码与手写代码的集成通常涉及数据交换。这里有一条安全边界必须守住生成代码不要直接操作硬件寄存器硬件访问应由手写驱动层完成。生成代码是通过Inport/Outport接口与驱动层交换数据的。这样算法代码可移植、可复用不依赖具体硬件。如果让生成代码直接读写寄存器换来的是短暂方便失去的是模型的通用性。8.5 单元测试与回归代码生成不是“一锤子买卖”。模型改了之后重新生成的代码必须经过回归验证。在工程中更稳妥的做法是先运行SIL测试确保生成代码行为与模型一致。用MATLAB编写测试脚本导入仿真测试用例验证关键指标是否达标。在目标硬件上做硬件在环测试确认实时性能满足时序要求。8.6 版本管理与多人协作MATLAB模型是二进制文件多人修改时很难像源代码那样方便合并。建议采用以下策略使用MATLAB的Compare/Merge工具比较模型版本差异。让不同工程师负责不同子系统通过模型引用整合避免直接冲突。对模型文件做版本控制时保留描述性的提交信息方便回溯。8.7 安全与合规边界如果在汽车、医疗、航空航天等安全相关领域使用代码生成必须考虑功能安全标准如ISO 26262、IEC 61508。Embedded Coder提供了针对这些标准的认证套件但使用前提是你必须按照对应标准的流程执行需求追溯、模型验证、代码评审、测试追溯。即使不在安全关键领域也建议养成记录模型版本、配置参数和测试结果的习惯这是工程化的基本素养。9. 总结与后续学习方向这篇文章从“仿真模型到产品代码”的鸿沟出发梳理了Simulink代码生成的核心原理、环境准备、建模约束、配置方法和验证思路。我们用一个PID温控模型走完了从建模到生成C代码、再到PC端调用的完整流程也分析了外部模式、SIL测试这些验证手段最后给出了工程实践中最容易被忽略的建议。现在值得你想清楚的一个问题是你的项目到底适不适合走Simulink代码生成这条路如果答案是肯定的那接下来可以沿着下面几个方向继续深入学习更多Embedded Coder配置项代码优化、函数打包、存储类别、多速率系统。深入研究目标硬件支持包配置定时器中断、外设驱动和外部模式。探索硬件在环测试把模型运行在实时仿真机上与真实控制器闭环验证。建立自动化测试脚本用MATLAB脚本批量执行SIL测试和回归测试。阅读官方文档和示例MATLAB自带的demo是掌握复杂功能最快的方式。最后有必要提醒一句生成代码只是流程的一部分真正可靠的产品是整个流程的产物——从需求、模型、仿真、代码到测试每一环都要经得起推敲。把这条链路想明白了Simulink对你来说就不仅仅是一个画框图的仿真实用工具而是一套可以支撑产品开发的完整工程方法论。
返回列表