Opened 12 years ago

Closed 12 years ago

#47 closed Aufgabe (fixed)

Ablauf Messwerk-Kommunikation

Reported by: Melanie Hermann Owned by: Melanie Hermann
Priority: mittelfristig Milestone:
Component: Gesamtsystem Version:
Severity: Aufgabe Keywords:
Cc:

Description

Der Ablauf der Messwerk-Kommunikation optimieren.

Attachments (3)

GC9000-Log_20140526 (57.2 KB ) - added by Melanie Hermann 12 years ago.
GC9000-Log_20140527 (77.7 KB ) - added by Melanie Hermann 12 years ago.
GC9300_Threads.txt (2.0 KB ) - added by Melanie Hermann 12 years ago.

Download all attachments as: .zip

Change History (37)

comment:1 by Melanie Hermann, 12 years ago

Änderungen:

  • CP4002Prot.h/CP4002Prot.cpp:
    • Flag m_setParameter entfernt. SMB-Parameter werden jetzt immer gesendet.
    • Neues Flag m_FlushMode. Enthält FlushMode-Status des Messwerks. Analysen dürfen nur gestartet werden, wenn das Messwerk nicht mehr im FlushMode ist.
    • Neues define FLUSH_READY 0x00. Bedeutet, dass das Messwerk nicht mehr im FlushMode ist und bereit ist.
    • CCP4002ThreadFunc():
      • CP_WAIT übergibt jetzt immer an CP_RESET
    • Transmit():
      • case CP_N_SEND: m_bytesSollRecv = 1
    • Recv():
      • Wenn Timeout bei CP_N_SEND kein Timeout melden, denn es kann sein, dass das Messwerk diesen Befehl nicht kennt.
    • ProcessRecvData():
      • case CP_N_SEND: Empfangenes Byte in Flag m_FlushMode kopieren.
Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:2 by Melanie Hermann, 12 years ago

Momentaner Ablauf:

  • WAIT
  • RESET
  • A
  • J
  • N
  • C
  • H
  • SMB
  • D
  • START
  • CLOSE
  • ...

comment:3 by Melanie Hermann, 12 years ago

Weitere Änderungen:

  • GcCM.cpp:
    • GcCMThreadFunc():
      • InstrumentState wird erst auf READY gesetzt, wenn auch sich das Messwerk nicht mehr im FlushMode befindet.
      • Wenn Messwerk-Timeout ist, dann wird der FlushMode in der Membervariable des CP4002Protokolls und in der Matrix auf 1 gesetzt. Somit kann es nach Wiederherstellung der Verbindung nicht passieren, dass zu früh eine Analyse gestartet wird.

comment:4 by Melanie Hermann, 12 years ago

Siehe auch Ticket #41.

comment:5 by Melanie Hermann, 12 years ago

TODO:
Dauertest Kommunikation

comment:6 by Melanie Hermann, 12 years ago

Priority: kurzfristigmittelfristig

comment:7 by Melanie Hermann, 12 years ago

Kommentar:
Messwerk wurde nun 2 Tage lang mit dem GC9000 betrieben, um zu überprüfen wie dieser sich verhält.
In diesen 2 Tagen gingen keine Analysen verloren. Die Kommunikation hat problemlos funktioniert.
Der Abstand zwischen 2 Analysen beträgt immer etwas mehr als 3 Minuten.

by Melanie Hermann, 12 years ago

Attachment: GC9000-Log_20140526 added

by Melanie Hermann, 12 years ago

Attachment: GC9000-Log_20140527 added

comment:8 by Melanie Hermann, 12 years ago

Testergebnis:
Es gehen immer noch vereinzelt Bytes und damit Analysen verloren.

comment:9 by Melanie Hermann, 12 years ago

Idee:

Bisher wird pro Funktionsaufruf von ReadFile() nur 1 Byte gelesen.
Die Verwendung von der Struktur COMMPROP und der Funktion GetCommProperties() hat gezeigt, dass die Comm einen Receive-Buffer von der Größe 16 Byte hat.
Das Messwerk schickt aber 1200 Byte pro Sekunde.
Eventuell wurde der Buffer, in wenigen Fällen, zu langsam geleert und ein paar Bytes verworfen.

