Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched.
Close
Das ist dann das Problem von sogenannten "Füllbytes" in einer Datenstruktur.
Mach dir mal einen Pointer to Array of Byte auf die Struktur, und schau nach was da Byteweise im Speicher steht.
Wenn du in die Bytes der Struktur z.B. 1 , 2 , 3 , 4 reinschreibst, dann wird im Speicher folgendes stehen: 0 , 1 , 0 , 2 , 0 , 3 , 0 , 4.
Das ist dann genau dieses Problem mit den 16 Bit, weil die 8 nicht benötigten Bits aufgefüllt werden.
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Wenn ein Sizeof(BYTE) eine 1 zurückliefert, bzw. ein Sizeof(10Byte) eine 10, dann macht dein Compiler die Umrechnung.
Die Speicherbelegung ist aber trotzdem (Zielsystem und damit Prozessorabhängig) eine andere.
Das funktioniert aber bei der Struktur nicht mehr, weil hier die Daten an der Wortgrenze ausgerichtet werden(word alignment).
Sprich alle 16 Bit ein Byte, Rest mit nullen aufgefüllt.
Was den Sizeof(Struct) dann da zwangsläufig zu dem Ergebnis 8 bringen muss.
Aber wenn du mir das nicht glauben magst, kannst du auch gerne Google (odere jede andere Suchmaschine) befragen.
Ich mach jetzt nämlich Feierabend.
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Moin
Na ja, am einfachsten wärs natürlich wenn du aus BYTE INT machen würdest.
Dann wäre das Word-Alignment korrekt, SIZEOF würde das selbe Ergebnis liefern wie vorher und der Speicherverbrauch wäre natürlich auch der selbe.
Müssens unbedingt Bytres sein ?
Wen ja, kannst du ja beim auslesen aus dem Array ein casting auf byte machen.
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
jetzt bin ich voll auf dem Schlauch.
Also kurz meine Vorhaben. Ich habe eine Menge an Messwerten die ich in einer CSV Datei speichern möchte.
Ich nehme keine Stringvariabel um meine Daten zu speichern, das der String so rund 300 Zeichen oder mehr haben kann.
Habe mir eine Funktion geschrieben die mir jeden Datentyp in ein Array of Byte ablegt.
So war mein Gedanke, damit bin ich von der Stringgröße unabhängig.
Übergeben an die Funktion meine Größe des Datentyps, größe des Arrays und einen Offset etc.
Bis dato habe ich immer Real Variablen oder Fertige Strings in die Funktion gepackt und die im Array abgelegt. Jetzt muss ich noch verschiedenes Parameter
anhängen, die ich wie schon gesehen, in einer Struktur erstellt worden sind.
Jetzt habe ich nicht ganz verstanden wie das mit dem Typ INT sein soll. Das mit dem Word Alignment habe ich verstanden, ein INT auf dem 32 Bit System hat 4Byte.
Nur wo führt das jetzt hin.
MacToolz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Servus
Wenn nur die Stringlänge dein Problem ist, ein String kann auch deutlich länger als 300 Byte sein. 8000 Bytes funktionieren auf jeden Fall noch.
Die Beschränkung auf 255 Bytes betrifft nur die Stringfunktionen, wie CONCAT, MID, LEFT usw...
Einen CONCAT der die 8k kann könntest du von mir haben.
Dann kopierst du alle Messwerte nacheinander immer mit CONCAT in einen ausreichend lang definierten String und schreibst das
dann wenn du fertig bist komplett ins File.
SysFileWrite kann die Länge auch, dann sollte eigentlich kein Problem mehr übrig beliben...
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ne Concat ist doof. Erstens sind ja Stringfunktion total lahm ..... und zweitens gefällt mir das nicht
und außerdem sind es ja nicht nur Strings sondern auch Real etc....
Ich möchte vom Prinzip egal welcher Datentyp kommt auch wenn es ein eigener ist als
Byte ablegen und dann ins Dateihandling übergeben.
MacToolz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Das größte Problem ist ja wohl, dass deine Speicherbelegung (in Bytes) so aussieht: 0,1,0,2,0,3,0,4
Was aber auch nur auf Strukturen zutrifft, die ausschliesslich mit Bytes belegt sind.
Wenn in die Struktur noch andere Datentypen mit reinkommen wird das Ganze noch ungleich komplizierter, weil du
dann evtl. gar nicht mehr weisst was ein Füll- und was ein 'richtiges' Byte ist.
Wenn du jetzt noch anfängst die Strukturen auf feste Adressen zu legen, dann kanns sein, du hast die Füllbytes an verschiedenen Positionen innerhalb der Struktur.
Genau dieses Problem hatte ich schon mal...
Da muss ich jetzt leider sagen: Dafür hab ich momentan keine Lösung.
Ich überleg mal übers Wochenende (bin beim Snowboarden), vielleicht trifft mich ja einen Geistesblitz...
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Snowboarden bei den Außentemperaturen .... na dann viel Spaß.
Meine Überlegung war ohne SysMemCopy zu arbeiten und die einzelnen Bytes über eine while-Schleife auszulesen.
Nur was steht drinne in den Füllbytes??? Das werde ich mir anschauen.
Meine Überlegung ist nich dazu, was ist schneller SysMemCopy oder gleich schnell wie die while-Schleife?
SysMemCopy macht doch eigentlich nichts anderes fast wie die while-Schleife oder ?
Mein Versuch wäre folgender,
wenn die Füllbytes als Ascii 48 rauskommt, dann ist es die Zahl 0 als Zahl, wenn NULL das Ergebnis wäre kann man dies überspringen und das nächste Byte auslesen
Ich werde das mal gleich testen und berichten.
MacToolz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
tja das war nix. Also wenn ich mir jedes Byte anschaue steht dann irgendwas drin.
Aber es muss doch nach dem allokieren die Strukturen genuso byte für byte hintereinander abgelegt werden.
Darum verstehe ich nicht wieso ich da nicht dran komme ...
MacToolz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Nö, ich bin so schlau wie vorher.
Der Geistesblitz blieb leider aus. Und je länger ich drüber nachdenke, um so weniger glaube ich an ein Lösung.
Ich denke du solltest dir etwas grundsätzlich anderes ausdenken.
in dem Quellcode finde ich auch keinen Fehler.
Sollte so funktionieren.
Ich habs mal so probiert:
Zielsystem RTE
pntPdtRingBuffer: POINTER TO ARRAY[1..100] OF BYTE;
pdwTest: POINTER TO DWORD;
iSize: INT;
iSize := SIZEOF(pntPdtRingBuffer^);
iSize wird wie erwartet 100
ja moment mal, SP RTE ist doch das gleiche wie RTE oder ???
Und ich bin mir verdammt sicher das ich schonmal auf meinem Rechner in der SP RTE Speicher allokiert habe.
Ok, das mit der Hilfe hatten wir glaube ich schonmal oder, wenn ja ist es mir leider entfallen.
Trotzdem bin ich mir absolut sicher.
@Erik Böhm
Tja und nu bin ich sprachlos. Mal so am Rande, wie werden denn in anderen Programmiersprachen
für ganze Objekte Speicher reserviert, da gibt es diese Probleme nicht.
MacToolz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Das die SysMemLib auf der RTE nicht funktioniert hatten wir ja ganz am Anfang des Threads bereits.
Warum das so ist und ob die Doku dazu korrekt ist sollte bei 3S nachgefragt werden.
Bin ich immer noch der Meinung, dass die Allokierung in einem SPS Programm sowieso keiner braucht.
Gibts das Problem (oder besser diese Lösung des Problems) des WordAlignment und der Füllbytes auch auf jedem anderen System, das mehr als 8 Bit Datenbreite hat.
Gruß Erik
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Erik Böhm hat geschrieben:
Moin
Jetzt drehen wir uns aber langam im Kreis...
1. Das die SysMemLib auf der RTE nicht funktioniert hatten wir ja ganz am Anfang des Threads bereits.
Gruß Erik
Da hast du recht, sorry.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ich gebe es auf.
Sehr viele meiner Bausteine basieren darauf Speicher zu allokieren von daher weiß ich doch das es funktioniert hat.
Ob man diese Vorgehensweise braucht oder nicht ist erstmal nicht das Thema
Also, euch einen schönen Tag noch.
Bis dann, man liest sich ...
Änderung:
Ich muss nochmal schauen in welcher CoDeSys Version die Allokation ging.
MacToolz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
also ich habe mir das mit den FüllBytes nochmal ganz stark durch den Kopf gehen lassen.
Also FüllBytes kommen wir leider nicht drum rum.
Ist alles so wie es meine Vorschreiber schon stark erwähnt haben.
Nicht desto trotz möchte ich nicht immer wieder irgend welche Strukturen oder sonstiges FBs oder was auch immer
voll an eine Funktion oder was auch immer übergeben.
Wenn ich jetzt meinen Thread hier noch so recht im Kopf habe, könnte man folgendes tun.
Ich wollte mit Adressen arbeiten und entsprechend über eine Struktur die Adresse einer Variabel schreiben oder lesen etc.
Also zu meiner Idee und auch schon voll in der Umsetzung.
Ich versuche es mal in Worte zu fassen. Wird nicht einfach werden.
Da man ja in der Regel weiß wie Groß seine Daten sind, sollte man sich eine Struktur anlegen die genau
so groß dem Bereich sein sollte worin man z.B. Daten schreiben oder lesen und entsprechend umkopieren möchte.
Gehen wir einfach mal davon aus man hat einen Datenbereich z.B. von 100 Bytes.
Was auch immer darin steht ist ja erstmal egal.
Jetzt geht es um das befüllen der Bytes.
Man legt eine Struktur an die genauso groß ist. Es braucht ja natürlich nicht vom Typ Byte 100 Bytes sein sondern
alle möglichen Variabeltypen die wir haben.
Jetzt nimmt man seine Struktur irgendwo eine Variabel heraus, z.B. ein Real Wert.
der steht jetzt von den 100 ab dem 8Byte.
Man nimmt sich also die Adresse von dem 8Byte und kopiert die mit
der Adresse von der Sturkturvariabel auf die Zieladresse vom 8Byte mit dem SizeOf der SturkturVariabel.
Der einzige Nachteil darin ist das man im zusammen rechnen seiner Struktur sich nicht vertun darf,
da sonst die Startadresse nachher irgendwas verschoben quasi kopiert.
Kann mir da jemand folgen.
MacToolz
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
gut wenn du der Meinung bist.
Dann bitte die Frage beantworten wieso hier 10Byte rauskommen
arrTest:array[0..9] of Byte;
Danke
Servus
Das ist dann das Problem von sogenannten "Füllbytes" in einer Datenstruktur.
Mach dir mal einen Pointer to Array of Byte auf die Struktur, und schau nach was da Byteweise im Speicher steht.
Wenn du in die Bytes der Struktur z.B. 1 , 2 , 3 , 4 reinschreibst, dann wird im Speicher folgendes stehen: 0 , 1 , 0 , 2 , 0 , 3 , 0 , 4.
Das ist dann genau dieses Problem mit den 16 Bit, weil die 8 nicht benötigten Bits aufgefüllt werden.
Gruß Erik
Hi,
nochmal, das beantwortet nicht mein Frage. ????
Danke
MacToolz
Doch das tut es.
Wenn ein Sizeof(BYTE) eine 1 zurückliefert, bzw. ein Sizeof(10Byte) eine 10, dann macht dein Compiler die Umrechnung.
Die Speicherbelegung ist aber trotzdem (Zielsystem und damit Prozessorabhängig) eine andere.
Das funktioniert aber bei der Struktur nicht mehr, weil hier die Daten an der Wortgrenze ausgerichtet werden(word alignment).
Sprich alle 16 Bit ein Byte, Rest mit nullen aufgefüllt.
Was den Sizeof(Struct) dann da zwangsläufig zu dem Ergebnis 8 bringen muss.
Aber wenn du mir das nicht glauben magst, kannst du auch gerne Google (odere jede andere Suchmaschine) befragen.
Ich mach jetzt nämlich Feierabend.
Gruß Erik
Hi,
ok habe mir das ganze nochmal durch den Kopf gehen, ja da war mal was.
Aber wie kann ich denn jetzt meine Struktur trotz in einem Array of Byte speichern ???
Danke
MacToolz
Moin
Na ja, am einfachsten wärs natürlich wenn du aus BYTE INT machen würdest.
Dann wäre das Word-Alignment korrekt, SIZEOF würde das selbe Ergebnis liefern wie vorher und der Speicherverbrauch wäre natürlich auch der selbe.
Müssens unbedingt Bytres sein ?
Wen ja, kannst du ja beim auslesen aus dem Array ein casting auf byte machen.
Gruß Erik
Mahlzeit,
jetzt bin ich voll auf dem Schlauch.
Also kurz meine Vorhaben. Ich habe eine Menge an Messwerten die ich in einer CSV Datei speichern möchte.
Ich nehme keine Stringvariabel um meine Daten zu speichern, das der String so rund 300 Zeichen oder mehr haben kann.
Habe mir eine Funktion geschrieben die mir jeden Datentyp in ein Array of Byte ablegt.
So war mein Gedanke, damit bin ich von der Stringgröße unabhängig.
Übergeben an die Funktion meine Größe des Datentyps, größe des Arrays und einen Offset etc.
Bis dato habe ich immer Real Variablen oder Fertige Strings in die Funktion gepackt und die im Array abgelegt. Jetzt muss ich noch verschiedenes Parameter
anhängen, die ich wie schon gesehen, in einer Struktur erstellt worden sind.
Jetzt habe ich nicht ganz verstanden wie das mit dem Typ INT sein soll. Das mit dem Word Alignment habe ich verstanden, ein INT auf dem 32 Bit System hat 4Byte.
Nur wo führt das jetzt hin.
MacToolz
Servus
Wenn nur die Stringlänge dein Problem ist, ein String kann auch deutlich länger als 300 Byte sein. 8000 Bytes funktionieren auf jeden Fall noch.
Die Beschränkung auf 255 Bytes betrifft nur die Stringfunktionen, wie CONCAT, MID, LEFT usw...
Einen CONCAT der die 8k kann könntest du von mir haben.
Dann kopierst du alle Messwerte nacheinander immer mit CONCAT in einen ausreichend lang definierten String und schreibst das
dann wenn du fertig bist komplett ins File.
SysFileWrite kann die Länge auch, dann sollte eigentlich kein Problem mehr übrig beliben...
Gruß Erik
Hi,
ne Concat ist doof. Erstens sind ja Stringfunktion total lahm ..... und zweitens gefällt mir das nicht
und außerdem sind es ja nicht nur Strings sondern auch Real etc....
Ich möchte vom Prinzip egal welcher Datentyp kommt auch wenn es ein eigener ist als
Byte ablegen und dann ins Dateihandling übergeben.
MacToolz
OK. Dann sind wir ja wieder am Anfang
Das größte Problem ist ja wohl, dass deine Speicherbelegung (in Bytes) so aussieht: 0,1,0,2,0,3,0,4
Was aber auch nur auf Strukturen zutrifft, die ausschliesslich mit Bytes belegt sind.
Wenn in die Struktur noch andere Datentypen mit reinkommen wird das Ganze noch ungleich komplizierter, weil du
dann evtl. gar nicht mehr weisst was ein Füll- und was ein 'richtiges' Byte ist.
Wenn du jetzt noch anfängst die Strukturen auf feste Adressen zu legen, dann kanns sein, du hast die Füllbytes an verschiedenen Positionen innerhalb der Struktur.
Genau dieses Problem hatte ich schon mal...
Da muss ich jetzt leider sagen: Dafür hab ich momentan keine Lösung.
Ich überleg mal übers Wochenende (bin beim Snowboarden), vielleicht trifft mich ja einen Geistesblitz...
Gruß Erik
Hi,
Snowboarden bei den Außentemperaturen .... na dann viel Spaß.
Meine Überlegung war ohne SysMemCopy zu arbeiten und die einzelnen Bytes über eine while-Schleife auszulesen.
Nur was steht drinne in den Füllbytes??? Das werde ich mir anschauen.
Meine Überlegung ist nich dazu, was ist schneller SysMemCopy oder gleich schnell wie die while-Schleife?
SysMemCopy macht doch eigentlich nichts anderes fast wie die while-Schleife oder ?
Mein Versuch wäre folgender,
wenn die Füllbytes als Ascii 48 rauskommt, dann ist es die Zahl 0 als Zahl, wenn NULL das Ergebnis wäre kann man dies überspringen und das nächste Byte auslesen
Ich werde das mal gleich testen und berichten.
MacToolz
Hi,
tja das war nix. Also wenn ich mir jedes Byte anschaue steht dann irgendwas drin.
Aber es muss doch nach dem allokieren die Strukturen genuso byte für byte hintereinander abgelegt werden.
Darum verstehe ich nicht wieso ich da nicht dran komme ...
MacToolz
Hallo,
so langsam bekomme ich einen Vogel.
Warum allokiert der mir jetzt nicht meinen gewissen Speicherbereich.
pntPdtRingBuffer := SysMemAlloc(SIZEOF(pntPdtRingBuffer^)); ( Speicher allokieren )
Ich erhalte keinen Zeiger !!!!!!
@Erik Böhm
Ist dir eine Idee wegen den Füllbytes beim Snowboarden eingefallen ... ???
MacToolz
Servuz,
liefert die SIZEOF Funktion einen Wert >0 zurück?
ist vielleicht dein Speicher aufgebraucht?
Ich weiß, es sind einfache Dinge, aber die übersieht man ja gerne mal, da man davon ausgeht das diese hin hauen.
Gruß
KlOis
Hi
Nö, ich bin so schlau wie vorher.
Der Geistesblitz blieb leider aus. Und je länger ich drüber nachdenke, um so weniger glaube ich an ein Lösung.
Ich denke du solltest dir etwas grundsätzlich anderes ausdenken.
in dem Quellcode finde ich auch keinen Fehler.
Sollte so funktionieren.
Ich habs mal so probiert:
Zielsystem RTE
pntPdtRingBuffer: POINTER TO ARRAY[1..100] OF BYTE;
pdwTest: POINTER TO DWORD;
iSize: INT;
iSize := SIZEOF(pntPdtRingBuffer^);
iSize wird wie erwartet 100
pdwTest := SysMemAlloc(100); ( Speicher allokieren )
pdwTest bleibt <00000000>
Da hätte ich was anderes erwartet...
Gruß Erik
Hello Again,
Aus der Hilfe vom CoDeSys >Zitat:
Die Funktion wird von CoDeSys SP RTE nicht unterstützt.
Ich habe auch ein RTE und es mal getestet, bei mir tut es, ist wohl doch sehr Zielsystemabhängig!
mein Code:
Hi,
ja moment mal, SP RTE ist doch das gleiche wie RTE oder ???
Und ich bin mir verdammt sicher das ich schonmal auf meinem Rechner in der SP RTE Speicher allokiert habe.
Ok, das mit der Hilfe hatten wir glaube ich schonmal oder, wenn ja ist es mir leider entfallen.
Trotzdem bin ich mir absolut sicher.
@Erik Böhm
Tja und nu bin ich sprachlos. Mal so am Rande, wie werden denn in anderen Programmiersprachen
für ganze Objekte Speicher reserviert, da gibt es diese Probleme nicht.
MacToolz
Ich wollte nur nochmal auf die kontroversen Hinweise deuten.
In Objektorientierten Sprachen geschieht dies entweder durch Konstruktoren oder auch durch Allokierungsbefehle.
Gruß
KlOis
Moin
Jetzt drehen wir uns aber langam im Kreis...
Das die SysMemLib auf der RTE nicht funktioniert hatten wir ja ganz am Anfang des Threads bereits.
Warum das so ist und ob die Doku dazu korrekt ist sollte bei 3S nachgefragt werden.
Bin ich immer noch der Meinung, dass die Allokierung in einem SPS Programm sowieso keiner braucht.
Gibts das Problem (oder besser diese Lösung des Problems) des WordAlignment und der Füllbytes auch auf jedem anderen System, das mehr als 8 Bit Datenbreite hat.
Gruß Erik
Da hast du recht, sorry.
Hallo zusammen,
ich gebe es auf.
Sehr viele meiner Bausteine basieren darauf Speicher zu allokieren von daher weiß ich doch das es funktioniert hat.
Ob man diese Vorgehensweise braucht oder nicht ist erstmal nicht das Thema
Also, euch einen schönen Tag noch.
Bis dann, man liest sich ...
Änderung:
Ich muss nochmal schauen in welcher CoDeSys Version die Allokation ging.
MacToolz
Hallo zusammen,
ich hab eine Idee, habe aber jetzt keine Zeit und werde mal die Tage
das Problem mit den Füllbytes klären.
Ich stelle das dann mal Online.
Bis später mal ...
Wenn Interesse an meiner Idee besteht mal bescheid sagen
MacToolz
Klar, ein Happy End wär doch mal super
Hallo zusammen,
also ich habe mir das mit den FüllBytes nochmal ganz stark durch den Kopf gehen lassen.
Also FüllBytes kommen wir leider nicht drum rum.
Ist alles so wie es meine Vorschreiber schon stark erwähnt haben.
Nicht desto trotz möchte ich nicht immer wieder irgend welche Strukturen oder sonstiges FBs oder was auch immer
voll an eine Funktion oder was auch immer übergeben.
Wenn ich jetzt meinen Thread hier noch so recht im Kopf habe, könnte man folgendes tun.
Ich wollte mit Adressen arbeiten und entsprechend über eine Struktur die Adresse einer Variabel schreiben oder lesen etc.
Also zu meiner Idee und auch schon voll in der Umsetzung.
Ich versuche es mal in Worte zu fassen. Wird nicht einfach werden.
Da man ja in der Regel weiß wie Groß seine Daten sind, sollte man sich eine Struktur anlegen die genau
so groß dem Bereich sein sollte worin man z.B. Daten schreiben oder lesen und entsprechend umkopieren möchte.
Gehen wir einfach mal davon aus man hat einen Datenbereich z.B. von 100 Bytes.
Was auch immer darin steht ist ja erstmal egal.
Jetzt geht es um das befüllen der Bytes.
Man legt eine Struktur an die genauso groß ist. Es braucht ja natürlich nicht vom Typ Byte 100 Bytes sein sondern
alle möglichen Variabeltypen die wir haben.
Jetzt nimmt man seine Struktur irgendwo eine Variabel heraus, z.B. ein Real Wert.
der steht jetzt von den 100 ab dem 8Byte.
Man nimmt sich also die Adresse von dem 8Byte und kopiert die mit
der Adresse von der Sturkturvariabel auf die Zieladresse vom 8Byte mit dem SizeOf der SturkturVariabel.
Der einzige Nachteil darin ist das man im zusammen rechnen seiner Struktur sich nicht vertun darf,
da sonst die Startadresse nachher irgendwas verschoben quasi kopiert.
Kann mir da jemand folgen.
MacToolz
Halloooooooo,
Statement dazu ....
MacToolz