# libnodave und Message-Counter



## poppycock (28 Juni 2011)

Hallo,

ich bin dabei den Quellcode von libnodave für den seriellen MPI-Adapter auf ein Non-PC-System zu übersetzen.

Allerdings habe ich eine Frage zum Message-Counter.
Wenn ich mich nicht verguckt habe, ist der Message-Counter ein Byte groß, kann also von 0 bis 255 (FF) zählen. Ist das soweit richtig?
Was passiert, wenn die 255 überschritten wird?
Klar, wird zu 0, aber: Muss der Message-Counter-Wert, der für die Kommunikation benötigt wird, wieder auf 1 gesetzt werden?
Dazu habe ich im Quellcode leider nichts gefunden...
...oder ich habe Tomaten auf den Augen! 

Außerdem macht es mich stutzig, dass im Quelltext erwähnt wird, dass der *zweite Zählerstand* in der Nachricht um eins höher ist als der *aktuelle Zählerstand* des Message-Counters.
Ein Mitschreiben der Kommunikation sagt etwas anderes aus:
04 82 80 0C 14 03 F1 *02* 32 03 00 00 00 *01* 00 02 00 05 00 00 04 01 FF 04 00 08 FF 10 03 C3
Der *zweite Zählerstand* ist _IMMER _um eins niedriger als der *aktuelle Zählerstand*!

Was meint ihr dazu?

Gruß,
poppycock


----------



## poppycock (29 Juni 2011)

*Ergänzung*



poppycock schrieb:


> Außerdem macht es mich stutzig, dass im Quelltext erwähnt wird, dass der *zweite Zählerstand* in der Nachricht um eins höher ist als der *aktuelle Zählerstand* des Message-Counters.
> Ein Mitschreiben der Kommunikation sagt etwas anderes aus:
> 04 82 80 0C 14 03 F1 *02* 32 03 00 00 00 *01* 00 02 00 05 00 00 04 01 FF 04 00 08 FF 10 03 C3
> Der *zweite Zählerstand* ist _IMMER _um eins niedriger als der *aktuelle Zählerstand*!



Hier beispielsweise die Angabe im Quelltext der nodave.c 1.3 auf der SourceForge-Seite:


```
int daveReadBytesMulti(daveConnection * dc, int area, int DB, int start, int len)
{
  int res=0;
  uc readRequest[]=
  {
    0xF1,
[COLOR=Lime][B]     0x0, /[/B][/COLOR][B][COLOR=Lime]/ messageNumber[/COLOR][/B]
    0x32, // always 50
    0x01,
    0x00,0x00,
[B][COLOR=Red]     0x0, // messageNumber+1   [U]<-- darum geht's ![/U][/COLOR][/B]
    0x00,
    0x00,14+12,0x00,0x00, // 14 bytes parameter, 0 data
[B] ...[/B]
}
```


----------



## Thomas_v2.1 (29 Juni 2011)

poppycock schrieb:


> Hier beispielsweise die Angabe im Quelltext der nodave.c 1.3 auf der SourceForge-Seite:



Hast du etwa das CVS Archiv ausgecheckt? Das ist steinalt weil Zottel das nicht mehr nutzt bzw. nicht mehr aktuell hält.
Die Version im CVS ist von 2002! 

In der aktuellen Version ist die Funktion daveReadBytesMulti gar nicht mehr vorhanden.

Ansonsten erfolgt über diese Telegrammkennung die Zuordnung von Request und Response. Auch wenn es libnodave nicht nutzt, ist es prinzipiell möglich je nach CPU Typ mehrere Anfragen abzuschicken ohne die Antwort abzuwarten. Die Antworten müssen dann aber nicht in der angefragten Reihenfolge eintreffen. Darum wird die Nummer benötigt um die Zugehörigkeit von  Response zum Request herzustellen.


----------



## poppycock (29 Juni 2011)

Thomas_v2.1 schrieb:


> Hast du etwa das CVS Archiv ausgecheckt? Das ist steinalt weil Zottel das nicht mehr nutzt bzw. nicht mehr aktuell hält.
> Die Version im CVS ist von 2002!
> 
> In der aktuellen Version ist die Funktion daveReadBytesMulti gar nicht mehr vorhanden.



Ja, ich weiß, diese Version ist steinalt.
Ich halte mich nur zur Orientierung an den alten Code, meinen Code reenginiere ich größtenteils anhand Sniffen der seriellen Übertragung.
Woher hast du denn den Quelltext von der aktuellen Version? Mit einer dll kann mein Mikrocontroller nichts anfangen!
Oder schließt du nur deswegen darauf, weil man die dll nicht mehr mit der Funktion daveReadBytesMulti verwenden kann?



Thomas_v2.1 schrieb:


> Ansonsten erfolgt über diese Telegrammkennung die Zuordnung von Request und Response.


Achso, dann könnte ich bei einem Überlauf des Zählerstandes (von 0xFF auf 0x00) den Zählerstand wieder auf 0x01 setzen und gut ist!
Das werde ich ausprobieren.


