# C-Script Datenformat INT/Word???



## sailor (28 Juni 2010)

Hallo,
in einen C-Script (WINCC7) lese ich eine Rohdatenvariable:

*#define RawTag "Raw1"
struct{
 int Stat1;
 int Stat2;
 usw.}
getTagRaw(RawTag,(Byte*)&RStat,32)
SetTagSWord("last_val_1",RStat.Stat1);
SetTagSWord("last_val_2",RStat.Stat2);
usw.
*Es kommt die Warnung :conversion may loose information
und es werden nur jeder 2. Wert gelesen!!!!
Stimmt da was mit den Datenformat nicht???
Nur wenn ich SetTagDouble... schreibe, kommt keine Warnung, aber es wird trotzdem nur jeder 2. Wert gelesen/geschrieben.
Aber Int ist doch integer mit 16 Bit und double 32 Bit, oder?
 Gruß
Sailor


----------



## Bender25 (28 Juni 2010)

Auf die schnelle versuch mal
GetTagRaw(RawTag,(BYTE*)&RStat,sizeof(RStat)

zu dem anderen Problem >> mit conversion may loose information sollte dann weg sein

*SetTagSWord (WORD) ("last_val_1",RStat.Stat1);*


ohne Gewähr*g* und eine bitte an die C-Götter. Bitte nicht verbal fertig machen wenn es nicht 100%ig richtig ist


----------



## sailor (28 Juni 2010)

Nee. gleicher Effekt. Die Rohdatenvariable ist ne Variable vom Typ Rohdaten Adressierung Wort Länge 96
Das (WORD) will er überhaupt  nicht


----------



## Bender25 (28 Juni 2010)

Zu welchem Problem der gleiche effekt?


----------



## sailor (28 Juni 2010)

Das nur jeder 2. Wert der Rohdatenvariablen gelesen wird.
Irgenwie scheinen da 32 Bit im Spiel zu sein, ich weiss nur nicht wo.
Mögen die C-Götter mir armen AWL/FUP-Knilch gnädig sein


----------



## Bender25 (28 Juni 2010)

hm also normal sollte es so funktionieren. Zumindest tut es bei mir so.

Bei der Adressierung der Variable was ist da ausgewählt? Byte? oder dann in deinem fall Doppelwort vieleicht? Vieleicht funktioniert es deswegen nicht?


----------



## sailor (28 Juni 2010)

Ich hab in der Adressierung der Rohdaten schon alles probiert (Byte,Wort,Doppelwort). Alles schon probiert. 
Hier nochmal der ganze Mist:
#define RawTag  "Raw1"
struct {
    int Stat1;
        int Stat2;
        int Stat3;
        int Stat4;
        int Stat5;
        int Stat6;
        int Stat7;
        int Stat8;  
            } RStat;

GetTagRaw(RawTag,(BYTE*)&RStat,sizeof(RStat));
SetTagSWord("last_C1_S1",RStat.Stat1);
SetTagSWord("last_C1_S2",RStat.Stat2);    
SetTagSWord("last_C1_S3",RStat.Stat3);
last_C1_S1 sind interne vorzeichenlose 16-Bit-Variable
RAW1 ist Variable DB21 Adressierung Wort ab DBB96 Rohdaten angewählt, Länge 32


----------



## Bender25 (28 Juni 2010)

Hm also ich hab auch kein Plan mehr. Ich lese alle meine Variablen so ein.
Nur das ich den Status der Variable noch mit nehme und diese noch auswerte. Aber sonst ist es bei mir ebenfalls so wie bei dir und es geht.

Werden denn die Werte, die geschrieben werden, auch richtig geschrieben? Liegt es vieleicht am Low/High Byte tausch?


----------



## sailor (28 Juni 2010)

Also ich tausche in der CPU von der 16 Bit Variable Hi mit Lo-Byte, damit wird die Variable in der Visu auch richtig dargestellt. Es sind alles WORD-Variable(hab auch schon Integer probiert)
Was ich aber jetzt gesehen hab: Egal was ich in der Adressierung der Rohdatenvariable angib(Byte,Wort, DW) es ist egal!!?? es sind immer 32 Bit, die da angesprochen werden. Hast Du Version 7.0?


----------



## Bender25 (28 Juni 2010)

Gerade nicht zur hand Arbeite auf einer 5er Version. Aber ich hab die Bilder von dort genommen sprich die Anzeigen laufen auch auf WinCC 7

also ich bin jetzt echt ratlos. Keine Ahnung mehr.

Sprich Stat 1, Stat 3, Stat 5 usw. diese werden geschrieben.

Wasist wenn die Daten richtig gelesen werden aber schreiben nicht richtig funktioniert? 
Versuch doch mal mit SetTagXXXWait  Wobei ich nicht denke das dies  das Problem ist


----------



## sailor (28 Juni 2010)

Also: Stat1 Stat 2 werden schon geschrieben, aber mit den falschen werten!!! Aber die werden wie 32 Bit behandelt. Irgendwas ist mit Rohdatenvariablen faul, glaub ich. Aber was? Ich hab eine SoftSPS (RTX) auf den gleichen PC laufen. Vieleicht liegts daran ??


----------



## Bender25 (28 Juni 2010)

bin überfragt. Sorry. Hast keine S7 da?


----------



## sailor (28 Juni 2010)

Doch. Probier ich mal . Bin aber die nächsten 3 Tage unterwegs.
Hab mit dem Sch... auch Kollege S supportrequestet.
trotzdem Danke
Melde mich hier wieder
Gruß
Sailor


----------



## Thomas_v2.1 (28 Juni 2010)

Hallo,
bei C ist es so dass ein Integer mindestens 16 Bits breit sein muss, aber er durchaus größer sein kann. Auf gängigen PC-Prozessoren ist ein int zur Zeit üblicherweise 32 Bit breit.
Überprüfen kannst du das in deinem C-Code indem du dir mal die Ausgabe von sizeof(int) ansiehst. Ich schätze mal dass dort 4 Bytes zurückgegeben werden.

Das passt dann eben mit deinem GetTagRaw() und deiner Struktur nicht mehr zusammen. Es gibt aber Datentypen bei denen die Anzahl der Bits fest vorgegeben ist. Da wären z.B. der Typ BYTE (1 Byte) und der Typ WORD (2 Byte) (dies ist kein C-Standard, sondern WinCC bzw. Windows spezial, im C99-Standard gibt es dafür die Typen uint8_t, uint16_t etc.).

Du könntest deine Struktur dann so ändern:

```
struct{
  WORD Stat1;
  WORD Stat2;
  WORD Stat3;
  WORD Stat4;
} RStat;
```

Nun ist aber immer noch nicht gesagt dass die Stat1-4 Variablen direkt im Speicher hintereinander liegen, denn der Compiler kann zu Optimierungszwecken sogenannte Padding-Bytes einfügen. Das macht er, weil je nach Architektur ein Zugriff auf 4 Bytes schneller ist als auf 2 Bytes die im Speicher ungünstig angeordnet sind.
Also es kann sein, dass sizeof(WORD) den Wert 2 zurückgibt, aber im obigen Beispiel ein sizeof(RStat) einen Wert von 16 zurückgibt. Ich habs eben mal mit WinCC in einer VM getestet, dort ist die Struktur wirklich genau 8 Bytes groß (also keine Padding-Bytes).
Aber verlassen kann man sich darauf nicht!

Bei einigen Compilern lässt sich mit entsprechenden Compiler-Pragmas angeben, dass keine Padding-Bytes eingefügt werden sollen (beim GCC z.B. mit #pragma pack(1) ).
Wenn du wirklich sicher sein willst dass dein Programm auf verschiedensten Prozessorarchitekturen einwandfrei läuft, ist die Lösung mit der Struktur aber unbrauchbar. Dann nimmt man ein char Array und muss wohl oder übel die einzelnen Werte selber korrekt zusammensetzen.


----------



## Bender25 (28 Juni 2010)

hm genau das könnte das problem sein. Da hab ich gar nicht dran gedacht. Danke für die ausführliche Info


----------



## sailor (30 Juni 2010)

Dann liegt die Ursache wahrscheinlich daran, daß ich keine S7-CPU benutze mit einer Verbindung über den Treiber S7-Protocol-Suite sondern eine WINLC RTX von Siemens über den gleichen Treiber. In dem Fall ja den virtuellen S7-Bus. 
Da muss man ja erst mal drauf kommen. 
Siemens Supportrequest hat natürlich auch keine Ahnung warum. 
Aber ich habs jetzt so gelöst: da ich die Bytes ja sowieso in der CPU drehen muß (TAW) lade ich die Integrerwerte mach TAD und transfrerier die in Doppelwörter. Funktioniert einwandfrei. Aber die GRenze von 204 bytes der Raw-Var ist natürlich auf 32 bit Werte begrenzt.

Herzlichen Dank noch mal an Euch und Grüezi aus der Schwyz.
Sailor


----------



## Bender25 (1 Juli 2010)

Hast es mal mit dem vorschlag von Thomas versucht?

Deine Struc von INT in WORD zu ändern? Dann sollte es gehen!!


----------

