别再覆盖你的ert_main.c了!Simulink代码生成后与外部集成的3个关键设置

张开发
2026/4/19 17:51:53 15 分钟阅读

分享文章

别再覆盖你的ert_main.c了!Simulink代码生成后与外部集成的3个关键设置
Simulink代码生成与外部集成的工程化实践指南每次修改完ert_main.c文件后下一次代码生成时所有心血付诸东流——这可能是许多Simulink开发者都经历过的噩梦。本文将分享一套经过实战验证的工程化方法帮助开发者避免常见陷阱实现生成代码与外部系统的无缝集成。1. 理解Simulink代码生成的核心机制Simulink的自动代码生成功能为嵌入式开发带来了革命性的效率提升但同时也引入了一些特有的工作流程挑战。要避免文件被意外覆盖首先需要理解其代码生成的基本逻辑。代码生成过程中Simulink会根据模型配置参数决定哪些文件需要重新生成。默认情况下ert_main.c被视为生成产物而非用户修改文件因此每次生成时都会被覆盖。这种设计源于Simulink对代码一致性的保证机制——它假设所有生成文件都应完全由模型决定。关键配置文件位置model.slx主模型文件model_ert_rtw/默认代码生成目录ert_main.c默认生成的主程序框架model.h/model.c核心算法实现文件重要提示任何需要保留的修改都应通过定制化模板或后期处理脚本实现而非直接修改生成文件2. 配置参数的关键设置2.1 防止文件覆盖的配置方法在Configuration Parameters中有几个关键设置决定了代码生成行为代码生成→模板文件指定自定义的ert_main.c模板路径Configuration Parameters → Code Generation → Templates代码生成→接口取消勾选Generate an example main program这将避免生成默认的ert_main.c代码生成→报告启用Create code generation report便于追踪生成文件的变化推荐配置组合配置项安全值作用Generate example mainOff不生成默认ert_main.cCustom template指定路径使用定制化模板Override templateOn确保使用自定义模板2.2 自定义模板的实现步骤创建不会被覆盖的自定义主程序复制原始ert_main.c到安全目录如/custom_templates进行所需修改如添加硬件特定初始化在模型中指定该模板路径set_param(gcs, ERTCustomFileTemplate, custom_templates/ert_main.c);验证模板应用get_param(gcs, ERTCustomFileTemplate)3. 工程化代码打包技术3.1 packNGo的高级用法packNGo命令是Simulink提供的代码打包工具但大多数开发者只使用了其基本功能。以下是一些进阶技巧结构化打包命令load(buildInfo.mat); packNGo(buildInfo, packType, hierarchical, ... fileName, generated_code.zip, ... nestedZipFiles, false);打包内容控制参数参数类型说明packTypeflat/hierarchical目录结构方式includeReporttrue/false是否包含生成报告ignoreFileMissingtrue/false忽略缺失文件additionalPathscell array添加额外依赖路径3.2 自动化打包脚本示例创建可复用的打包脚本package_code.mfunction package_code(modelName) % 加载构建信息 buildInfoFile fullfile([modelName _ert_rtw], buildInfo.mat); if ~exist(buildInfoFile, file) error(BuildInfo file not found. Generate code first.); end % 设置打包选项 packOpts struct(); packOpts.packType hierarchical; packOpts.includeReport true; packOpts.additionalPaths {../drivers, ../config}; % 执行打包 load(buildInfoFile); packNGo(buildInfo, packOpts); % 移动打包文件 movefile(*.zip, ../deliverables/); end4. 代码路径管理的专业实践4.1 自定义生成路径的完整方案标准的model_ert_rtw生成路径往往不符合工程管理规范。以下是设置自定义路径的完整方法基础路径设置命令Simulink.fileGenControl(set,... CodeGenFolder,./generated_code,... CacheFolder,./cache,... CreateDir,true);推荐的项目目录结构project_root/ ├── models/ # Simulink模型文件 ├── generated_code/ # 自定义代码生成目录 │ ├── controller/ # 各模块生成代码 │ └── shared/ # 共享文件 ├── external/ # 外部代码 ├── drivers/ # 硬件驱动 └── build/ # 编译输出4.2 多模型协同开发的路径管理当多个模型需要协同工作时共享文件的管理尤为关键设置共享工具链目录set_param(gcs, SharedUtilsTgtDir, generated_code/shared);为每个模型指定独立输出目录set_param(gcs, CodeGenFolder, generated_code/controller);验证路径设置Simulink.fileGenControl(getConfig)5. 外部代码集成的工程化方法5.1 安全的接口设计原则要实现生成代码与外部代码的安全集成应遵循以下接口规范数据接口使用明确的#include语句避免直接访问模型内部数据结构通过函数接口交换数据时间接口统一时间基准明确任务调度时序处理多速率集成示例接口头文件model_interface.h#ifndef MODEL_INTERFACE_H #define MODEL_INTERFACE_H #include model.h #ifdef __cplusplus extern C { #endif /* 初始化接口 */ void model_init(void); /* 单步执行接口 */ void model_step(float input1, float input2, float* output); /* 终止接口 */ void model_terminate(void); #ifdef __cplusplus } #endif #endif /* MODEL_INTERFACE_H */5.2 多模型集成的架构设计当需要集成多个生成模型时推荐采用以下架构分层架构底层硬件抽象层HAL中间层各功能模块上层协调调度层接口适配器模式// 多模型协调示例 void control_loop(void) { static bool initialized false; if (!initialized) { model1_initialize(); model2_initialize(); initialized true; } // 读取传感器数据 float sensor1 read_sensor(1); float sensor2 read_sensor(2); // 执行各模型步进 float temp_output; model1_step(sensor1, temp_output); model2_step(temp_output, sensor2, final_output); // 写入执行器 write_actuator(final_output); }6. 版本控制集成策略将Simulink代码生成纳入版本控制系统时应考虑以下实践应纳入版本控制的内容原始模型文件.slx自定义模板文件关键配置脚本接口定义文件不应纳入版本控制的内容自动生成的代码应在构建时生成临时文件大型数据文件.gitignore示例# Simulink生成文件 *_ert_rtw/ slprj/ *.asv *.autosave # 编译输出 build/ *.exe *.obj在实际项目中我们发现最有效的策略是将模型文件与生成代码分开管理通过CI/CD管道自动化整个构建过程。这既保证了可重复性又避免了不必要的版本控制负担。

更多文章