Pointer in ein Byte Array umwandeln

kai86

Level-1
Beiträge
158
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

brauche kurz mal eure Hilfe.
Ich habe eine Funktion die hat als Eingangsparameter ein Pointer und eine Länge.

der Pointer zeigt auf ein Byte Array und die Länge sagt mir wie lang das halt ist. nun will ich jedes Byte einzeln auslesen über eine for schleife.

for i:= 0 TO länge DO
byte := BytePointer;
END_FOR;

so gehts nicht aber irgendwie so was in der art hätte ich gern.

Vielleicht stehe ich gerade auf dem Schlauch, aber habe gerade keine Idee wie es geht. Bitte kein BlockMov oder irgendwas mit AnyPointern :) muss auch irgendwie anders gehen.
 
Bitte kein BlockMov oder irgendwas mit AnyPointern :) muss auch irgendwie anders gehen.

Hallo,
ich wntnehme deinem Code-Schnipsel, dass du mit SCL arbeiten möchtest ... ist aber eigentlich auch egal, da es kein abweichendes Vorgehen gibt.
Du übergibst deinem Baustein via ANY-Pointer das Array. Nun enthält der ANY-Pointer alle benötigten Informationen. Du mußt nun den ANY-Pointer in seine Grundbestandteile zerlegen (das ginge in SCL mit einer AT-Sicht) und kannst damit dann deine Schleife füttern.
Einen anderen Weg gibt es nicht ...

Was machen wir da nun ?

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich bekomme keinen Any-Pointer sondern nur einen einfachen Pointer.
Den kann ich zerlegen und intern immer nach oben zählen. Das ist richtig. Aber wie mache ich aus dem Pointer ein Byte, darauf komme ich gerade nicht, das geht doch sicher irgendwie. Hast du da eine Idee Larry
 
... und du willst das mit SCL machen ?

Der Pointer ist eine 6 Byte breite Struktur (siehe hierzu auch die Sztep7-Hilfe).
In Byte 0 und 1 steht die DB-Nummer als Absolutwert oder 0 wenn die Datenquelle kein DB ist.
In Byte 2 steht die Hex-Kennung des Quell-Speicher-Bereichs. Entsprechend dieser mußt du dann die Adressierung deiner Datenquelle vornehmen.
In den Bytes 3-5 steht der Bit-Pointer auf die Quell-Adresse. Brauchst du hier die Byte-Adresse so mußt du diesen Wert noch durch 8 dividieren.

Kannst du das umsetzen ?
 
Hallo,


for i:= 0 TO länge DO
byte := BytePointer;
END_FOR;

so gehts nicht aber irgendwie so was in der art hätte ich gern.

Vielleicht stehe ich gerade auf dem Schlauch, aber habe gerade keine Idee wie es geht. Bitte kein BlockMov oder irgendwas mit AnyPointern :) muss auch irgendwie anders gehen.



Hallo Kai,

so wie du das gemachts hast, schreibst du in jedem Schleifendurchlauf den Wert der verschiedenen Byte auf die gleiche Variable. Am Ende steht dann der Wert von Byte[Länge] in dem Byte.

Wenn du das Ganze umkopieren willst müßte der Code so aussehen:
For n := i to Länge Do
Byte1 := byte2
End_For;

Oder hab ich was falsch verstanden?

Gruss,
Piloti
 
Das ich alles in ein byte schreibe ist mir klar.
War auch nur als Beispiel gedacht.

@Larry das kriege ich schon hin mit dem AT

damit kann ich immer den zeiger um 1 Byte erhöhen.

aber wie bekomme ich wenn der Zeiger nun auf ein Byte in einem DB zeigt den Wert aus dem DB.

byte := Pointer^; oder wie es auch immer gehtich will gerade einfach nur noch einen Wert haben auf den der Pointer gerade zeigt.

byte := Pointer; glaube ich nicht das es geht. aber vielleicht ist das auch möglich mal testen.
 
also direkt gehts nicht.
hätte mich auch gewundert.

byte := Pointer; <---- ich will den Wert worauf der Pointer zeigt.

muss doch gehen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Kai,

wie schon gesagt mußt du den pointer zerlegen. Hast du dir dazu die Step7-Hilfe mal angesehen ?

Das zerlegen in SCL könnte so in etwa aussehen :
Code:
FUNCTION_BLOCK FB500     
//     Bausteinparameter
VAR_INPUT
   PEW_Adr : POINTER ; 
   a_PEW_Adr AT PEW_Adr : STRUCT
                          DB_Nr   : INT ;
                          Mem_Ptr : DWORD ;
                          END_STRUCT ;
END_VAR

VAR_IN_OUT
END_VAR

VAR_OUTPUT
   Mem_Typ : BYTE ;
   Mem_Adr : INT ; 
END_VAR

VAR_TEMP
   Mem_Ptr : DWORD ; 
END_VAR

//     Anweisungsteil
BEGIN
   Mem_Typ := DWORD_TO_BYTE(SHR (IN:=a_PEW_Adr.Mem_Ptr , n:=24)) ;
   Mem_Ptr := a_PEW_Adr.Mem_Ptr AND dw#16#00FF_FFFF ;
   Mem_Adr := DWORD_TO_INT(SHR (IN:=Mem_Ptr , n:=3)) ;
END_FUNCTION_BLOCK
Der Code sollte so funktionieren.
Wenn ich es richtig in Erinnerung habe so kannst du in SCL nur bei einem FB eine AT-Sicht auf einen Pointer machen.

Probier mal mit dem Code ...

Gruß
Larry
 
Hallo,

in SCL bin ich überhaupt nicht fit, aber was Kai will würde in AWL ungefähr so aussehen:
(Nachdem er den Pointer zerlegt hat)

Code:
L DBB [#Pointer]
T DBB xy
#Pointer = Byteadresse

vllt. kann Larry das ja übersetzen.

Grüße
Gebs
 
Zuletzt bearbeitet:
@piloti:
Sprechen du und der TE von der gleichen Sache ?

Sorry, hast recht. Irgendwie paßt das nur zur Hälfte.
Dachte das Problem ist, dass in jeder Schleife immer wieder die gleiche Variable beschrieben wird.

Was ist das denn für eine Funktion mit den Eingängen Pointer und Länge?
Was macht diese genau und wo liegen die Bytesarrays auf die über den Pointer zugegriffen werden kann?

Gruss, piloti
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ok ich hole kurz weiter aus.
das soll eine funktion werden.
Die benutze ich später um Byte Arrays in meinen TCP-SendeBuffer zu kopieren. Für das Buffer kopieren und damit alle ringpuffer Pointer vernünftig überwacht werden gibt es eine funktion writeByte() die mir ein Byte in meinen Buffer schreibt(samt sonstigen sachen die ich dabei noch mache).

was ich jetzt machen will ist. eine funktion wo ich ein Byte Array rein gebe und alle Bytes einzeln mit meiner Funktion in den SendeBuffer schreibe.
klar gehts sicher einfacher über Blkmov oder ähnliches aber ich würde es gern über die writeByte funktion machen, weil da wie gesagt auch Fehlerüberwachung statt findet, wie was ist wenn der Buffer voll ist usw.

das was Larry gepostet hat habe ich irgendwo schonmal gesehen in einem anderen Beitrag, ich habe nur gehofft das es auch eleganter geht.

was mich dabei noch verwirrt, das Format vom Pointer sieht eigentlich anders aus und steht so nicht in den ersten 3 Bytes.

DB Nummer in den ersten beiden Bytes und die Byte und Bit Addresse in den letzen 19Bits.
 
ich hätte es ehr so gemacht um den Pointer zu manipulieren.

Code:
 val     : POINTER;
 val_REF AT val: STRUCT
        temp1   : ARRAY[0..28] OF BOOL; //irgendwelche anderen sachen
        byteAdr : INT;
        bitAdr  : ARRAY[0..2] OF BOOL;
 END_STRUCT;
damit kann man dann die ByteAdr Problemlos hochzählen hätte ich gesagt.

aber wie ich nun den Wert an der Stelle auslese habe ich immer noch nicht gerafft.
ich schau mir das nochmal von larry an aber das sah glaube ich nur nach pointer manipulation aus
 
@Kai:
Sorry ... das ist schon der eleganteste Weg.
Und ... wenn ich mich da jetzt nicht vertippt habe dann ist so auch so OK wie gepostet ...
Aus dem Mem_Ptr extrahiere ich den Quell-Datentyp und, bilde die Byte-Adresse und durch "rechts-schieben" die Byte-Adresse.

Am Besten du testest es einfach mal ... ;)

Wenn du allerdings mit einem FB-Send (oder -Receive) arbeiten willst so kannst du den in SCL auch sehr elegant mit einem lokal-statisch angelegten Sende-Puffer (oder Empfangspuffer) versorgen und mußt keine großen "Klimmzüge" machen.

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Kai:
dein Beispiel wird gar nicht funktionieren, da in der AT-Sicht alle Einzel-Variablen immer an der Byte-Adresse oder Wort-Adresse ausgerichtet werden. Mit deinem Code-Beispiel bildest du eine AT-Sicht auf eine 7 Byte große Struktur - auch einfach mal ausprobieren - bei dir wird ggf. der Compiler schon "meckern" ...
 
ok aber meine eigentlich frage ist immer noch nicht geklärt.
wie bekomme ich in scl aus einem Pointer, den Byte Wert an der Stelle wo der Pointer hin zeigt.

@larry hast recht der meckert der doofe
 
:confused: ... benutze einfach meinen Code und in Mem_Adr steht dann die Byte-Adresse des im Pointer übergebenen Bytes - wie gesagt ... einfach mal ausprobieren ... ;)
 
Zurück
Oben