Problem mit WriteFile

09/01/2014 - 11:47 von Edzard Egberts | Report spam
Mit WriteFile() werden Daten auf einen COM-Port ausgegeben, der über
USB-Treiber mit einem Arduino verbunden ist. Dabei ergibt sich das
seltsame Verhalten, dass WriteFile() zwar keinen Fehler meldet, aber
trotzdem nichts ausgibt, dieses Verhalten finde ich unter
http://msdn.microsoft.com/en-us/lib...85%29.aspx
nicht dokumentiert:

DWORD ULen;
bool Ret= WriteFile(m_Port, Out.c_str(), Out.size(), &ULen, 0);
if (!Ret)
{
DWORD Test= GetLastError();
cout << "Error # " << Test << endl;
cout << "Ulen " << ULen << " OLen " << Out.size() << endl;
}
else if (ULen!= Out.size())
{
cout << "Len Error" << endl;
}

Der Port ist synchron geöffnet und es werden in größeren Abstànden
(Sekunden) kleine Datenpakete wie "MV?" geschickt. Da gehen dann
zwischendurch welche verloren, wobei WriteFile() zwar keinen Fehler
liefert, ULen aber Null ist, obwohl eine Lànge angegeben wurde - das
obige Beispiel liefert dann also "Len Error". Der nàchste Versuch klappt
dann wieder.

Bevor ich jetzt eine "Wiederholung bei Len Error" baue, wüßte ich gerne,
was dieses Verhalten verursacht und ob man das auch anders abstellen
kann. Der Port wird übrigens mit folgenden Optionen geöffnet:

m_Port= CreateFile(
pPort,
GENERIC_READ|GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,
0);

Zur Zeit vermute ich ein USB-Problem, da die Software vorher mit RS232
funktionierte. Hat hier jemand àhnliche Erfahrungen gemacht?
 

Lesen sie die antworten

#1 Edzard Egberts
09/01/2014 - 15:49 | Warnen spam
Edzard Egberts schrieb:
Bevor ich jetzt eine "Wiederholung bei Len Error" baue



Kann es sein, dass der Port im Halbduplex làuft? Ich habe jetzt fast
drei Stunden herumprobiert, bis die Ausgabe funktionierte:

DWORD ULen;
unsigned char Repeat= 3;
do {
Ret= WriteFile(m_Port, Out.c_str(), Out.size(), &ULen, 0);
if (Ret && !ULen && !Out.empty())
{
string Test= oClear();
cout << "Clearing: " << Test << ", " << Test.size() << endl;
}
} while (ULen!= Out.size() && --Repeat);

mit

string oClear()
{
char Buf;
string S;
while (os_com_port::Read(&Buf, 1, 250)== 1) S+= Buf;
return S;
}

Ohne den Lesezugriff ist der Fehler nicht zu beheben, da kann man noch
so lange Sleep()en und Repeaten, das bleibt mit ULen== 0 hàngen. Der
Lesezugriff liefert manchmal die erwartete Antwort (die Ausgabe fand
also trotz ULen== 0 statt) und manchmal ist der String leer (Ausgabe von
size(), damit keine Sonderzeichen übersehen werden). Der nàchste
Schreibzugriff klappt dann aber einwandfrei. Die Theorie, dass bloß ULen
nicht richtig belegt wird, funktioniert nicht - die Ausgaben gehen
tatsàchlich oft verloren, auch wenn sie manchmal trotz ULen== 0 erfolgen.

Ähnliche fragen