在工作中,我最近接受了 MATLAB/Simulink 培训,包括可以为嵌入式应用程序生成 C 代码的 Simulink Coder。我想尝试一下,所以我买了一个 Arduino,并投入其中。我能够毫无问题地编写简单的草图,但在尝试集成 Simulink 生成的代码时遇到了障碍。
我最初使用的是 Arduino IDE,然后是带有 Arduino 插件的 Eclipse,最后是带有 embedXcode 模板的 Xcode。(我使用 Simulink 的工作机器是 PC,但我不允许安装“未经授权的软件”,所以我在家里的 Mac 上完成了剩下的工作。)所有三个都使用相同的 avr-gcc 编译器。
这三个都有相同的故障点:生成的函数调用上出现“未定义的引用”错误。我认为这是一个链接器问题,而不是基本语法或标头包含,因为 Eclipse 和 Xcode 代码完成工作正常,如果我以任何方式更改调用签名,错误就会改变。我可以对数据结构进行引用。
据我所知,默认的 makefile 设置为编译和链接文件夹中的任何文件。至少使用 Xcode 创建一个“mass_model2.o”文件。最后,如果我使用简单的函数调用手动编写单独的“myFunction.c”和“MyFunction.h”文件,它会按预期在设备上编译和运行。
setup()
无奈之下,我复制了生成的“.c”文件的全部内容,并将它们粘贴到我的和函数之后的主草图文件中loop()
,保持相同的“.h”引用,并从项目中删除了“.c”文件. 这实际上确实编译并运行了!但是,我不应该为了使用它而触摸生成的代码。
我需要做什么才能正确编译和链接?
Simulink 代码非常冗长,因此这里是关键部分:
mass_model2.h 摘录:
#include "rtwtypes.h"
#include "mass_model2_types.h"
/* External inputs (root inport signals with auto storage) */
typedef struct {
int16_T PotPos; /* '<Root>/PotPos' */
} ExternalInputs_mass_model2;
/* External outputs (root outports fed by signals with auto storage) */
typedef struct {
int16_T ServoCmd; /* '<Root>/ServoCmd' */
} ExternalOutputs_mass_model2;
/* External inputs (root inport signals with auto storage) */
extern ExternalInputs_mass_model2 mass_model2_U;
/* External outputs (root outports fed by signals with auto storage) */
extern ExternalOutputs_mass_model2 mass_model2_Y;
/* Model entry point functions */
extern void mass_model2_initialize(void);
extern void mass_model2_step(void);
mass_model2.c 摘录:
#include "mass_model2.h"
#include "mass_model2_private.h"
/* External inputs (root inport signals with auto storage) */
ExternalInputs_mass_model2 mass_model2_U;
/* External outputs (root outports fed by signals with auto storage) */
ExternalOutputs_mass_model2 mass_model2_Y;
/* Model step function */
void mass_model2_step(void)
{
// lots of generated code here
}
/* Model initialize function */
void mass_model2_initialize(void)
{
// generated code here
}
其他引用的标头“rtwtypes.h”和“mass_model2_private.h”定义了生成代码使用的特定类型,例如int16_T
. 这些文件包含在项目中,我没有收到任何与它们相关的错误。
在我的草图文件中,setup()
函数调用mass_model2_initialize()
. loop()
读取我的输入(电位器),在 中设置值mass_model2_U.PotPos
,然后调用mass_model2_step()
. 然后它获取mass_model2_Y.ServoCmd
并将值写入伺服输出,最后有一个delay()
.