Clear Filters
Clear Filters

Simulink S-Function Builder with external library and runtime binary not compiling

10 views (last 30 days)
I am trying to make a S-Function (written in C and using SDL library) in Simulink to read joystick values from the device and output them to Simulink. I used before the standard aerospace library joystick block, however, this does not support compiling (which is needed for Rapid Acceleration). Hence, I decided to write my own S-Function.
I managed to make a simple C program that uses SDL (https://www.libsdl.org/download-2.0.php) to read values of joystick and print to terminal:
#include <stdio.h>
#include <unistd.h>
#include "SDL2/SDL.h"
static SDL_Joystick *joy = NULL;
int
main(int argc, char *argv[])
{
// ITIALIZE:
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
// Check for joystick
if (SDL_NumJoysticks() > 0) {
// Open joystick
joy = SDL_JoystickOpen(0);
if (joy) {
printf("Opened Joystick 0\n");
printf("Name: %s\n", SDL_JoystickNameForIndex(0));
printf("Number of Axes: %d\n", SDL_JoystickNumAxes(joy));
printf("Number of Buttons: %d\n", SDL_JoystickNumButtons(joy));
printf("Number of Balls: %d\n", SDL_JoystickNumBalls(joy));
} else {
printf("Could not open Joystick 0\n");
return 0;
}
}
SDL_JoystickEventState(SDL_IGNORE);
// READ VALUES:
for (int i = 1; i < 100; ++i){
SDL_JoystickUpdate();
for (int j = 0; j < SDL_JoystickNumAxes(joy); ++j) {
int value = (((int) SDL_JoystickGetAxis(joy, j)) + 32768);
printf("Axes %d: %d ", j, value);
}
printf("\n");
usleep(100000);
}
// CLOSE:
if (SDL_JoystickGetAttached(joy)) {
SDL_JoystickClose(joy);
}
return 1;
}
I compile the C code in Code::Blocks with linkers:
-lmingw32 -lSDL2main -lSDL2
The compiled .exe requires runtime binary SDL.dll, which is simply located in the same folder as the compilation, and everything works!
The problem is, how to transfer the above to work in Simulink environment? I have transferred the code into Simulink S-Function builder:
/* Includes_BEGIN */
#include "SDL2/SDL.h"
#include <stdio.h>
/* Includes_END */
/* Externs_BEGIN */
static SDL_Joystick *joy = NULL;
/* Externs_END */
void sunf_joystick_Start_wrapper(void)
{
/* Start_BEGIN */
// ITIALIZE:
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
// Check for joystick
if (SDL_NumJoysticks() > 0) {
// Open joystick
joy = SDL_JoystickOpen(0);
if (joy) {
ssPrintf("Opened Joystick 0\n");
ssPrintf("Name: %s\n", SDL_JoystickNameForIndex(0));
ssPrintf("Number of Axes: %d\n", SDL_JoystickNumAxes(joy));
ssPrintf("Number of Buttons: %d\n", SDL_JoystickNumButtons(joy));
ssPrintf("Number of Balls: %d\n", SDL_JoystickNumBalls(joy));
} else {
ssWarning("Warning:Joystick","Could not open Joystick 0\n");
}
}
SDL_JoystickEventState(SDL_IGNORE);
/* Start_END */
}
void sunf_joystick_Outputs_wrapper(real_T *y0)
{
/* Output_BEGIN */
SDL_JoystickUpdate();
for (int j = 0; j < SDL_JoystickNumAxes(joy); ++j) {
y0[j] = (((int) SDL_JoystickGetAxis(joy, j)) + 32768);
}
/* Output_END */
}
void sunf_joystick_Terminate_wrapper(void)
{
/* Terminate_BEGIN */
if (SDL_JoystickGetAttached(joy)) {
SDL_JoystickClose(joy);
}
/* Terminate_END */
}
and added the LIB_PATH and INCL_PATH to point for the SDL library:
However, I get a lot of similar error messages when trying to build through the GUI:
C:\Users\user\AppData\Local\Temp\mex_121831936796334_22096\sunf_joystick_wrapper.obj:sunf_joystick_wrapper.c:(.text+0xe): undefined reference to `SDL_InitSubSystem'
To me it seems that the libraries are not linked correctly. An idea how to fix this? I have tried to build it also with mex through MATLAB command line, not successful, and feels also wrong way to do it.
Also, any advice where the the runtime library SDL.dll should be stored or referenced if the compilation is successful?
Many thanks!

Accepted Answer

Kausthub
Kausthub on 28 Dec 2023
Edited: Kausthub on 28 Dec 2023
Hi Johannes Soikkeli,
I understand that you are facing an error when building an S-Function which depends on external library.
Yes, the error seems like a linking error. I would suggest you to simply make sure that the directory containing the DLL has been added to the System PATH environment variable (NOTE: you will need to restart MATLAB to make sure the new PATH value is picked up. Run "getenv PATH" in MATLAB to see the PATH setting.)
Also, building with MEX through the command line is not the right approach. Alternatively, you can create a C-MEX S-Function using the “legacy_code” function which has more capabilities than the S-Function Builder block and it provides options for you to provide the path the libraries.
  • LibPaths — Directories containing host and target library files, specified as a cell array of character vectors or string array. You can specify the directories using absolute or relative path names.
You can refer to the documentation of “legacy_code” for more details:
Here are few previously asked MATLAB Answers that might be helpful:
Hope it helps!

More Answers (0)

Categories

Find more on Schedule Model Components in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!