TIA Serielle Schnittstelle mit Sendepuffer

daloeff

Level-1
Beiträge
59
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Servus,

ich hab eine Serielle RS422 Verbindung mit einem "CM PtP RS422/485 HF" Modul zu einem Teilnehmer im Freeport Modus aufgebaut.
Für die Telegramme habe ich einen Baustein geschrieben, dieser wird mit dem zu lesenden/schreibenden Parameternummer und dem Wert versorgt.
Intern wird noch eine Checksumme generiert und eine Packet ID angegeben. Sobald der Baustein Daten senden soll, wird das Telegramm erstellt und in einen globalen Sendepuffer über INOUT übergeben. Der Sendepuffer ist ein Array[0..63, 0..255] of Bytes. Der Sendepuffer kann also bis zu 64 Telegramme mit jeweils einer länge von 256 Bytes/Zeichen haben.
Wird ein Telegramm im Puffer abgelegt, wird eine interne Indexzahl um 1 erhöht. Somit wird der Puffer gefüllt, wobei bei >64 die Indexzahl auf 0 zurückgesetzt wird.
Da der Baustein mehrere male im Zyklus aufgerufen wird, kann je nach Situation sein, dass in einem Zyklus ein, oder mehrere Telegramme im Puffer abgelegt werden.
Am ende vom Zyklus wird der Send_P2P Baustein aufgerufen. Zuvor wird über eine FOR x := 0 TO 63 DO der Sendepuffer durchsucht, bis ein Telegramm im Puffer gefunden wird.
Wurde ein Telegramm gefunden, wird dieses dem Send_P2P Baustein übergeben und gesendet. Sobald der Send_P2P Baustein sein DONE meldet, wird das nächste Telegramm im Puffer gesucht.

Ich bin mir nicht sicher, ob die FOR Schleife die richtige Lösung ist?! Da es jetzt zu einem Timeout kommen kann, wenn die Indexzahl z.B.: bei 62 liegt und in einem Zyklus 8 neue Telegramme hinzukommen, beträgt die Indexzahl 6, da sie ja bei größer 63 auf 0 gesetzt wird. Nun beginnt die FOR Schleife aber immer bei 0 mit der Suche nach Telegrammen und da der Puffer fortlaufend gefüllt wird, kann es vorkommen, das die letzten Telegramme mit Index < 63 nicht mehr gesendet werden und diese dann zu einem Timeout Fehler führen...

Wäre es vlt besser den Puffer direkt mit einer REPEAT oder WHILE Schleife umzuschichten, so dass die ein neues Telegramm immer auf Platz 0 im Array eingefügt wird und die restlichen nach hinten verschoben werden und zusätzlich die FOR schleife von 63 nach 0 zählen lassen, also rückwärts?

Ich hoffe, ich habe es halbwegs verständlich rübergebracht...

Der Timeoutfehler wird generiert, wenn ein Antworttelegramm zu lange auf sich warten lässt. Der Baustein überprüft den Empfangspuffer auf neue Telegramme, dieses wird mit der zuvor mitgesendeten Packet ID abgeglichen, die Checksumme geprüft und das muss alles innerhalb eines definierten Zeitfenster passieren. Jedoch habe ich diesen Teil weckgelassen, da es ja so schon kompliziert genug ist :D
 
Moin,

ich habe das immer so gelöst, dass ich es als FIFO umgesetzt habe.
Die Instanz die die Telegramme einträgt durchsucht den Fifo von "oben" 63,62... nach dem ersten belegten Telegram, und trägt dann in dem Index davor seine Daten ein.
Die Instanz die die Telegramme verarbeitet lädt immer von dem Index 0, und wenn dies abgearbeitet wurde wird das ganze Array um ein Element verschoben.
Das ist nicht performant, ganz ganz sicher nicht... aber es macht genau was es soll.

Alternativ brauchst Du zwei Indizes. Einmal wo wurde zuletzt gelesen, und einmal wo wurde zuletzt geschrieben.

Grüße

Marcel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also ich löse solche Sachen immer so.

IndexEintrag <> IndexAustrag
IndexAustrag += 1;
if IndexAustrag > Max then
IndexAustrag := 0;
end_if;

Ob ich das nun für eine while schleife verwende, oder bei langsamen Sachen Zyklisch in einer IF Abfrage ist am Ende dann egal ;)

Gruß Christoph
 
Zurück
Oben