<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Comport: zeitkritische timeouts]]></title><description><![CDATA[<p>Hi,</p>
<p>versuche seit einigen Tagen ein zeitbasiertes Protokoll auf RS232 zu<br />
implementieren, allerdings machen diverse Timeouts tierischen Stress:</p>
<p>Aufeinanderfolgende Bytes innerhalb eines Datenblocks haben max. 8 Millisekunden Abstand, von Datenblock zu Datenblock vergehen 12 &lt; t &lt; 50 ms.</p>
<p>Laut Analyzer vergehen im konkreten Fall ca. 40 ms zwischen zwei Datenblöcken,<br />
aber im Idealfall sollte das Programm auch mit 12 zurecht kommen.</p>
<p>Das Problem besteht darin, dass RX und TX über die selbe Leitung laufen und<br />
daher das TX nur zwischen zwei Blöcken erfolgen kann.</p>
<p>So wie ich's bisher verstanden hab, hab ich also genau 4ms Zeit, um<br />
den &quot;Interblock Gap&quot; zu erkennen (nach Definition) bzw. 32ms im konkreten Fall.</p>
<p>Mit meinem Latein bin ich inzwischen am Ende...</p>
<p>Laufen soll das ganze unter WinXP.<br />
Meine erste Vermutung war, dass es nicht geht, weil win nicht Echtzeitfähig ist.<br />
Aber auf dem selben Rechner läuft Software für eine ähnliche Geschichte und da<br />
haben zwei Datenblöcke laut Sniffer sogar nur 18 Millisekunden Abstand.<br />
Und funktionieren tut's trotzdem perfekt...</p>
<pre><code class="language-cpp">CreateFile (str, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
SetupComm(hComm, 132, 1024);
SetCommState(hComm, &amp;dcb); // DCB erzeugt mittels BuildCommDCB(L&quot;baud=200  Parity=N data=8 stop=1&quot;, &amp;dcb)

COMMTIMEOUTS cto;
cto.ReadIntervalTimeout = 30;
cto.ReadTotalTimeoutMultiplier = 11;
cto.ReadTotalTimeoutConstant = 50;
cto.WriteTotalTimeoutMultiplier = 0;
cto.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(hComm, &amp;cto); 

// Kommunikationsaufbau
//----------------------
// Ein Byte senden
// Warten
// Umschalten auf 9600 Baud
// 3 Byte empfangen 
// Antwort senden

// Kommunikation ist eröffnet
//--------------------
// externes Gerät sendet jetzt alle t=40ms  (12ms &lt; t &lt; 50ms) Daten  (max. 132 Byte);

// Wenn der Rechner eine Anfrage stellt, muss er das zwischen zwei Datenblöcken machen.
// Und wie findet man jetzt dieses &quot;Loch&quot;?

// das hab ich aus bestehender Software abgekupfert:

// 1) Timeouts in cto auf (13, 11, 50, 0, 0) setzten
// 2) in einer while-Schleife solange einzelne Byte empfangen bis ein Timeout auftritt.
//    für jedes Empfangene Byte den Lesepuffer leeren:
// 2.1 Timeouts auf (MAXWORD, 0, 0, 0, 0) setzten, dann blockiert ReadFile nicht mehr
// 2.2 in Schleife solange lesen, bis nichts mehr empfangen wird
// 23. Timeouts zurücksetzen
// 3) nach der Whileschleife:Das nächste empfangene Byte ist der Beginn des nächsten Blocks
// 4) Timeouts auf (50, 11, 50, 0, 0) setzten
// 5) das nächste empfangene Byte soll der Beginn eines Blocks sein. Diese Byte gibt die Länge des
//   Blocks an
// 6) Restliche Bytes des Blocks empfangen

// JETZT sind wir zwischen zwei Blöcken:
// ---&gt; Anfrage senden
</code></pre>
<p>Problem:<br />
entweder wird bei 5) oder 6) ein Timeout erkannt, oder wenn doch mal was auf die Leitung rausgeht,<br />
dann völlig unkontrolliert und i. d. R. nicht in dem Zeitfenster zwischen zwei Blöcken.</p>
<p>Folge: Anfrage schlägt fehl</p>
<p>Hab auch schon an den Timeouts gedreht, weil meiner Meinung nach müssten die eher (8, 0, 0, 0, 0) lauten,<br />
aber das allerselbe Trauerspiel.</p>
<p>Oder als alternativ mal mittels WaitCommEvent() auf die Daten gewartet und mittels timeGetTime() die<br />
Abstände zwischen den Bytes ermittelt. Aber die kommen da irgendwie völlig unkontrolliert rein...</p>
<p>Ähnliches gilt für aktives Polling der Funktion ReadFile(): die meisten Bytes haben 0ms Abstand (laut Analyzer<br />
aber 3-4) und mittendrin sind wieder welche mit 15 - 63ms dabei.<br />
Aber da hat vermutlich der Billy schuld...</p>
<p>Sollte jemand bis hierher gelesen haben: danke und hoffentlich kannst du mir einen Tipp geben.</p>
<p>mfg<br />
Martin</p>
<p>PS:<br />
Hab auch schon die Quellcodes der funktionierenden Software verwendet (im Prinzip selbes Protokoll, nur sind einige Statusbytes anders).<br />
Aber auch die machen in meinem Programm immer den selben Ärger.</p>
<p>Leider kann ich das funktionierende Programm nicht übersetzten, weil das noch einige Abhängigkeiten hat, die<br />
mir allerdings nicht vorliegen...<br />
Wär schon mal interessant, ob das dann noch laufen würde...</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/150262/comport-zeitkritische-timeouts</link><generator>RSS for Node</generator><lastBuildDate>Mon, 20 Jul 2026 10:55:36 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/150262.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 14 Jun 2006 15:12:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Comport: zeitkritische timeouts on Wed, 14 Jun 2006 15:12:05 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>versuche seit einigen Tagen ein zeitbasiertes Protokoll auf RS232 zu<br />
implementieren, allerdings machen diverse Timeouts tierischen Stress:</p>
<p>Aufeinanderfolgende Bytes innerhalb eines Datenblocks haben max. 8 Millisekunden Abstand, von Datenblock zu Datenblock vergehen 12 &lt; t &lt; 50 ms.</p>
<p>Laut Analyzer vergehen im konkreten Fall ca. 40 ms zwischen zwei Datenblöcken,<br />
aber im Idealfall sollte das Programm auch mit 12 zurecht kommen.</p>
<p>Das Problem besteht darin, dass RX und TX über die selbe Leitung laufen und<br />
daher das TX nur zwischen zwei Blöcken erfolgen kann.</p>
<p>So wie ich's bisher verstanden hab, hab ich also genau 4ms Zeit, um<br />
den &quot;Interblock Gap&quot; zu erkennen (nach Definition) bzw. 32ms im konkreten Fall.</p>
<p>Mit meinem Latein bin ich inzwischen am Ende...</p>
<p>Laufen soll das ganze unter WinXP.<br />
Meine erste Vermutung war, dass es nicht geht, weil win nicht Echtzeitfähig ist.<br />
Aber auf dem selben Rechner läuft Software für eine ähnliche Geschichte und da<br />
haben zwei Datenblöcke laut Sniffer sogar nur 18 Millisekunden Abstand.<br />
Und funktionieren tut's trotzdem perfekt...</p>
<pre><code class="language-cpp">CreateFile (str, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
SetupComm(hComm, 132, 1024);
SetCommState(hComm, &amp;dcb); // DCB erzeugt mittels BuildCommDCB(L&quot;baud=200  Parity=N data=8 stop=1&quot;, &amp;dcb)

COMMTIMEOUTS cto;
cto.ReadIntervalTimeout = 30;
cto.ReadTotalTimeoutMultiplier = 11;
cto.ReadTotalTimeoutConstant = 50;
cto.WriteTotalTimeoutMultiplier = 0;
cto.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(hComm, &amp;cto); 

// Kommunikationsaufbau
//----------------------
// Ein Byte senden
// Warten
// Umschalten auf 9600 Baud
// 3 Byte empfangen 
// Antwort senden

// Kommunikation ist eröffnet
//--------------------
// externes Gerät sendet jetzt alle t=40ms  (12ms &lt; t &lt; 50ms) Daten  (max. 132 Byte);

// Wenn der Rechner eine Anfrage stellt, muss er das zwischen zwei Datenblöcken machen.
// Und wie findet man jetzt dieses &quot;Loch&quot;?

// das hab ich aus bestehender Software abgekupfert:

// 1) Timeouts in cto auf (13, 11, 50, 0, 0) setzten
// 2) in einer while-Schleife solange einzelne Byte empfangen bis ein Timeout auftritt.
//    für jedes Empfangene Byte den Lesepuffer leeren:
// 2.1 Timeouts auf (MAXWORD, 0, 0, 0, 0) setzten, dann blockiert ReadFile nicht mehr
// 2.2 in Schleife solange lesen, bis nichts mehr empfangen wird
// 23. Timeouts zurücksetzen
// 3) nach der Whileschleife:Das nächste empfangene Byte ist der Beginn des nächsten Blocks
// 4) Timeouts auf (50, 11, 50, 0, 0) setzten
// 5) das nächste empfangene Byte soll der Beginn eines Blocks sein. Diese Byte gibt die Länge des
//   Blocks an
// 6) Restliche Bytes des Blocks empfangen

// JETZT sind wir zwischen zwei Blöcken:
// ---&gt; Anfrage senden
</code></pre>
<p>Problem:<br />
entweder wird bei 5) oder 6) ein Timeout erkannt, oder wenn doch mal was auf die Leitung rausgeht,<br />
dann völlig unkontrolliert und i. d. R. nicht in dem Zeitfenster zwischen zwei Blöcken.</p>
<p>Folge: Anfrage schlägt fehl</p>
<p>Hab auch schon an den Timeouts gedreht, weil meiner Meinung nach müssten die eher (8, 0, 0, 0, 0) lauten,<br />
aber das allerselbe Trauerspiel.</p>
<p>Oder als alternativ mal mittels WaitCommEvent() auf die Daten gewartet und mittels timeGetTime() die<br />
Abstände zwischen den Bytes ermittelt. Aber die kommen da irgendwie völlig unkontrolliert rein...</p>
<p>Ähnliches gilt für aktives Polling der Funktion ReadFile(): die meisten Bytes haben 0ms Abstand (laut Analyzer<br />
aber 3-4) und mittendrin sind wieder welche mit 15 - 63ms dabei.<br />
Aber da hat vermutlich der Billy schuld...</p>
<p>Sollte jemand bis hierher gelesen haben: danke und hoffentlich kannst du mir einen Tipp geben.</p>
<p>mfg<br />
Martin</p>
<p>PS:<br />
Hab auch schon die Quellcodes der funktionierenden Software verwendet (im Prinzip selbes Protokoll, nur sind einige Statusbytes anders).<br />
Aber auch die machen in meinem Programm immer den selben Ärger.</p>
<p>Leider kann ich das funktionierende Programm nicht übersetzten, weil das noch einige Abhängigkeiten hat, die<br />
mir allerdings nicht vorliegen...<br />
Wär schon mal interessant, ob das dann noch laufen würde...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1077713</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1077713</guid><dc:creator><![CDATA[anonymus]]></dc:creator><pubDate>Wed, 14 Jun 2006 15:12:05 GMT</pubDate></item></channel></rss>