Änderungen:

  • CP4002Prot.cpp:
    • Transmit():
      • Konkrete Angabe der Anzahl Bytes, die maximal pro ReadFile() gelesen werden sollen. Bei CP_START sind das nun die Anzahl an Bytes, die das Messwerk pro 2 Sekunden (Timeoutzeit) schickt (hier 1200 Bytes). Bei allen anderen Befehlen bleibt es bei 1 Byte pro ReadFile().
    • Recv():
      • ReadFile() wird mit m_bytesSollRecv aufgerufen.


Ergebnis:

Immer noch vereinzelt fehlerhaft übertragene Analysen.

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:10 by Melanie Hermann, 12 years ago

Weitere Änderungen:

  • CP4002Prot.cpp:
    • CP4002ThreadFunc():
      • Wenn Timeout wegen fehlerhaft übertragener Analyse wird kein Sleep(Runtime) mehr gemacht.
    • Transmit():
      • CP_START: Timeout bis zum ersten empfangenen Byte = Sampletime + 35Sek.
      • CP_START: 1 Byte pro ReadFile() empfangen, nicht mehr 1200

Ergebnis:
Immer noch vereinzelt fehlerhaft übertragene Analysen.

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:11 by Melanie Hermann, 12 years ago

TODO:
Am besten Software zum Testen nach Butzbach geben und schauen ob dieses Problem mit anderen Messwerken auch besteht.

comment:12 by Melanie Hermann, 12 years ago

Liegt Problem vllt doch in der Hardware?

Änderung:
Controller und Messwerk richtig geerdet.

TODO:
Prüfen ob Kommunikation besser läuft.

Ergebnis:
Kein Unterschied. Kommunikation hat weiterhin sporadisch Probleme.

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:13 by Melanie Hermann, 12 years ago

TODO:
Rohdaten des Messwerks mit Hilfe des Tools LOG mitschreiben. Anhand der Dateigrößen kann erkannt werden, ob wirklich immer 48000 Bytes vom Messwerk gesendet werden oder nicht.
Wenn die Dateien immer 48K groß sind, liegt das Problem an der GC9300 Software.

Ergebnis:
Es werden alle 48K Bytes gesendet. Trotzdem meldet der GC sporadisch, dass einige wenige Bytes fehlen.

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:14 by Melanie Hermann, 12 years ago

TODO:
Mit Hilfe von GetCommError() den Status der Comm-Schnittstelle auslesen.
Über die Funktion kann erkannt werden, ob ein Framerror o.Ä. vorliegt.

Ergebnis:
Direkt nach dem Auftreten des Timeouts (47992 / 48000) wurde die funktion ClearCommErrors() aufgerufen. Die Struktur commStat war Null. Aber die Variable commErrors hatte den Wert 0x02.

0x01 = CE_RXOVER = An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.
0x02 = CE_OVERRUN = A character-buffer overrun has occurred. The next character is lost.

Das bedeutet, dass es im Empfangspuffer der Schnittstelle einen Überlauf gab und dadurch Bytes verloren gegangen sind.

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:15 by Melanie Hermann, 12 years ago

TODO:
Mit Hilfe der Funktion SetupComm() werden die Größen des In - und Outputpuffers auf 4096 Byte gesetzt.
Jedoch ist unklar auf welche Größe diese Puffer zuvor eingestellt waren, da es wohl keine Funktion zum Auslesen dieser Werte gibt.

Jetzt muss getestet werden, ob weiterhin Bytes verloren gehen.

Ergebnis:
SetupComm() funktioniert nicht...

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:16 by Melanie Hermann, 12 years ago

TODO:
Mit Hilfe der Funktion SetupComm() werden die Größen des In - und Outputpuffers gesetzt.

  1. Test: Buffer auf 1 Byte setzen und prüfen ob Fehler öfter auftritt.
  2. Test: Buffer auf 48000 Byte setzen und prüfen ob Fehler nicht mehr auftritt.

Ergebnis:
Die Funktion SetupComm() scheint nicht unterstützt zu werden!
Beim Versuch die Buffersize per DeviceIoControl() zu setzen wurde festgestellt, dass der IoControlCode IOCTL_SERIAL_SET_QUEUE_SIZE nicht definiert ist. Also kann DeviceIoControl() auch nicht verwendet werden.
Somit kann die Buffer-Größe nicht angepasst werden und muss auf Default 16 Byte bleiben...

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:17 by Melanie Hermann, 12 years ago

