WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

S-Functions: Port Dimensions

 

Maggus

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.09.2008, 12:15     Titel: S-Functions: Port Dimensions
  Antworten mit Zitat      
Hallo!

Ich schreibe eine S-Function in C für Simulink. Ich möchte, dass meine S-Function 3 Eingänge und 3 Ausgänge hat.
Eingang 1 und Ausgang 1 sollen die Breite 5 haben (also 5 gemultiplexte Signale).
Eingang 2 und Ausgang 2 sollen die Breite 8 haben (also 8 gemultiplexte Signale).
Eingang 3 und Ausgang 3 sollen die Breite 9 haben (also 9 gemultiplexte Signale).

Dies funktioniert leider nicht. Simulink will, dass Eingang 2 und Eingang 3 die Breite 5 haben, genauso wie Eingang 1. Ich möchte jedoch im Allgemeinen unterschiedliche Breiten für die Eingänge haben. Die o.g. Werte sind nur Beispiele, ich möchte die Ein- und Ausgänge DYNAMICALLY_SIZED haben und keine festen Werte vorgeben. Wenn ich einen festen Wert vorgebe, funktioniert es.

Die Fehlermeldung lautet:
Error in port widths or dimensions. Invalid dimension has been specified for input port 1 of 'matlab_test6_muxer_modell/S-Function'.


Mein Code:
Code:

static void mdlInitializeSizes(SimStruct *S)
{
   int i;
   
   printf("mdlInitializeSizes(): started\n");
   
    ssSetNumSFcnParams(S, 0);                        //Null function Parameters
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        return; /* Parameter mismatch will be reported by Simulink */
    }

    if (!ssSetNumInputPorts(S, 3)) return;               //3 Eingänge, dynamically sized
    /* uint16 Signale */
    ssSetInputPortWidth(         S, 0, DYNAMICALLY_SIZED);
    ssSetInputPortDataType(         S, 0, SS_UINT16);      //Eingang soll vom Datentyp uint16 sein
    ssSetInputPortDirectFeedThrough(S, 0, 1);
    /* Boolesche Signale */
   ssSetInputPortWidth(         S, 1, DYNAMICALLY_SIZED);
    ssSetInputPortDataType(         S, 1, SS_BOOLEAN);      //Eingang soll vom Datentyp bool sein
    ssSetInputPortDirectFeedThrough(S, 1, 1);
    /* CAN-Signale */
   ssSetInputPortWidth(         S, 2, DYNAMICALLY_SIZED);
    ssSetInputPortDataType(         S, 2, SS_UINT16);      //Eingang soll vom Datentyp uint16 sein
    ssSetInputPortDirectFeedThrough(S, 2, 1);


    if (!ssSetNumOutputPorts(S, 3)) return;               //Genau 3 Ausgänge, dynamically sized
    /* uint16 Signale */
    ssSetOutputPortWidth(   S, 0, DYNAMICALLY_SIZED);
    ssSetOutputPortDataType(S, 0, SS_UINT16);            //Ausgang soll vom Datentyp uint16 sein
    /* Boolesche Signale */
    ssSetOutputPortWidth(   S, 1, DYNAMICALLY_SIZED);
    ssSetOutputPortDataType(S, 1, SS_BOOLEAN);            //Ausgang soll vom Datentyp bool sein
    /* CAN-Signale */
    ssSetOutputPortWidth(   S, 2, DYNAMICALLY_SIZED);
    ssSetOutputPortDataType(S, 2, SS_UINT16);            //Ausgang soll vom Datentyp uint16 sein

    ssSetNumSampleTimes(S, 1);                        //Einstellungen zur Sample Time

    /* Take care when specifying exception free code - see sfuntmpl_doc.c */
    ssSetOptions(S,
                 SS_OPTION_WORKS_WITH_CODE_REUSE |
            //     SS_OPTION_EXCEPTION_FREE_CODE |
                 SS_OPTION_USE_TLC_WITH_ACCELERATOR);
}
 


Code:

static void mdlOutputs(SimStruct *S, int_T tid) {
    unsigned char i;
   
   //Den Eingängen Variablen zuordnen
    InputUInt16PtrsType  uPtrs_uint16  = (InputUInt16PtrsType)  ssGetInputPortSignalPtrs(S,0);
    InputBooleanPtrsType uPtrs_boolean = (InputBooleanPtrsType) ssGetInputPortSignalPtrs(S,1);
    InputUInt16PtrsType  uPtrs_can      = (InputUInt16PtrsType)  ssGetInputPortSignalPtrs(S,2);
   
   //Den Ausgängen Variablen zuordnen
   uint16_T   *out_uint16         = ssGetOutputPortSignal(S,0);
   boolean_T   *out_boolean      = ssGetOutputPortSignal(S,1);
   uint16_T   *out_can         = ssGetOutputPortSignal(S,2);
   
   //Breite des Eingangssignal, d.h. wieviele Signale sind auf einen Eingang "gemuxt"
    int_T      width_in_uint16     = ssGetInputPortWidth(S,0);
    int_T      width_in_boolean     = ssGetInputPortWidth(S,1);
    int_T      width_in_can      = ssGetInputPortWidth(S,2);
   
     //Breite des Ausgangssignal
    int_T      width_out_uint16     = ssGetOutputPortWidth(S,0);
    int_T      width_out_boolean     = ssGetOutputPortWidth(S,1);
    int_T      width_out_can      = ssGetOutputPortWidth(S,2);

   printf("Eingang: Es liegen %d uint16-Signale, %d Boolsche Signale und %d CAN-Signale an.\n", width_in_uint16, width_in_boolean, width_in_can);
   printf("Ausgang: Es liegen %d uint16-Signale, %d Boolsche Signale und %d CAN-Signale an.\n", width_out_uint16, width_out_boolean, width_out_can);  

   /*
    * Die for-Schleifen laufen über alle Signale eines Input-Ports.
    */    
    for (i = 0; i < width_in_uint16; i++) {
        *out_uint16++        = communicate(*uPtrs_uint16[i],    i);
    }
    for (i = 0; i < width_in_boolean; i++) {
        *out_boolean++      = communicate(*uPtrs_boolean[i],    i+0x40);
    }
   for (i = 0; i < width_in_can; i++) {
        *out_can++         = communicate(*uPtrs_can[i],       i+0xB0);
   }
}
 


