我正在开发一个具有许多 Cs 函数的 Simulink 模型。为了更容易处理,我想在 cs 函数中使用常量,就像在 simulink 模型中一样。所以我有一个带有预处理器常量的 c-header,例如:
#define THIS_IS_A_CONSANT 10
还有一个问题:如何以这种方式将其包含在 Simulink 中,例如,我可以在诸如工作区变量之类的常量源中使用 THIS_IS_A_CONSANT?
感谢和问候亚历克斯
Simulink 中有一些功能允许您包含定义常量、变量等的自定义 C 头文件;但是,据我所知(并且正如人们所期望的那样),这实际上仅在生成和编译代码的情况下才相关。
因此,在大多数情况下,此特定功能仅在您使用 Simulink Coder 从模型生成独立可执行文件时才相关。例如,此链接显示如何在代码生成期间通过使用具有自定义存储类的Simulink.Parameter对象和模型的配置参数下的代码生成 - 自定义代码窗格来包含存储在外部头文件中的参数。
Simulink 文档中的此链接显示了如何使用#define自定义存储类来实现类似的结果。
但是,听起来这些都不能真正解决您的问题,因为您想在模拟期间使用头文件中的代码。
也就是说,考虑到 Simulink 中的某些元素(例如 Stateflow 图和 MATLAB Function 模块)会在仿真过程中“在后台”生成和构建代码,因此(至少假设)您可以使用一些上面描述的概念,以便在模拟期间从这些元素之一访问头文件中的值。例如,只需转到Configuration Parameters 下的Simulation Target->Custom Code窗格并在Include custom C code in generated: Header下包含文本#include “header.h” ,我就能够成功访问 Stateflow 图中的预处理器宏文件. (在这种情况下,header.h 包含您在帖子中包含的 C 代码行)
尽管您似乎应该能够进一步扩展此功能,但这确实是我在模拟期间访问头文件所能实现的限制。例如,我知道在Rapid Accelerator模式下运行模型实际上会在后台生成和构建代码,所以看起来您应该能够使用我上面描述的技术的某种组合,以便能够在模拟期间访问头文件中的值. 不过,Rapid Accelerator 模式生成的代码似乎并没有像 Simulink/Embedded Coder 那样尊重这些技术定义的所有设置,所以我一直遇到编译错误。(尽管也许我只是错过了一些可以使这项工作发挥作用的创造性设置组合)。
希望这有助于解释 Simulink 在包含 C 头文件方面的能力(和限制)。因此,总而言之,根据上面包含的链接,您所要求的几乎是不可能的,但实际上......不是真的。
因此,如果您真正想要的只是能够从头文件中的预处理器#define中创建工作区变量,那么使用 MATLAB 脚本手动解析文件可能是最简单的,正如之前在评论中所建议的那样。这是一个快速而肮脏的脚本,它加载到头文件中,遍历每一行,使用正则表达式(如果需要,您可以改进)来解析#define语句,然后调用eval从解析的输入。
filename = 'header.h';
pattern = '^\s*#define\s*(\w*)\s*(\d*\.?\d+)';
fid = fopen(filename);
tline = fgetl(fid);
while ischar(tline)
tokens = regexp(tline, pattern,'tokens','once');
if(numel(tokens) == 2)
eval([tokens{1} ' = ' tokens{2}]);
end
tline = fgetl(fid);
end
fclose(fid);
您可以将此代码放在回调中,以便每次加载模型时都会执行。只需转到 File->Model Properties->Model Properties,单击 Callbacks 选项卡,然后将代码放在您想要的任何回调下(例如 PreLoadFcn,如果您希望它在模型加载之前立即运行)。