Änderungen:

  • Membervariable m_m_bytesSollRecvAll entfernt
  • CCP4002Prot::Trans():
    • m_bytesSollRecv enthält wieder Anzahl der Bytes, die insgesamt empfangen werden sollen
  • CCP4002Prot::Recv():
    • Beim ersten ReadFile() wird immer nur das erste Byte empfangen (Somit kann anschliessen bei CP_START die Runtime gestartet werden.
    • Das totale Timeout für die darauffolgenden ReadFile() wurde auf 200 ms runtergesetzt. Hinweis: Beim GC9000 war eine maximale Pausezeit von 2 Sekunden zwischen 2 Bytes erlaubt. Jetzt nur noch 200 ms.
    • Ab dem zweiten ReadFile() werden mehrere Bytes empfangen bis das Timeout zuschlägt (m_bytesSollRecv-m_bytesReceivedAll).

TODO:
Prüfen ob Timeouts weg sind.

Ergebnis:
Weiterhin Timeouts...

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:18 by Melanie Hermann, 12 years ago

Änderungen:

  • CP4002Prt::Recv():
    • Das totale Timeout ab dem zweiten ReadFile() von 200 ms auf 100 ms gesenkt.

TODO:
Prüfen ob weiterhin Timeouts.

Ergebnis:
Weiterhin Timeouts...

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:19 by Melanie Hermann, 12 years ago

Kommentare:

  • Erstes ReadFile() liest erstes Byte. Zweites ReadFile() liest die restlichen Bytes.
  • Threadpriotät jetzt auf THREAD_PRIORITY_NORMAL. Höhere Prioritäten getestet. Aber erfolglos.
Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:20 by Melanie Hermann, 12 years ago

Test:

Alle unnötigen Threads auskommentiert.
Es laufen nur die folgenden Threads:

  • Main-Thread (GUI)
  • CAN-IN (m_threadCanIn)
  • CAN-OUT (m_threadCanOut)
  • CP4002-Protokoll (m_threadCP4002)
  • GcCM (m_threadGcCMFunc)
  • SecTimer (m_threadSecTimer)

Ergebnis:
Nach ca. 7 Stunden läuft der GC immer noch ohne Timeout.
Die Wahrscheinlichkeit ist also hoch, dass es sich bei dem Timeout-Problem um ein Thread-Problem handelt.

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:21 by Melanie Hermann, 12 years ago

Kommentare:
Alle Threads im GC9300 werden mit der gleichen Priorität (THREAD_PRIORITY_NORMAL) gestartet. Nur der SecTimerThread stellt eine Ausnahme dar. Dieser wird mit höherer Priorität (THREAD_PRIORITY_ABOVE_NORMAL) gestartet.

by Melanie Hermann, 12 years ago

Attachment: GC9300_Threads.txt added

comment:22 by Melanie Hermann, 12 years ago

TODO:
Überlegen wie Thread-Problem behoben werden kann.

comment:23 by Melanie Hermann, 12 years ago

Änderungen:

  • Variable m_bytesSollRecv entfernt
  • Bei jedem Befehl 2x ReadFile(). Das erste liest 1 Byte, das zweite den Rest.

Kommentar:
Mit der Methode mit 2x ReadFile() kann nicht mehr erkannt werden, ob das Messwerk vllt zu viele Daten schickt. Hierfür müsste ein weitere Dummy-ReadFile() gemacht werden.

Ergebnis:
Keine Verbesserung.

Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:24 by Melanie Hermann, 12 years ago

Änderungen:
Aufgrund von Kontakt im F&S-Forum wurden zwei Registryeinträge für die Treiber der Seriellen Schnittstelle neu eingetragen.

This indicates HW buffer overrun not a SW buffer overrun (CE_RXOVER). 
Note SW buffer is 2048 bytes and you will see the actuell usage by evalute 
LPCOMSTAT::cbInQue.
Try to increase the priority of the driver 
(HKLM\Drivers\BuiltIn\<drivername>\Priority256=DWORD<newprio>) 
and/or calling thread (by CeSetThreadPrioritiy()).

PS: set also HKLM\Drivers\BuiltIn\<drivername>\Watermarker=DWORD:1, than the 
IR in the ISR occurs when the first byte is in the HW buffer (default = 8).

Registry:

  • Serial1: Priority256 = 97, Watermarker = 1 -> COM7
  • Serial2: Priority256 = 98, Watermarker = 1 -> COM5
  • Serial3: Priority256 = 99, Watermarker = 1 -> COM6
  • Serial4: Priority256 = 100, Watermarker = 1 -> COM?

comment:25 by Melanie Hermann, 12 years ago

Kommentar:
Stephan hat ein paar Sourcen vom UART-Treiber auf dem Server abgelegt.

Y:\Entwicklung_GC9300\PicoMOD6\UART-SRC-Snippets

comment:26 by Melanie Hermann, 12 years ago

TODO:

  • Nach den beiden ReadFile() ein Dummy-ReadFile() einbauen damit erkannt werden kann, ob das Messwerk vllt zu viele Daten schickt und dann eine entsprechende Fehlermeldung ausgegeben werden kann.
  • Versuchen Fehler zu provozieren indem auf der anderen Seite etwas dauerhaft viele Daten schickt. Dann müsste es schneller zum Überlauf kommen. Mit Testprogramm Test_WriteFile testen.
  • Testen, ob Registryeinträge eine Verbesserung gebracht haben.
Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:27 by Melanie Hermann, 12 years ago

Kommentar:
Mit dem Testprogramm Test_WriteFile werden dauerhaft Zeichen an den GC geschickt.
Dieser macht Debugausgaben, wenn er 48000 Byte empfangen hat oder wenn er ein Timeout hat.

  1. Test: Registryeinträge entfernt (alle Einstellungen so wie immer)
    Das Timeout (0x02 == ClearCommError()) ist in ~ 4 Stunden 16 mal aufgetreten. Das heißt im Schnitt trat der Fehler alle 15 Minuten auf.
  1. Test: Registryeinträge, wie oben angegeben, eingetragen
    In ~ 3 Stunden ist das Timeout 0 mal aufgetreten. Die Einträge scheinen eine deutliche Verbesserung gebracht zu haben.
  1. Test: Mit beiden Registryeinträgen
    Nach ~ 2.5 Stunden ist wieder kein Timeout aufgetreten.
  1. Test: Nur mit Regisrtyeintrag Priority256
    ...
  1. Test: Nur mit Registryeintrag Watermarker
    ...
Version 3, edited 12 years ago by Melanie Hermann (previous) (next) (diff)

comment:28 by Melanie Hermann, 12 years ago

TODO:

  • Nach den beiden ReadFile() ein Dummy-ReadFile() einbauen damit erkannt werden kann, ob das Messwerk vllt zu viele Daten schickt und dann eine entsprechende Fehlermeldung ausgegeben werden kann.
  • Registryeintrag Priority256 setzen und dann testen.
Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:29 by Melanie Hermann, 12 years ago

  1. Test: Serial1 -> Priority256 = 100
    Nach ~ 1 Stunde kein Timeout
  1. Test: Serial1 -> Priority256 = 103
    Priorität von 100 auf 103 geändert. Denn in MSDN steht, dass der Defaultwert für Serial 103 sein sollte.
    Nach ~2 Stunden kein Timeout.
Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:30 by Melanie Hermann, 12 years ago

Kommentar:
Im MSDN wird geschrieben, dass die Defaultpriorität des Seriellen Treibers = 103 sein sollte.
http://msdn.microsoft.com/en-us/library/aa450596.aspx
F&S hingegen hat im Forum geantwortet, dass die Defaultpriorität = 158 ist.
http://forum.fs-net.de/index.php/Thread/3647-PicoMod6-API-function-SetupComm/

comment:31 by Melanie Hermann, 12 years ago

Änderungen:

  • CP4002Prot.cpp:
    • Recv(): DummyRead eingebaut um sicherzustellen, dass das Messwerk nicht zu viele Daten schickt. Wenn es zu viele Daten schickt wird hier ein weiteres Byte empfangen und dann kann anhand der Summe der empfangenen Bytes erkannt werden, dass es zu viele waren und ein entsprechender Fehler ausgegeben werden.
  • GcApp.cpp:
    • WriteSerDriverCom7PrioToRegistry(): Neue Funktion, die die Priorität des Seriellen Treibers der Com 7 in der Registry setzt.
      Wenn der Registryeintrag neugeschrieben werden musste wird ein Hinweis ausgegeben, dass das Gerät neu gestartet werden muss.
    • InitInstance(): Aufruf der Funktion WriteSerDriverCom7PrioToRegistry().
Last edited 12 years ago by Melanie Hermann (previous) (diff)

comment:32 by Melanie Hermann, 12 years ago

TODO:
Alles wieder ausführlich testen.
Jetzt darf eigentlich kein Timeout mehr auftreten!

comment:33 by Melanie Hermann, 12 years ago

Ergebnis:
Keine Timeouts mehr aufgetreten.

comment:34 by Melanie Hermann, 12 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.