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)
Change History (37)
comment:3 by , 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.
- GcCMThreadFunc():
comment:6 by , 12 years ago
| Priority: | kurzfristig → mittelfristig |
|---|
comment:7 by , 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 , 12 years ago
| Attachment: | GC9000-Log_20140526 added |
|---|
by , 12 years ago
| Attachment: | GC9000-Log_20140527 added |
|---|
comment:8 by , 12 years ago
Testergebnis:
Es gehen immer noch vereinzelt Bytes und damit Analysen verloren.
comment:9 by , 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.
- Transmit():
Ergebnis:
Immer noch vereinzelt fehlerhaft übertragene Analysen.
comment:10 by , 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
- CP4002ThreadFunc():
Ergebnis:
Immer noch vereinzelt fehlerhaft übertragene Analysen.
comment:11 by , 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 , 12 years ago
Liegt Problem vllt doch in der Hardware?
Änderung:
Controller und Messwerk richtig geerdet.
TODO:
Prüfen ob Kommunikation besser läuft.
comment:13 by , 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.
comment:14 by , 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.
comment:15 by , 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...
comment:16 by , 12 years ago
TODO:
Mit Hilfe der Funktion SetupComm() werden die Größen des In - und Outputpuffers gesetzt.
- Test: Buffer auf 1 Byte setzen und prüfen ob Fehler öfter auftritt.
- 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...
comment:17 by , 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...
comment:18 by , 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...
comment:19 by , 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.
comment:20 by , 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.
comment:21 by , 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 , 12 years ago
| Attachment: | GC9300_Threads.txt added |
|---|
comment:23 by , 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.
comment:24 by , 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 , 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 , 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.
comment:27 by , 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.
- 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.
- 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.
- Test: Mit beiden Registryeinträgen
Nach ~ 2.5 Stunden ist kein Timeout aufgetreten.
- Test: Nur mit Regisrtyeintrag Priority256
Nach ~ 2.5 Stunden ist kein Timeout aufgetreten.
- Test: Nur mit Registryeintrag Watermarker
Innerhalb der ersten viertel Stunde ist das Timeout schon 2 mal aufgetreten. Der Registryeintrag Watermarker bringt also nichts.
Ergebnis:
Der Registryeintrag Priority256 scheint die Lösung zu sein.
comment:28 by , 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.
comment:29 by , 12 years ago
- Test: Serial1 -> Priority256 = 100
Nach ~ 1 Stunde kein Timeout
- 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.
comment:30 by , 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 , 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().
- WriteSerDriverCom7PrioToRegistry(): Neue Funktion, die die Priorität des Seriellen Treibers der Com 7 in der Registry setzt.
comment:32 by , 12 years ago
TODO:
Alles wieder ausführlich testen.
Jetzt darf eigentlich kein Timeout mehr auftreten!
comment:34 by , 12 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Änderungen: