AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Verdrehte Bits (Wilde Pointereien)

Ein Thema von Phoenix · begonnen am 16. Aug 2007 · letzter Beitrag vom 4. Sep 2007
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.640 Beiträge
 
#1

Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 19:59
Ich lese (soll lesen) Daten aus einer SPS aus und packe diese in eine Datenbank.

Das klappt einwandfrei. Folgendes steht Testweise in der SPS und dann auch im Blob:
Code:
00 01 00 14 00 1E 00 28 00 32 00 3C 00 00 00 00 00 00 00 00
Nun lese ich den Blob und packe den aus Performancegründen in einen selber allokierten Speicherbereich mit der Länge des Datenbausteins.

Um gezielt auf einzelne Bytes zugreifen zu können, speichere ich den Pointer aus GetMem als PByteArray.
Greife ich nun so auf die Daten zu:
Delphi-Quellcode:
i := 0;

while i < dm.ModuleLength do
begin
  Memo1.Lines.Add('Byte ' + IntToStr(i) + ' : ' + IntToStr(dm.Bytes[i]));
  Inc(i);
end;
Wobei dm mein Datenbaustein (DataModule) ist und dm.Bytes folgendermassen deklariert ist:
Delphi-Quellcode:
FData: PByteArray;
property Bytes[AIndex: Integer]: Byte read GetBytes;
//...
function PLCDataModule.GetBytes(AIndex: Integer): Byte;
begin
  Result := FData^[AIndex];
end;
Bekomme ich folgende Ausgabe:
Code:
Byte 0 : 0
Byte 1 : 1
Byte 2 : 0
Byte 3 : 20
Byte 4 : 0
Byte 5 : 30
Byte 6 : 0
Byte 7 : 40
Byte 8 : 0
Byte 9 : 50
Byte 10 : 0
Byte 11 : 60
Byte 12 : 0
...
Was exakt das ist, was ich erwarte.

Nun zum Problem:

Manche Datenbereiche in der SPS sind größer als ein Byte. In der Regel habe ich es mit 2- oder gar 4 Byte grossen Einträgen zu tun, die ich gegen Bitmasken mit verschiedenen Operatoren (Gleichheit, invertiert verandetet) prüfen muss, um bestimmte Status abzufragen. Diese Bitmasken kann ich also wahlweise als Integer oder als Cardinal speichern. Zur Zeit sind es Integers.

Da die Datenbereiche aber Unregelmässig sind (z.B. 1 Byte, 1 Byte, 6 Byte) kann ich den Pointer nicht auf ein Integer-Array umcasten und den Index (Startbyte) durch 4 Teilen. Das heisst ich muss von einem Pointer auf ein Byte 4 Bytes lesen.

Das mache ich so:
Result := PInteger(Integer(FData) + AIndex)^; Rufe ich das in der gleichen Schleife wie oben alle 4 Bytes, beginnend beim Nullten, auf, bekomme ich folgende Ausgabe:
Code:
Wert 0 : 335544576
Byte 0 : 0
Byte 1 : 1
Byte 2 : 0
Byte 3 : 20
Wert 1 : 671096320
Byte 4 : 0
Byte 5 : 30
Byte 6 : 0
Byte 7 : 40
Wert 2 : 1006645760
Byte 8 : 0
Byte 9 : 50
Byte 10 : 0
Byte 11 : 60
Das ist nicht, was ich erwarte. Denn wenn ich diese Werte in binäre Daten umwandele, dann erhalte ich folgendes:

Code:
Byte 0 - 11 laut der ersten Einzelbyte-Ausgabe:

0  = 00000000 
1  = 00000001
0  = 00000000
20 = 00010100

0  = 00000000
30 = 00011110
0  = 00000000
40 = 00101000

0  = 00000000
50 = 00110010
0  = 00000000
60 = 00111100

Laut dem Windows-Calculator haben diese 3x4 Bytes folgende Werte:

00000000 00000001 00000000 00010100 b =  65556 d
00000000 00011110 00000000 00101000 b = 1966120 d
00000000 00110010 00000000 00111100 b = 3276860 d

Die Werte aus der Ausgabe geben jedoch:

00010100 00000000 00000001 00000000 b = 335544576 d
00101000 00000000 00011110 00000000 b = 671096320 d
00111100 00000000 00110010 00000000 b = 1006645760 d
Warum verdreht die andere Zahlendarstellung auf einmal meine Bytes?
Ich meine, sie stehen ja offenbar auch definitiv andersrum im Speicher.

Nur wenn ich einen Status definiere, der z.B. die ersten 4 Bits prüfen soll, und dann
Code:
11110000 00000000 00000000 00000000 vs.
00000000 00000000 00000000 11110000
verglichen wird, dann gibt das freilich ein False, obwohl ich ein True bräuchte.

Was kann ich da machen?
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#2

Re: Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 20:13
Das schnellste ist ein "BSWAP" (inline-Assembler).

Das Problem ist das Gleiche in Windows. Sobald nämlich mehr als ein Byte dabei ist, kommst du in Probleme mit der Byte-Reihenfolge, zumindest ist das theoretisch der Fall.

Suche hier:
http://jedi-apilib.cvs.sourceforge.n...11&view=markup
nach "RtlUlongByteSwap" und kopiere den Code. Ist von mir und du darfst es auch ohne die MPL/LGPL verwenden. Wegen einem zweibytigen Opcode muß ich keine Erwähnung irgendwo haben

Auch:
MSDN-Library durchsuchenhtonl
MSDN-Library durchsuchenntohl

Ach was, hier ist sie:

Delphi-Quellcode:
function RtlUlongByteSwap(Source: ULONG): ULONG;
asm
  // This is not written as mnemonics to be compatible with D4!
  db 0Fh, 0C8h // "bswap EAX" can only be executed on 486+!!!
(*
  // Does the same but perhaps slower ...
                        // Source = $11223344
  rol  AX,  08h        // Source = $11224433
  rol  EAX, 0Fh        // Source = $44331122
  rol  AX,  08h        // Source = $44332211
*)

end;
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.640 Beiträge
 
#3

Re: Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 20:30
Hrm. Ich hab mir grad meine SPS-Layout-Konfiguration zerlegt, weil ich blöderweise von der Datenbank nur Integer lese und der mir natürlich dank Vorzeichen irgendwann umkippt. Jetzt hab ich Kopfschmerzen und keinen Nerv mehr dafür.

Als was ist denn ULONG definiert?

Und würde es ggf. reichen, hier bei meinen Operationen die Bereichsprüfung zu deaktivieren, damit ich auch Werte > MAX_INT in einen int Reinschreiben kann, solange meine Bitfolge passt?
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 20:34
Hi,

Zitat:
Als was ist denn ULONG definiert?
Delphi-Quellcode:
uses Windows;

type
 ULONG = Cardinal;
Gruß
Neutral General
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#5

Re: Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 20:46
Vorzeichenloser 32bittiger Ganzzahltyp.

Übrigens:

DWORD und PDWORD sind auch in Windows.pas deklariert und ULONG entspricht DWORD, womit nix mehr "umkippt"
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.640 Beiträge
 
#6

Re: Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 22:04
Ich glaub ich pack die 'Bitmaske' dann am besten als Float in die Datenbank und Runde die dann beim wieder auslesen auf einen ganzzahligen DWORD.

Dann hab ich auch kein Problem mit dem Eingabeformular, das ist ein bisschen Tricky, weil ich da die Bitmaske als String von 0 und 1, als einzelne Checkboxen für jedes Bit und eben als Zahl eingeben kann.

Und sollte irgend ein SPS'ler irgendwann mal meinen, er müsste 5 oder gar 6 Byte für ein Gerät verwenden, dann hab ich damit auch keine Probleme
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.859 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 22:51
Hallo Phoenix,

rein interessehalber, liest Du die Daten aus der SPS, oder werden die Daten von der SPS gesendet?

Bis bald Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.640 Beiträge
 
#8

Re: Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 23:07
Ich fetche sie selber aus der SPS. Die sendet nix von alleine.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Benutzerbild von Chemiker
Chemiker

Registriert seit: 14. Aug 2005
1.859 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 23:16
Hallo Phoenix,

Aber normalerweise kann die SPS doch Dir die Daten zur Verfügung stellen. Durch einen Timer (z.B.: jede Sekunde) in der SPS können die Messdaten doch übermittelt werden, oder liest Du das Programm der SPS?

Bis bald Chemiker
wer gesund ist hat 1000 wünsche wer krank ist nur einen.
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.640 Beiträge
 
#10

Re: Verdrehte Bits (Wilde Pointereien)

  Alt 16. Aug 2007, 23:42
Nein, ich lese die Datenbausteine aus. Aber es geht hier nicht nur um Messdaten, sondern um eine komplette gesteuerte Anlage, von der ich alle - also wirklich sämtliche - Status brauche.

Wenn die SPS mir die Daten aktiv sendet, geht das von der Zykluszeit ab.
Wenn ich die Daten hingegen selber fetche, dann erzeugt das keine Last auf der SPS.

Und wenn da tausende kleiner Pakete durch eine Anlage flitzen, dann braucht die SPS jede Millisekunde die sie bekommen kann, um die rechtzeitig an die richtige Stelle zu schubsen Wenn dann so ein Kerle daher kommt, und sich dann auch noch Daten - nur um sie hybsch an einem Monitor anzuzeigen - senden lassen will, dann lachen die SPS-Programmierer mal herzhaft und lassen den Kerle - also mich - links liegen

Edit Nachtrag: Verdammich. Ich werde mich NIE an Status als Mehrzahl von Status gewöhnen. *brr*
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:21 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz