network.lib > Modulentwicklung

OSCAT-NETWORK-LIB 1.30 Release Candidate 1

<< < (6/6)

amos:
Hi, im Projekt NET_VAR darf ich nicht antworten, darum hier mein Vorschlag:

Bitte das Rad nicht neu erfinden, sondern bezüglich der Kommunikation von mehreren Steuerungen untereinander  besser auf bewährte Open Source Lösungen zurück greifen.

http://www.oscat.de/community/index.php/topic,2106.0.html

Der kostenfreie Message Broker:

http://activemq.apache.org/

kann in weniger als 10 Minuten installiert werden und kommt meiner Erfahrung nach auch mit Millionen von Nachrichten <1500 Byte pro Sekunde klar.

rrbd:
Wann gibt's eigentlich mal ein Release? Die 1.21 war ja für mich jedenfalls eher unbrauchbar, während ich die 1.30 schon seit längerem erfolgreich nutze.

Gruß

Rainer

arsh0r:
Hi,

wir nutzen einige Funktionen der network.lib 1.30RC1 auf der PC WORX SRT Soft-SPS.

Da die Soft-SPS auf Windows läuft ergeben sich zusätzliche Probleme, die für eine normale SPS höchstwahrscheinlich nicht relevant sind (z.B, können andere Prozesse Dateien locken). Trotzdem stelle ich hier meine Patches mal rein.

FILE_SERVER:
Falls eine Datei nicht existiert brincht FILE_REMOVE mit einem Fehler ab, siehe: http://www.oscat.de/community/index.php/topic,2248.0.html

--- Code: ---@@ -528,6 +561,11 @@
 IF command = BYTE#7 THEN
  IF FILE_REMOVE.Done THEN
  error := FILE_REMOVE.Error;
+ IF FSD.MODE = BYTE#3 AND FILE_REMOVE.ErrorID = UINT#21 THEN
+ error := FALSE; (*Wenn die Datei nicht existiert kommt bei SRT ein Fehler*)
+ END_IF;
  command := BYTE#0;
  error_code := SEL_BYTE(error,BYTE#00,UINT_TO_BYTE(FILE_REMOVE.ErrorID + UINT#140)); (* Errorcode basis verschieben *)
  (* ---------------------- Debug-Message ----------------------------*)

--- Ende Code ---

Nur zur vorsicht, es gibt nämlich funktionen, die Error=TRUE setzen aber am crror_code "0" schreiben. Im Handbuch steht hier: "Keine Fehlerinformation vorhanden."

--- Code: ---@@ -327,6 +355,11 @@
 
 30000: (* Befehl fertig *)
  FSD.MODE := BYTE#0;
+ IF error AND error_code = BYTE#0 THEN (*Keine Fehlerinformation vorhanden?!*)
+ error_code := BYTE#1;
+ END_IF;
  FSD.ERROR := error_code;
  step := 0;
  (* ---------------------- Debug-Message ----------------------------*)

--- Ende Code ---

Eher suboptimal, aber ich weiss mir aktuell nicht anders zu helfen. Ich hatte den Fehler, dass Dateien trotz  FSD.OFFSET = UDINT#4294967294 trotzdem überschrieben wurden anstatt am Ende anzuhängen. Die genaue Ursache konnte ich noch nicht eingrenzen. Ich gehe einfach nochmal sicher, dass der Zeigen am Dateiende sitzt.

--- Code: ---@@ -238,6 +238,11 @@
IF FSD.OFFSET = UDINT#4294967294 THEN (* 16#FFFF_FFFE -> Zeiger auf Dateiende stellen *)
command := BYTE#5; (* File-Seek *)
  seek_position := FSD.FILE_SIZE;
  seek_mode := UINT#0; (* Positionierung relativ zum Dateianfang *)
  step := 210;
+ seek_mode := UINT#2;  (* Positionierung relativ zum Dateiende *)
+ seek_position := UDINT#0;
+ step := 201;
  ELSIF FSD.OFFSET > FSD.FILE_SIZE THEN (* prüfe auf gültige offset-vorgabe *)
  error_code := BYTE#255;
  step := 30000; (* Beenden *)
@@ -249,7 +254,30 @@
  ELSE
  step := 300;
  END_IF;
+201: (* File Seek *)
+ IF command = BYTE#0 THEN
+ IF Error THEN
+ step := 30000; (* Beenden *)
+ ELSE
+ step := 202;
+ END_IF;
+ END_IF;
 
+202: (* File Tell - Position des Schreib/Lesezeiger auslesen *)
+ command := BYTE#6; (* File Tell *)
+ step := 203;
+
+203: (* File Tell *)
+ IF command = BYTE#0 THEN
+ IF Error THEN
+ step := 30000; (* Beenden *)
+ ELSE
+ seek_position := tell_position;
+ step := 210;
+ END_IF;
+ END_IF;
 210: (* File Seek *)
  IF command = BYTE#0 THEN
  file_position := seek_position;

--- Ende Code ---

DLOG_STORE_FILE_CSV

Ich will auf keinen Fall das irgendwelche Logfiles überschrieben werden (nur anhängen) und ich will ein Logfile pro Tag mit 1-Minuten Werten. Ich nehme dafür in Kauf, dass bei einem Neustart der Soft-SPS die Kopfzeile noch einmal geschrieben wird. Ohne das Patch (retry on error) landen alle neuen Zeilen im Nirvana, falls die CSV von einem anderen Prozess (in meinem Fall WinSCP) gelockt ist. Kann der Puffer nicht ins CSV geschrieben werden, dann probiert er es im 5 Sekunden Abstand erneut. Läuft der Puffer (4096 Zeichen) über gibt es eine unschöne Zeile und alle zusätzlichen Daten sind fort. Die CSV wir bei mir aber nur einmal pro Stunde für ca. 20 Sekunden gelockt (ungünstigerweise wollte er genau da eine neue Zeile schreiben)...

--- Code: ---@@ -68,6 +68,7 @@
  total_bytes : UDINT;
  buf_totalsize : INT := 4096;
  workaround : WORD;
+ err_retry : TON;
 END_VAR
 
 @@ -217,6 +221,10 @@
 
  FSD.MODE := WORD_TO_BYTE(workaround); (* 0X00 -> 000X = 3 create + write / 2 open + write *)
  FSD.OFFSET := UDINT#0; (* Start bei Dateianfang *)
+ FSD.MODE := BYTE#2; (* File_Open_Exist + File_Write *)
+ FSD.OFFSET := UDINT#4294967294; (* 16#FFFF_FFFE ->Spezialcode: Daten automatisch an Dateiende anhängen *)
  FSD.FILENAME := X.UCB.D_STRING; (* Dateiname *)
  PT.SIZE := UINT#0;
  SAVE_DATA.FN_REM := FSD.FILENAME; (* aktuellen Dateinamen remanent sichern *)

@@ -297,7 +305,15 @@
  END_IF;
  step_2 := 20;
 
-20: IF FSD.MODE = BYTE#0 THEN
+20:
+ IF err_retry.Q THEN (*Falls ein Fehler aufgetreten ist, nach 5s noch einmal probieren*)
+ FSD.ERROR := BYTE#0;
+ FSD.MODE := BYTE#2; (* File_Open_Exist + File_Write *)
+ FSD.OFFSET := UDINT#4294967294; (* 16#FFFF_FFFE ->Spezialcode: Daten automatisch an Dateiende anhängen *)
+ END_IF;
+ IF FSD.MODE = BYTE#0 AND FSD.ERROR = BYTE#0 THEN
  total_bytes := FSD.FILE_SIZE;
  X.NEW_FILE_SIZE := total_bytes + INT_TO_UDINT(idx);
  IF log_stop OR aw_aktiv THEN

@@ -333,6 +349,9 @@
 ERROR_T := SEL(FSD.ERROR > BYTE#0,BYTE#0,BYTE#1);
 
 trig_m_last := TRIG_M;
+err_retry(IN:=FSD.ERROR > BYTE#0,PT:=t#5s);
 
 (* revision history
 ks 01. jan. 2011 rev 1.0

--- Ende Code ---

Wenn der Puffer einmal überläuft kommt er nie wieder in die Spur zurück, wenn hier nicht initialisiert wurde.

--- Code: ---@@ -201,6 +202,9 @@
  ELSE
  wd_ton(IN:= FALSE, PT:= wd_time);
  wd_ton(IN:= TRUE);
+ n := USINT#0; (*falls UCB mal voll war.*)
  WHILE X.UCB.BUF_COUNT > 0 AND step_2 = 0 AND wd_ton.Q = FALSE DO
  X.UCB.D_MODE := 10;
  UCB(DATA:=X.UCB); (* Element lesen , aber noch nicht entfernen *)

--- Ende Code ---

peewit:
hallo arsh0r

ich danke dir für den guten konstruktiven input

leider gibt es bei den verschiedenen plattformen immer wieder "extrawürste" zu berücksichtigen

da ich aber genau das eingeplant und den file_server gemacht habe , kann man nun relativ einfach für jede plattform einen angepassten file_server machen und der rest der bausteine ist nicht betroffen.

Navigation

[0] Themen-Index

[*] Vorherige Sete

Zur normalen Ansicht wechseln