我的目标
我正在使用 Mathworks 的代码生成支持包为 Nucleo L476RG 构建一个基于 Simulink 的应用程序。这些软件包包括用于控制控制器外围设备的基本块,但是当涉及到外部硬件(例如基于 SPI 的 SD 卡写入器)时,我不想从头开始实施通信协议。
我有使用支持 STM32 板的 Arduino IDE 对 Nucleo 板进行编程的经验,并且找到了一些描述使用 S-Functions 将此类 Arduino 代码直接集成到 Simulink 中的过程的资源,请参见以下链接:
https://www.ee-diary.com/2020/11/How-to-create-Arduino-S-Function-in-Simulink.html
https://www.mathworks.com/matlabcentral/fileexchange/39354-device-drivers
我的目标是结合创建一个 S-Function“驱动程序”,它将利用 Arduino STM 包和库,我可以将其与我的其他 Simulink 函数一起包含,并使用 Mathworks 生成 + 将最终代码部署到 Nucleo 板上toobloxes.
我的方法
首先,我在 Arduino IDE 中测试了一个简单的 LED 闪烁功能,将其上传到板上并验证了一切都按预期工作。这是默认的 Arduino 闪烁代码加上项目设置:
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
然后我想使用 S-Function 构建块复制相同的功能。这就是 S-func。来源:
/* 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 */
/*
* Custom Start code goes here.
*/
/* 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 */
/*
* Custom Terminate code goes here.
*/
/* Terminate_END */
}/* 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 */
/*
* Custom Start code goes here.
*/
/* 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 */
/*
* Custom Terminate code goes here.
*/
/* Terminate_END */
}
S-Function 生成 C 源代码没有任何问题。下一步是构建包含 S-Function 的 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();
extern "C" void(..)
而不是 void()
。这只会导致 Simulink 抱怨缺少 .c 类型的包装文件。