----------



## Zottel (29 Juni 2011)

poppycock schrieb:


> Woher hast du denn den Quelltext von der aktuellen Version?


Der ist immer dabei! Verdammt noch mal!
Wie die Nummern gezählt werden, habe ich vergessen (ich glaube, eine durfte nicht 0 sein). Steht aber im Quellcode. 
Zu deiner PN:
Die Zeiten (tv.usec) beim select()-Befehl sind timeouts.


----------



## poppycock (29 Juni 2011)

Hallo Zottel!



Zottel schrieb:


> Der ist immer dabei! Verdammt noch mal!


Ich hatte vor längerer Zeit libnodave-0.8.4.5 von SourceForge heruntergeladen, allerdings war dort nicht die nodave.c zu finden.
Vielleicht ist diese Datei beim Entpacken damals verloren gegangen?! Ich weiß es nicht...
Weil also die nodave.c fehlte, habe ich vor ein paar Wochen begonnen mich mit dem Quellcode aus dem Jahre 2002 herumzuschlagen.
Deine Aussage hat mich stutzig gemacht und lud libnodave-0.8.4.6 von SourceForge herunter: nodave.c ist dabei! Hhm, lade ich mal libnodave-0.8.4.5 erneut herunter, hab ich mir gedacht: oh, nodave.c ist auch dabei! Sogar viele Quellcodes mehr.
Also Zottel, komm bitte wieder runter, meine Frage war doch nicht böse gemeint!



Zottel schrieb:


> Wie die Nummern gezählt werden, habe ich vergessen (ich glaube, eine durfte nicht 0 sein). Steht aber im Quellcode.


Habs getestet.
Der *aktuelle Zählerstand *des Message-Counters muss 1 bis 255 betragen und darf nach der PLC-Initialisierung nie mehr 0 sein.



Zottel schrieb:


> Zu deiner PN:
> Die Zeiten (tv.usec) beim select()-Befehl sind timeouts.


Danke!


----------



## Jochen Kühner (29 Juni 2011)

Für was für ein nonPc System übersetzt du denn den Quellcode? Mit avrgcc läßt er sich nämlich schon compilieren (ob die lib dann funktioniert, hab ich mangels seriellem adapter nicht getestet!)


----------



## Zottel (30 Juni 2011)

Meines Wissens nach für AVR.
Was ich gar nicht verstehe: Warum interessierte ihn/dich vor einigen Wochen das Thema endianness und heute die Nummerierung der Nachrichten?
Meiner Meinung nach
- kann man erst Nachrichten austauschen, wenn die Nummerierung stimmt.
- ist, solange man keine Nachrichten austauscht, Endianness zweitrangig.
- kann man Endianness selber austesten, indem man mit Step7 in die CPU schreibt und nachschaut, wie die Bytes im  PC ankommen
- sollte man immer versuchen, begrenzte Teilprobleme zu lösen, als da wären:
Libnodave benutzen, verstehen wo welche S7-Daten im Puffer landen bzw. umgekehrt, Libnodave compilieren (mit  gcc oder MSVC). 
Erst danach würde ich die Portierung auf AVR angehen.


----------



## poppycock (30 Juni 2011)

Zottel schrieb:


> Meines Wissens nach für AVR.


8bit-Mikrocontroller...



Zottel schrieb:


> Was ich gar nicht verstehe: Warum interessierte ihn/dich vor einigen Wochen das Thema endianness und heute die Nummerierung der Nachrichten?


Eigentlich habe ich es nicht nötig mich hier zu irgendwas zu  rechtfertigen, das nicht zu meiner Anfangsfrage passt, aber nunja...



Zottel schrieb:


> Meiner Meinung nach
> - kann man erst Nachrichten austauschen, wenn die Nummerierung stimmt.


Ja, das hat auch funktioniert. Bei meinen Testversuchen habe ich mich auf das Auslesen *EINES* Datums aus der SPS beschränkt und den *zweiten Zählerstand* jeweils immer um 1 niedriger als den *aktuellen Zählerstand* gehalten.
In *DEINER* varalteten nodave.c aus dem Jahre 2002 ist es irgendwie anders im Quelltext kommentiert.



Zottel schrieb:


> - ist, solange man keine Nachrichten austauscht, Endianness zweitrangig.


In welcher Reihenfolge das Datum ist, ist erstmal zweitrangig, ja.



Zottel schrieb:


> - sollte man immer versuchen, begrenzte Teilprobleme zu lösen, als da wären:
> Libnodave benutzen, verstehen wo welche S7-Daten im Puffer landen bzw. umgekehrt, Libnodave compilieren (mit  gcc oder MSVC).


Nach und nach an die "Probleme" herantasten, das habe ich gemacht.
_*Ich hatte aber DEINE veralteten Codes aus dem CVS!*_



Zottel schrieb:


> Erst danach würde ich die Portierung auf AVR angehen.


Fast alle Sachen brauche ich für meine Anforderung nicht, da ist das serielle Protokoll mitschreiben und gucken, was *du* im Quelltest wie machst, *für mich* sinnvoller.
Ich nehme nicht alles so hin, wie es gegeben ist.
Mich interessiert hier nicht vorrangig, wie man eine Funktion fehlerfrei in VB.net oder C# aufruft, sondern was eine Funktion auf Bitebene macht.
Meiner Meinung nach kann man erst danach verstehen, wie etwas funktioniert.

Auf der einen Seite werde ich gefühlt als doof abgestempelt und bekomme zu hören, dass ich an die Sachen falsch herangehe (obwohl der Antworter absolut nicht meine bereits gewonnenen Kenntnisse _[nicht Erfahrung]_ kennt), auf der anderen Seite bekam ich eine Antwort wie:


Zottel schrieb:


> Wie die Nummern gezählt werden, habe ich vergessen (ich glaube, eine durfte nicht 0 sein). Steht aber im Quellcode.


Auch wenn Zottel der "Erfinder" von libnodave ist und keinen Support geben muss, ist so eine Antwort sehr schade.

Dieser Thread ist für mich abgeschlossen, da ich ja nur nach dem Message-Counter gefragt habe und das Thema jetzt so dermaßen off-topic wird, dass man denken könnte, man sei im MikrocontrollerNet-Forum gelandet! *ROFL*


----------



## bike (30 Juni 2011)

poppycock schrieb:


> Auch wenn Zottel der "Erfinder" von libnodave ist und keinen Support geben muss, ist so eine Antwort sehr schade.



Wenn du dich an jede Programmzeile erinnerst die du programmiert hast, dann hast du entweder ein super Gedächtnis oder nur wenige Zeilen geschrieben.

Zottel hat ja die Sourcen dokumentiert, um sich nicht jeden Teil merken zu müssen.


bike


----------



## Jochen Kühner (1 Juli 2011)

Thomas_v2.1 schrieb:


> Ansonsten erfolgt über diese Telegrammkennung die Zuordnung von Request und Response. Auch wenn es libnodave nicht nutzt, ist es prinzipiell möglich je nach CPU Typ mehrere Anfragen abzuschicken ohne die Antwort abzuwarten. Die Antworten müssen dann aber nicht in der angefragten Reihenfolge eintreffen. Darum wird die Nummer benötigt um die Zugehörigkeit von  Response zum Request herzustellen.



Wieviele Anfragen kann Ich denn gleichzeitig absetzten, oder ist das Cpu abhänig (wenn ja, wo ließt man das aus?)? Wenn Ich Anfragen gleichzeitig sende, gibt das einen Geschwindigkeitsvorteil, d.h. Werden die auch gleichzeitig von der Cpu verarbeitet?


----------



## Thomas_v2.1 (1 Juli 2011)

Jochen Kühner schrieb:


> Wieviele Anfragen kann Ich denn gleichzeitig absetzten, oder ist das Cpu abhänig (wenn ja, wo ließt man das aus?)? Wenn Ich Anfragen gleichzeitig sende, gibt das einen Geschwindigkeitsvorteil, d.h. Werden die auch gleichzeitig von der Cpu verarbeitet?



Die Anzahl wird beim Verbindungsaufbau zur SPS ausgehandelt. Diese findet im gleichen Teil statt wo auch die PDU-Größe ausgehandelt wird. In meinem Wireshark Filter habe ich die Felder "Max number of parallel jobs" genannt.

In der Siemens Dokumentation wird dieses "Maximale Anzahl paralleler Netzaufträge" genannt.
Dadurch bin ich auch erst darauf gekommen wofür das Feld zuständig ist. Wenn du in einem Step7 Projekt einen Simatic.Net OPC Server einrichtest, hast du in den Einstellungen der S7-Verbindungen im Reiter "OPC" dieses Einstellungsfeld. Per Voreinstellung steht dort 2 drin. Der dort eingestellte Wert korrespondiert mit dem Wert der beim Verbindungsaufbau zur SPS im entsprechenden Feld eingetragen wird.
Da es dort zwei Felder gibt (also im Netzwerkpaket), gehe ich davon aus dass das eine für die Anzahl der Lese- und das andere für die Anzahl der Schreibaufträge gilt - ich weiß es aber auch nicht definitiv.

Ob das performanter ist weiß ich nicht, und habe es auch noch nicht nachgeprüft. In der Hilfe steht dazu folgendes:


			
				Siemens Hilfe schrieb:
			
		

> Maximale Anzahl parallele Netzaufträge
> 
> Die maximale Anzahl paralleler Netzaufträge (Credits) gibt an, wie viel Aufträge der OPC-Server gleichzeitig absetzen kann. Der tatsächlich verwendete Wert wird mit dem Kommunikationspartner ausgehandelt. In der Kommunikationsbaugruppe werden jedoch die Ressourcen für die maximale Anzahl reserviert.


----------

