SP RTE Speicher reservieren ...

mactoolz
2011-02-12
2012-04-05
1 2 3 > >> (Page 1 of 3)
  • mactoolz - 2011-02-12

    Hallo,

    ich bin der Meinung das ich schon öfters in der RTE Speicher allokiert habe.
    Wobei ich sagen muss ich teste gerade auf meinem Laptop ohne jeglichen Controller.

    pnt: pointer to Array[0..99] of String;

    pnt := SysMemAlloc(Sizeof(pnt^));

    Warum bekomme ich hiermit keinen Zeiger zurück ???

    MacToolz

     
  • mactoolz - 2011-02-12

    Hi,

    super, steht ganz klar in der Doku.

    Kann mir jemand erklären was das für einen Sinn macht ???

    MacToolz

     
  • KlOis - 2011-02-15

    liefert denn die SIZEOF- Funktion denn überhaubt etwas zurück?
    du greifst ja auf die Referenz eines Zeigers zurück die nicht existiert!
    versuch es mal mit einer statischen Übergabe der Größe (in deinem Bsp. 100String=10080=8000)

    Grüße
    Klaus

     
  • Erik Böhm - 2011-02-15

    Moin

    Ich hab auch den Eindruck das wäre ein Fehler.
    SysMemAlloc liefert auch mit Aufruf "dwAlloc := SysMemAlloc(5);" auf der RTE und in der Simulation nur eine NULL zurück.

    iSize := SIZEOF(pnt^);
    liefert korrekt 8100 zurück.

    Gruß
    Erik

     
  • KlOis - 2011-02-15

    In der Hilfe wir darauf hingewiesen das 0 zurückgeliefert wird, wenn nicht genügend Speicher vorhanden ist:

    Zitat:
    Als Rückgabewert erhält man entweder den Pointer auf den reservierten Speicherplatz oder 0, wenn nicht soviel Platz wie angefordert, verfügbar ist. Dieser Rückgabewert sollte immer geprüft werden, auch wenn nur ein kleiner Speicherbereich allokiert werden soll !

    Als Hinweis wird noch erwähnt:

    Zitat:
    Die Funktion wird von CoDeSys SP RTE nicht unterstützt.

    Vielleicht hilft das noch weiter bei der Problemfindung

     
  • Erik Böhm - 2011-02-15

    Hallo zusammen

    1.

    Zitat:
    ich bin der Meinung das ich schon öfters in der RTE Speicher allokiert habe.

    oder

    Zitat:
    Hinweis: Die Funktion wird von CoDeSys SP RTE nicht unterstützt.

    Es kann ja nur Eins von Beiden richtig sein...

    1. Ich programmier ja jetzt auch schon länger mit CoDeSys, frage mich (oder besser den Ersteller des Threads) aber immer noch: Wofür überhaupt Speicher allokieren ?
      Das passiert doch automatisch.
      Auch in anderen Threads gabs ja schon diverse Fragen zu dem Thema, und auch da habe ich keine Antwort auf diese Frage bekommen.

    Gruß
    Erik

     
  • KlOis - 2011-02-16

    Hey

    Zitat:
    Wofür überhaupt Speicher allokieren ?

    Ich denke zur dynamischen Speicherverwaltung, doch sehe ich das in einem SPS Programm generell auch als kritisch an!

    Wenn es ansonsten im RTE funktioniert hat, kann es auch sein das kein Speicher mehr frei ist und deshalb eine 0 zurückgeliefert wird, oder?

    Letztendlich ist es doch immer eine Frage des Targets wie und ob die Funktionen unterstützt werden.

    Benötigt man nur den Zeiger und die Referenz ist eh immer gleich Groß, kann man sich auch den Zeiger von der Referenz holen:

    VAR
       arString:    ARRAY[0..99] OF STRING;
       dwPointer:   DWORD;
    END_VAR
    dwPointer:=ADR(arString);
    
     
  • Anonymous - 2011-02-16

    Originally created by: blackenslaver666

    Hi.

    KlOis hat geschrieben:
    Ich denke zur dynamischen Speicherverwaltung, doch sehe ich das in einem SPS Programm generell auch als kritisch an!

    Und wozu sollte man sowas brauchen?! Mir fällt keine App ein wo das zwingend nötig wäre. Ich erkenne da auch einfach die praxisrelevanten Aussagen von Erik wieder, für einen Anlagenprogrammierer ist dyn. Speicherreservierung eigentlich kein Thema. Denn eine SPS ist im eigentlichen Sinne kein Datensammler, dafür gibts FTP, DB-Systeme & Co.. Wozu dann also dynamisch Speicher allokieren? Das würde mich auch mal interessieren. Mehr als "Rumspielerei" erwarte ich da auch ehrlich gesagt nicht.

    Was das Thema Speicherreservierung angeht:
    Das ist absolutes Detailwissen welches wohl die wenigen die selbst täglich mit Codesys zu tun haben kennen. Ich weiss dass es von 3S regelmäßig "Expertentreffen" gibt, dort werden solche Details auch diskutiert. Oder an den Support wenden. In der Praxis halte ich dieses Wissen aber für irrelevant außer "nice-to-know". Generell stimme ich dir aber, dass das kritisch ist. Selbst Pointer sind absolut kritisch. Wer mal einen Pointer in den Wald gesetzt weil er z.B. die Adresse nicht zyklisch aktualisiert wurde und dadurch seine Maschine/Steuerung abballert hat ganz viiiel Spass bei der Fehlersuche.

    Gruß Andy

     
  • Erik Böhm - 2011-02-16

    Servus

    Ich hab eigentlich nichts gegen Pointer. Sind ne feine Sache, wenn man weiss was man tut.
    Nutzen wir teilweise auch recht ausgiebig.

    Das Pointer Modell einem 'klassichen' SPS Programmierer zu erklären ist immer wieder interessant

    Aber allokieren muss ich deshalb trotzdem nicht. Zumal dadurch das Ganze noch lange nicht dynamisch wird.
    Das Array hat immer noch feste Grenzen.

    Gruß
    Erik

     
  • KlOis - 2011-02-17

    Moin,

    halte es auch nicht für sinnvoll (dyn. Speicherverwaltung), außer man soll viele Daten sammeln, was wie schon erwähnt am besten anders geschieht.
    Doch nicht immer kann man es sich aussuchen!
    Deshalb die Suche nach einer solchen Lösung!

    Zitat:
    Aber allokieren muss ich deshalb trotzdem nicht. Zumal dadurch das Ganze noch lange nicht dynamisch wird.
    Das Array hat immer noch feste Grenzen.

    Nein.

    Man bestimmt durch das allokieren wieviel Speicher belegt wird.

    wenn man einen Pointer anlegt, z.B. ```

    ptArray:  POINTER TO ARRAY[1..255] OF BYTE;

    Dann sind die 255 Byte noch nicht reserviert.
    Wenn man Speicher allokiert, z.B.:
    

    ptArray:=SysMemAlloc(10);

    ```
    Hat man nur 10 Byte Speicher reserviert.
    Sollte jedoch aufpassen das man nicht auf Elemte > 10 zugreift ^^

    Deshalb --> unsauber und sollte vermieden werden!
    Aber dynamisch ist es doch, nur die Obergerenze wird in der Deklaration festgelegt (Bei meinen Bsp.).

    MfG
    KlOis

     
  • Erik Böhm - 2011-02-17

    Moin

    Wenn man einen Pointer anlegt, dann wird (ausser den 4Byte für den Pointer) kein Speicher reserviert.
    Der Pointer zeigt aber (physikalisch) auch nirgends hin. Was hab ich dann davon ?

    Gruß
    Erik

     
  • KlOis - 2011-02-17

    Servuz,

    Zitat:
    Wenn man einen Pointer anlegt, dann wird (ausser den 4Byte für den Pointer) kein Speicher reserviert.
    Der Pointer zeigt aber (physikalisch) auch nirgends hin. Was hab ich dann davon ?

    Nix, solang man dem Pointer kein Speicherbereich "zeigt".
    Wenn man mit der Funktion SysMemAlloc(); Speicher reserviert, liefert diese einen Zeiger auf den allokierten Bereich zurück --> man hat solang man nix reserviert nur 4Byte verbraten.
    Nachdem man den Inhalt seines reservierten Bereichs ausgewertet hat --> Speicher wieder freigeben.

    Diese Art der Programmierung hat dann nicht mehr viel mit SPS ansich zu tun.
    Es ist mehr für die Daten- sammlung und - auswertung von Nutzen.

    Ich habe mal einwenig damit experimentiert.
    Trotz dessen das ich nur auf allokierten Bereich zugegriffen hatte, kam nach mehrfachen allokieren und freisetzten von Speicherbereichen unterschiedlicher Größe, bei einem Speicherzugriff eine Access violation.

    Also Achtung und alles mit Vorsicht zu genießen.

    Grüße
    KlOis

     
  • mactoolz - 2011-02-20

    Hallo zusammen,

    als erstes wollte ich erwähnen dass in CoDeSys V.2.3 es keine Dynamischen Speicher gibt. Einen Speicher zu allokieren heißt noch lange nicht
    das er dynamisch ist.
    Dynamische Speicherrervierung ist erst dann dynamisch wenn er zur Laufzeit seine Größe verändert werden kann.

    Sobald ein Array mit einer Indexgröße deklariert wurde wird beim übersetzen der Speicher für die Größe des Arrays reserviert.

    arr: array[0..9] of Byte; --> folglich 10 Byte direkt durch compiler reserviert.

    Bei einem Zeiger wird erstmal ein DWORD als größe im Speicher belegt, dass bedeutet 4Byte.

    pntArr: array[0..9] of Byte; --> 4Byte

    Aber auch hier kann man von keiner dynamischen Allokierung sprechen. Weil die Feldgröße vom Array fest deklariert ist.
    Wenn man mit dem Zeiger Speicher reservieren will, durch SysMemAlloc, wird auch nur für die Größe
    des Arrays Speicher reserviert. Selbst wenn man versuchen würde und über die Größe die an SysMemAlloc übergeben wird
    eine größere Anzahl von Bytes reservieren wollte z.B. 20, wird als SizeOf(pntArr) = 10 Bytes zurück gegeben.

    Nur dann frage ich mich, wo sind die anderen Bytes hin ???

    Wozu braucht man denn Zeiger in CoDeSys. Ich könnte mir vorstellen wenn man größere FBs hat, diese über einen Zeiger
    zur Laufzeit den FB allokieren und wenn dieser nicht mehr benötigt wird wieder frei zu geben.

    Oder halt zur Laufzeit gewisse Anzahl von Bytes zu allokieren, Daten darin zu verarbeiten und wieder frei zu geben.
    In einem Programm mit Zeiger zu arbeiten ist vom Prinzip her das beste. Schnell, schneller geht es nicht, klar es liegt noch daran
    was dahinter an Quelltext liegt um mit dem Pointer zu arbeiten aber effektiv und Speicher sparend.

    Oder man hat ein

    arrPntListFb: array[0..9] of dword;

    und speichert hier viele verschiedene Adressen verschiedener FBs und man arbeitet mit dem Zeiger zu einem FB.
    Gut was dann dazu kommt das man wissen muss wie der FB aufgebaut ist damit man über die einzelenen Offsets der Variabeln
    den Zeiger verbiegt um an die Variabeln Werte zu kommen.

    Sicherlich sind Zeiger absolut gefährlich. Man ist sehr schnell da wo man nicht hin soll und die Steuerung steht ruck zuck. Ganz klar.

    Man darf aber nicht vergessen die ganzen Bibliotheken sind nicht in CoDeSys geschrieben sondern mindestens in C und dort
    werden definitiv Zeiger verwendet.

    Aber die schöne diskussion hat aber meine Frage nicht ganz beantwortet. Ich bin mir eigentlich sicher
    das die RTE den SysMemAlloc Befehl ausgeführt hat und jetzt nicht mehr. Obwohl die Anleitung schreibt das es nicht geht.
    Bin gerade irgendwie verwundert.

    Ich muss jetzt ins Bett .... bis später zur weiteren diskussion

    MacToolz

     
  • KlOis - 2011-02-21

    Moin Moin,

    Zitat:
    Selbst wenn man versuchen würde und über die Größe die an SysMemAlloc übergeben wird
    eine größere Anzahl von Bytes reservieren wollte z.B. 20, wird als SizeOf(pntArr) = 10 Bytes zurück gegeben.

    Ich denke mal du meinst ```

    SizeOf(pntArr^)

    Und den hast du als 
    

    pntArr: POINTER TO array[0..9] of Byte;

    ```
    deklariert. Deshalb gibt er immer 10 als Rückgabewert. Die Funktion "SizeOF()" weiß einfach nicht ob und wann du Speicher allokiert hast, sie gibt zurück wie groß der Speicherbereich sein sollte auf den der Pointer zeigt.

    Zitat:
    Nur dann frage ich mich, wo sind die anderen Bytes hin ???

    Die Stehen hinten dran. Ich weiß nicht was passiert wenn du auf pntArr^[11] z.B. zugreifst, aber theoretisch sollte da dein 12. Element stehen.

    Doch können die, die es nur benutzen, also wir, doch nur raten. Vielleicht kann sich in diesem offiziellen 3S Forum ja mal einer von 3S äußern.

    Zitat:
    Aber die schöne diskussion hat aber meine Frage nicht ganz beantwortet. Ich bin mir eigentlich sicher
    das die RTE den SysMemAlloc Befehl ausgeführt hat und jetzt nicht mehr. Obwohl die Anleitung schreibt das es nicht geht.
    Bin gerade irgendwie verwundert.

    Benutzt du seit dem ein anderes Target? Vielleicht das gleiche, aber eine neuere Version?

    Gruß
    Klaus

     

    Related

    Talk.ru: 11

  • mactoolz - 2011-02-21

    Hi,

    KlOis hat geschrieben:
    Doch können die, die es nur benutzen, also wir, doch nur raten. Vielleicht kann sich in diesem offiziellen 3S Forum ja mal einer von 3S äußern.

    was meinst du damit, ich kann gerade nicht folgen.

    KlOis hat geschrieben:
    Benutzt du seit dem ein anderes Target? Vielleicht das gleiche, aber eine neuere Version?

    Da habe ich schon nachgeschaut. Ich muss das nochmal prüfen was das ist. Laut Anleitung soll es ja nicht gehen.

    KlOis hat geschrieben:
    deklariert. Deshalb gibt er immer 10 als Rückgabewert. Die Funktion "SizeOF()" weiß einfach nicht ob und wann du Speicher allokiert hast, sie gibt zurück wie groß der Speicherbereich sein sollte auf den der Pointer zeigt.

    Da bin ich nicht der Meinung, dass hat nichts mit dem Sizeof zu tun. Das hat andere gründe. Normalerweise wäre die größe erstmal 0 weil kein Speicher allokiert wurde.
    Da aber wohl beim kompalieren automatisch der Speicher für den Pointer reserviert wird ist die Größe direkt als 10Byte zu ermitteln.

    Warum eigentlich ???
    Das könnte doch mal bitte jemand vom 3S erklären.
    Gibt es da eine logische Erklärung für ?

    MacToolz

     
  • KlOis - 2011-02-21

    Hey,

    Zitat:
    KlOis hat geschrieben:
    Doch können die, die es nur benutzen, also wir, doch nur raten. Vielleicht kann sich in diesem offiziellen 3S Forum ja mal einer von 3S äußern.
    was meinst du damit, ich kann gerade nicht folgen.

    Eigentlich das gleiche wie du, ich meine genau kann es keiner von uns sagen. Jemand von 3S sollte uns mal erleuchten

    Und ich habe gerade nochmal ein Test gestartet, die Funktion SIZEOF(); liefert immer das zurück wie groß der Bereich sein sollte:

    Die Variablen Deklaration:

       ptArByte1:                  POINTER TO ARRAY[1..10] OF BYTE;
       ptArByte2:                  POINTER TO ARRAY[1..20] OF BYTE;
       iSize1:                     INT;
       iSize2:                     INT;
       iSize1_1:                  INT;
       iSize2_1:                  INT;
       boTest2:                  BOOL;
    

    Na dann noch fröhliches Testen

    Klaus

    IMG: SysMemAlloc.PNG

     
  • mactoolz - 2011-02-21

    Hi,

    getestet habe ich das schon.

    Hoffentlich nimmt sich mal jemand vom 3S dieser Diskussion mal an.

    Mich würde das mal genau interessieren wie die Speicherverwaltung abläuft und vielleicht noch ein paar Tips
    was man z.B. mit dem Allokieren in der V.2.3 erreichen kann. Weil so ganz genau bin ich mir noch nicht im klaren ob meine Vorstellungen funktionieren würden.

    Momentan macht es gerade keine Sinn in der V.2.3 Version.

    Ich muss noch was nachtragen.
    Ich habe ein Doku bei mir gefunden die sich auf eine CoDeSys Versionen ab V.2.3.7.0 beziehen, die Doku SysLibs_Ueberblick
    darin steht explizit das in der RTE die SysLimMem.lib auf diesem Zielsystem funktioniert.

    Jetzt frage ich mich warum was anderes in der Hilfe steht???

    MacToolz

     
  • mactoolz - 2011-05-18

    Hallo zusammen,

    anscheinend hat niemand von 3S Lust uns darauf zu antworten. Wobei ich das für sehr sehr wichtig halte.

    Gut dann die nächste Frage. Vielleicht bewegt sich jemand vom 3S mal in dieses Thema

    Wieso ergibt dieser Aufruf genau 8Byte:
    SIZEOF(pdtKesselRegelung)

    TYPE pdtKesselRegelung :
    STRUCT
    bSoWinterUmsch : BYTE;
    bAbsenkKennlinie: BYTE; ( Absenkkennlinie / Nachtabsenkung )
    pdtState: pdtTypeNeigungNiveau;
    END_STRUCT
    END_TYPE

    TYPE pdtTypeNeigungNiveau :
    STRUCT
    bNeigung: BYTE;
    bNiveau: BYTE;
    END_STRUCT
    END_TYPE

    Sollten doch eher nur 4Byte sein und nichts anderes .... Also für mich ergibt das keine Logik ....

    Oder 3S ??? ....

    MacToolz

     
  • Erik Böhm - 2011-05-18

    Moin

    Schon mal die Beschreibung zu SIZEOF gelesen ?

    Zitat:
    Als Ergebnis liefert SIZEOF die Anzahl der Bytes, die die angegebene Variable benötigt.

    Auf einem 16 Bit System belegt ein Byte in der Regel 16 Bit, weil das die kleinste Speichereinheit ist.

    Gruß Erik

     
  • mactoolz - 2011-05-18

    Hallo,

    also ich glaube da habe ich in der Schule nicht aufgepasst, das muss mir nochmal jemand erklären.

    Was hat denn jetzt 16Bit Systembus mit der kleinsten Speichereinheit 16Bit (2Byte) zu tun ???

    MacToolz

     
  • Erik Böhm - 2011-05-18

    Hi

    Also es ist tatsächlich so, dass eine als Byte definierte Variable auf einem 8 Bit Prozessor (nicht Systembus, sondern Datenbusbreite des internen Speichers der CPU) auch wirklich 8 Bit belegt,
    auf einem 16 Bit Prozessor aber in der Regel 16 Bit, also genau so viel wie ein INT. Weshalb dann auch nichts gespart wird wenn anstatt INT ein Byte benutzt wird.

    SIZEOF macht das in diesem Fall völlig korrekt. Hat auch nicht mit IEC oder CoDeSys oder so zu tun. Das ist bei anderen Compilern genauso.

    Gruß Erik

     
  • Erik Böhm - 2011-05-18

    Wikipedia sagt dazu:
    A byte in this context is the same as an unsigned char, and may be larger than the standard 8 bits...

     
  • mactoolz - 2011-05-18

    Hi,

    wieso bekomme ich dann von sizeof 10Byte zurück bei

    arrTest:array[0..9] of Byte;

    Also die verschiedenen Datenbusarten habe ja nichts mit dem Speicherallokieren zu tun, sondern nur der Übertragung wie schnell das ganze von statten laufen soll.

    MacToolz

     
  • Erik Böhm - 2011-05-18

    Zitat:
    Also die verschiedenen Datenbusarten habe ja nichts mit dem Speicherallokieren zu tun, sondern nur der Übertragung wie schnell das ganze von statten laufen soll.

    Sorry, aber das ist nicht nur nicht ganz richtig, sondern grundsätzlich falsch.
    Das hat überhaupt nichts mit Geschwindigkeit zu tun, sondern wieviele Bits parallel übertragen werden.

    Früher gabs mal 8Bit Datenbus und 8Bit Adressbus.
    Was heisst, es können maximal 256 Speicherzellen adressiert werden, die jeweils 8Bit Daten enthalten.
    Das ist heute grundsätzlich noch genauso, nur eben mit mehr Bits.
    Drum kann z.B. ein 32 Bit System maximal 4GB Speicher adressieren

    Grundlagen Digitaltechnik

    Gruß Erik

     
1 2 3 > >> (Page 1 of 3)

Log in to post a comment.