mikrocontroller.net

Forum: PC-Programmierung Probleme mit WriteFile(),das Overlapped aufgerufen wird


Autor: Markus Bauknecht (Firma: MTU-FN) (ditsche)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi zusammen,

Ich hab' mal wieder ein weiteres Problem mit der RS232.

Ich möchte mit VS 2005 unter Vista ein Programm schreiben, das Daten 
über die Rs sendet und empfängt. Und zwar "Overlapped".

Das Lesen ist kein Problem. das Funktioniert einwandfrei.

Nur mit dem Schreiben hab' ich ein Problem.
Wenn ich WriteFile() aufruf, kommt sie gleich mit false zurück, wie sie 
das auch soll und was verständlich ist, da sie auch nicht zaubern kann.
Danach prüfe ich mit "GetLastError()" ob die Schnittstelle noch am 
Senden ist.
Das liefert mir dann auch immer ERROR_IO_PENDING zurück.
Dann warte ich mit WaitForSingleObject() darauf, dass das Event gesetzt 
wird. Wenn das passiert ist, müsste ja alles klar sein.
Aber die Variable, in die WriteFile() schreibt, ist dann immer noch "0".
Und es sind auch keine Daten aus der Schnittstelle herausbekommen.

Hier ist erstmal das öffnen des Ports:
------------------------------------------------------------------------ 
--
HANDLE Port::OpenPort(char* s1)
{
        OVERLAPPED sOverlapped;
  OVERLAPPED sOverlapped_W;
  HANDLE hEvent;
  HANDLE hEvent_W;
        HANDLE hComm;
  DCB sDcb;
         //Overlapped-Struct löschen, wie von Microsoft empfohlen
        ZeroMemory(&sOverlapped,sizeof(OVERLAPPED));
  ZeroMemory(&sOverlapped_W,sizeof(OVERLAPPED));
         //Events erstellen
  sOverlapped.hEvent = CreateEvent(NULL,false,false,NULL);
  sOverlapped_W.hEvent = CreateEvent(NULL,true,false,NULL);

        hComm = INVALID_HANDLE_VALUE;
         //Port öffnen
  hComm = CreateFileA(s1,GENERIC_READ | GENERIC_WRITE, 0, NULL,
                             OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

        GetCommState(hPort,&sDcb);
         //Parameter anpassen (komplett ohne Handshake)
  sDcb.BaudRate = CBR_38400;
  sDcb.ByteSize = 8;
  sDcb.Parity = NOPARITY;
  sDcb.fParity = false;
  sDcb.fDsrSensitivity = false;
  sDcb.StopBits = ONESTOPBIT;
  sDcb.fDtrControl = DTR_CONTROL_DISABLE;
  sDcb.fRtsControl = RTS_CONTROL_DISABLE;
  sDcb.fNull = true;

  SetCommState(hPort,&sDcb);
}

Und hier nun meine Funktion zum Senden:
------------------------------------------------------------------------ 
---
int Port::Send(char *buffer, int iBytesToWrite)

   DWORD dwBytesWritten = 0;

   if(WriteFile(hPort, buffer, iBytesToWrite, &dwBytesWritten,
                &sOverlapped_W))
   {
     return dwBytesWritten;
   }
   else
   {
     if(ERROR_IO_PENDING == GetLastError())
     {
                    //Ist noch am Senden...
       cout << "Braucht Noch" << endl;
       if(WAIT_OBJECT_0 ==
                        WaitForSingleObject(sOverlapped_W.hEvent,1000))
       {
                            //Jetzt wurde der Event gesetzt
                            //Hier kommt das Programm auch immer an
         cout << "Müsste gesendet haben" << endl;
                            //Problem!!!!!!!!!!!!!!1!!!!
          //Jetzt hat aber "dwBytesWritten" den Wert 0
                           return dwBytesWritten;
                            //Problem!!!!!!!!!!!!!!!!!!!!
       }
       else
       {
         cout << "Timeout 1000ms" << endl;
       }

     }
     else
     {
       cout << "Es ist ein Fehler aufgetreten" << endl;
       return 0;
     }
   }
}
------------------------------------------------------------------------ 
---
So steht's auch im MSDN. Darum hab' ich keine Ahnung, was ich noch 
vergessen oder falsch gemacht hab'.

Falls ihr noch was wissen müsst, sagt bitte bescheid.

Wär euch dankbar, wenn mir einer von euch "Cracks" :-) helfen könnte.

Danke schon mal

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst noch die Funktion GetOverlappedResult aufrufen, sonst wird 
Dein dwBytesWritten nie verändert.

Autor: Tobi H. (tobi-) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benutz mal GetOverlappedResult um die echt geschiebene Bytezahl zu 
bekommen
http://msdn2.microsoft.com/en-us/library/ms683209(...

Edit: Zu langsam, aber immerhin mit Link ;)

Autor: Markus Bauknecht (Firma: MTU-FN) (ditsche)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Danke, das ging ja schnell.

Ok, hab's gemacht. Jetzt passt's. Muss nur noch rausfinden ob wirklich 
was gesendet wird.

Dann hätt ich nur noch ne Verständnisfrage:

Wenn ich WriteFile() ohne Overlapped aufrufe dann schreibt es ja auch in 
die Variable.

Macht sie des in meinem Beispiel nur wegen dem Overlapped nicht?

Nochmals vielen Dank

Autor: FBI (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Direkt aus der M$-Doku zu WriteFile:
"If lpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL.
If this is an overlapped write operation, you can get the number
of bytes written by calling GetOverlappedResult."
CU

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.