'Simulink S-Function Builder with External Library and Runtime Binary

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 (I downloaded 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:

S-function builder Libraries tab

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?

All files in: https://github.com/JohannesSoikkeli/Simulink_joystick

Many thanks!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source