Titus
Forum-Meister

Forum-Meister


Beiträge: 871
Anmeldedatum: 19.07.07
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 01.09.2008, 12:57     Titel:
  Antworten mit Zitat      
Hallo,

zuerst einmal: ich denke, unter "Simulink" wäre die Frage besser aufgehoben Wink
Zur Frage: wenn man DYNAMICALLY_SIZED in der mdlInitializeSizes verwendet, muss man mdlSetInputPortWidth und mdlSetOutputPortWidth Funktionen schreiben, siehe <MATLAB>\simulink\src\sfuntmpl_doc.c

Ciao,
Titus
Private Nachricht senden Benutzer-Profile anzeigen
 
Maggus

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.09.2008, 14:37     Titel:
  Antworten mit Zitat      
Hallo!

Danke, das hat mir geholfen.

Musste folgende Funktionen selbst implementieren:

mdlSetInputPortDimensionInfo
mdlSetOutputPortDimensionInfo
mdlSetDefaultPortDimensionInfo


Jetzt gehts.


Noch eine Frage:
Wenn ein Eingangssignal meiner S-Function in Simulink einen Namen trägt, kann ich dann diesen Namen irgendwie innerhalb der S-Function irgendwie rausfinden?
 
SimRookie
Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 07.01.10
Wohnort: ---
Version: R2007b
     Beitrag Verfasst am: 12.10.2010, 10:03     Titel:
  Antworten mit Zitat      
Hallo Leute,

Es tut mir leid diesen Thread wieder aufzugreifen aber genau darum geht es und bevor ich ein neuen aufmache, schreibe ich lieber hier.

@Titus: wir hatten schon miteinander zutun. Ich möchte mich entschuldigen, dass du keine Antwort zur deinem Vorschlag von mir erhalten hast. Wird nicht mehr vorkommen. Embarassed

So nun zum Thema "Port Dimensions".

Ich bin in der Situation in der auch der Maggus war. Ich möchte dass die Größe der Ausgänge (speziell die Breite des Ausgangsvektors) dynamisch bleibt. Ich habe auch die drei mdl..DimensionInfo()-Funktionen in meinem S-Function Block implementiert. Leider macht die mdlSetDefaultPortDimensionInfo() probleme. Dazu die Funktion:
Code:

#if defined(MATLAB_MEX_FILE)
# define MDL_SET_DEFAULT_PORT_DIMENSION_INFO
static void mdlSetDefaultPortDimensionInfo(SimStruct *S)
{
    int_T outWidth = ssGetOutputPortWidth(S, 5);
       
    if(outWidth == DYNAMICALLY_SIZED){
        /* Output dimensions are unknown. Set it to scalar.*/
       ssSetOutputPortVectorDimension(S, 5, 1);
    }
} /* end mdlSetDefaultPortDimensionInfo*/
#endif
 


So ist die Funktion in dem Beispiel sfunc_matadd.c definiert. Nun zum Problem: sobald am Ausgang ein Block (z.B Demux) angeschloßen wird, der mehr Werte benötigt (Demux mit 2 Ausgängen) als in der mdl...Default...Info() (in diesem Beispiel: ein Wert) definiert wird, kommt beim erzeugen des Echtzeitcodes mit RTW eine Fehlermeldung in der folgenden Art:

Error using ==> rtwgen
--> Invalid setting for input port dimensions of '../Demux'. The dimensions are being set to 1. This is not valid because the total number of input and output elements are not the same.
--> Error in port widths or dimensions. Output port 'S-function Block' is a one dimensional vector with 1 element.

Ist die Default-Größe größer als die Anzahl der Bennötigten Werte im Demux Block (z.B. ssSetOutputPortVectorDimension(S, 5, 4)) so gibt es keine Fehlermeldung aber eine andere Sache, die mich stört. Und zwar erscheinen alle vier Werte aus mdl...Default..() an den zwei Demux Ausgängen als zwei Vektoren der Größe zwei (out1=[wert1, wert2]; out2=[wert1, wert2]).

Hat jemand eine Idee warum es dazu kommt und wie kann man dies umgehen??

Vorweg die Größe muss dynamisch bleiben.

Ich bedanke mich im Voraus und ich werde auf jeden Fall ein Feedback zum Vorschlag geben Smile.

SimRookie
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.