You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32 Arduino代码集成Simulink遇编译错误求助

我的目标

正在使用Mathworks代码生成支持包为Nucleo L476RG开发Simulink应用,官方模块可处理基础外设,但对于SPI接口SD卡这类外部硬件,不想从头编写通信协议。

有Arduino IDE搭配STM32支持包开发Nucleo板的经验,了解到可通过S-function将Arduino代码集成到Simulink中,目标是制作一个基于Arduino STM库的S-function驱动,能与其他Simulink模块配合使用,最终通过Mathworks工具箱生成代码并部署到板上。

操作步骤

  1. 先在Arduino IDE中测试LED闪烁功能,代码与配置如下,功能验证正常:
// 初始化函数,复位或上电时运行一次
void setup() {
  // 将内置LED引脚设置为输出模式
  pinMode(LED_BUILTIN, OUTPUT);
}

// 循环函数,持续运行
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // 点亮LED
  delay(1000);                      // 等待1秒
  digitalWrite(LED_BUILTIN, LOW);   // 熄灭LED
  delay(1000);                      // 等待1秒
}

Arduino IDE配置

  1. 尝试用S-function Builder复现该功能,S-function源码如下:
/* Includes_BEGIN */
#include <math.h>

#ifndef MATLAB_MEX_FILE
#include <Arduino.h>
#include <variant_NUCLEO_L476RG.h>
#endif
/* Includes_END */

/* Externs_BEGIN */
/* extern double func(double a); */
/* Externs_END */

void blink_sfunc_Start_wrapper(real_T *xD)
{
/* Start_BEGIN */
/*
 * 自定义启动代码写在这里
 */
/* Start_END */
}

void blink_sfunc_Outputs_wrapper(const real_T *xD)
{
/* Output_BEGIN */
if (xD[0]==1){
    # ifndef MATLAB_MEX_FILE
        digitalWrite(LED_BUILTIN,ledinp[0]);
    # endif
}
/* Output_END */
}

void blink_sfunc_Update_wrapper(const uint8_T *led_in,
                                real_T *xD)
{
/* Update_BEGIN */
if (xD[0]!=1){     
    # ifndef MATLAB_MEX_FILE        
    pinMode(LED_BUILTIN,OUTPUT);    
    # endif        
    xD[0]=1;}
/* Update_END */
}

void blink_sfunc_Terminate_wrapper(real_T *xD)
{
/* Terminate_BEGIN */
/*
 * 自定义终止代码写在这里
 */
/* Terminate_END */
}

遇到的问题

S-function生成C源码无异常,但构建Simulink模型时失败,Arduino库文件出现大量编译错误,示例如下:

C:/Users/tomru/AppData/Local/Arduino15/packages/STMicroelectronics/hardware/stm32/2.4.0/cores/arduino/stm32/digital_io.h:57:37: error: unknown type name 'GPIO_TypeDef'
   57 | static inline void digital_io_write(GPIO_TypeDef *port, uint32_t pin, uint32_t val)
      |                                     ^~~~~~~~~~~~

C:/Users/tomru/AppData/Local/Arduino15/packages/STMicroelectronics/hardware/stm32/2.4.0/cores/arduino/stm32/backup.h:67:3: warning: implicit declaration of function '__HAL_RCC_BACKUPRESET_RELEASE' [-Wimplicit-function-declaration]
   67 |   __HAL_RCC_BACKUPRESET_RELEASE();

已尝试的解决方法

  • 在S-function Builder中添加了所有必要头文件并配置路径,未出现头文件缺失错误;
  • 尝试将S-function wrapper改为.cpp格式,用extern "C" void(..)替换void(),但Simulink报错缺少.c类型的wrapper文件。

解决建议

1. 补充STM32 HAL库依赖

报错中的GPIO_TypeDef和__HAL_RCC_BACKUPRESET_RELEASE均属于STM32 HAL库内容,Arduino STM32核心依赖HAL库,但Simulink代码生成时未自动引入这些依赖:

  • 在S-function的Includes部分添加对应型号的HAL头文件:
    #ifndef MATLAB_MEX_FILE
    #include <stm32l4xx_hal.h> // 适配Nucleo L476RG的HAL头文件
    #include <Arduino.h>
    #include <variant_NUCLEO_L476RG.h>
    #endif
    
  • 在S-function Builder的Configuration > Custom Code > Additional build information > Linker flags中,添加Arduino IDE中该板型的HAL库链接参数(可从Arduino IDE的编译日志中提取)。

2. 统一S-function编译类型

Simulink默认期望S-function为C语言格式,直接修改为.cpp会导致兼容性问题:

  • 保持wrapper文件为.c格式,包含C++头文件时用extern "C"包裹以避免名字修饰:
    #ifndef MATLAB_MEX_FILE
    extern "C" {
    #include <Arduino.h>
    #include <variant_NUCLEO_L476RG.h>
    }
    #endif
    
  • 不要手动修改生成的wrapper文件,所有自定义代码在S-function Builder的对应代码块中编写。

3. 匹配编译器版本

确保Simulink代码生成使用的ARM GCC工具链版本与Arduino IDE一致,避免版本差异导致的语法兼容问题:

  • 在Simulink的Configuration Parameters > Code Generation > Toolchain Settings中,将编译器路径指向Arduino IDE使用的ARM GCC工具链。

若不想手动处理依赖,可尝试Simulink Arduino支持包的Custom Code模块:

  • 直接将Arduino代码嵌入到模块的Start、Outputs等回调中,支持包会自动处理Arduino库的依赖与编译流程,比S-function Builder更适配Arduino生态。

内容的提问来源于stack exchange,提问作者C. Matr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:24:58