Problem with OVERLAPPED structure



  • Hi,

    I use this sample driver with the PDIUSBD12D. If I only send data from pc to the controller it works. Send data from the controller it works also.

    But if I do both together there is a problem. If I send 400 bytes and then send this 400 bytes back sometimes I reseive on PC not all of the 400 bytes. But if I send the next packet from the controller to the pc the lost data come with this packet.

    I think windows buffers this lost data and don´t create an receive event.

    I use the overlapped struckture to send and receive data from the sample driver

    while(!ubThreadExit)
    {
    if (INVALID_HANDLE_VALUE != hRead)
    {
    // Empfangsevent?
    if (WAIT_OBJECT_0 == WaitForSingleObject(ov.hEvent,500))
    {
    if ((ov.InternalHigh > 0)&& (pUSBRxHandler))
    if (GetOverlappedResult(hRead, &ov, &ulNBytesRead, true))
    pUSBRxHandler(RxBuffer, ulNBytesRead, pUSBTag);
    ReadFile(hRead, RxBuffer, 256, &ulNBytesRead, &ov);
    }
    }
    }

    Does anybody knows about this problem?

    best regards Maik Hänig


  • Mod

    Wer sagt Dir wie die einzelnen Datenböcke gepuffert werden.
    In dem Moment in dem eben GetOverlappedResult zurückkommt wurde eben der Buffer geflusht. Dann kommen eben soviele Zeichen die eben bis dahin im Buffer waren.
    Das damit nicht alle Daten übertragen werden ist ja auch nicht garantiert. Denn die Daten kommen ja brav im nächsten Zyklus. Letzten Endes ist dies wohl abhängig von dem Device den Du hast.
    Letzten Endes geht ja nichts verloren.

    Was wäre also wenn Du Dich nicht Zyklen verlassen würdest sondern eben ein Protokoll einführst!
    Wenn Du weißt dass eben 400 Zeichen kommen müssen, dann musst Du eben solange warten bis die 400 voll sind und sooft ReadFile aufrufen bis dieser Block eben voll ist!



  • Die Daten werden auf jeden Fall gepuffert, denn ich verwende den BulkUSB Sample Treiber aus dem WinDDK in verbindung mit dem Philips PDIUSBD12D und dieses ist an einen DSP angeschlossen. Die Daten sind auf jeden Fall am PC angekommen da mir das PDIUSBD12D die USB kommonikation bestätigt.

    Achso und du verstehst da was falsch. Die Daten sind somot in Windows Puffern zwischengespeichert wenn welche noch nicht angekommen sind aber ich kann warten solange ich will es wird kein neues Empfangsevent generiert. Die Daten kommen dann mit wenn ich vom DSP das nächste Packet sende und es sind nicht immer 400 Byte diese Anzahl hab ich nur zum testen gewählt. Jrtzt ist die Frage wie finde ich den Fehler


  • Mod

    D.h. ein erneuter ReadFile liefert keine Infos? Der Event wird natürlich nur einmal ausgelöst und nur durch einen neuen ReadFile zurückgesetzt. Also was passiert wenn Du ReadFile erneut uaslöst, bevor die nächsten 400 Zeichen kommen?



  • Also das Event ist an das Readfile gekoppelt ich habe mein programm jetzt umgestellt auf ReadfileEx. Jetzt ist halt die frage wo das Event verloren geht.

    Sobald ein Readfile zurückkehrt ist ja ein event ausgelöst wurden dann starten sich die execution rutuine in der ich die Daten behandle. Der vorteil bei ReadfileEx ist das sich das Event erst nach dieser rutine anzeigt. Jetzt starte ich sofort ein erneutes Readfile.

    while(!ubThreadExit)
    {
    if (INVALID_HANDLE_VALUE != hRead)
    {
    // Empfangsevent?
    if (WAIT_IO_COMPLETION == WaitForSingleObjectEx(ov.hEvent, 500, true))
    {
    ReadFileEx(hRead, RxBuffer, 256, &ov, ReadFileIOCompletionRoutine);
    }
    }
    }


  • Mod

    Ja! ReadFile setzt das Event zurück. Es ist nicht automatisch gesetzt, sondern dann wenn eben Daten anliegen. Das heißt nicht wieviele Daten anliegen.
    Das Event wird intern ausgelöst.
    Du kannst Dich nicht darauf verlassen, dass wenn das Event gesetzt wurde, nicht bereits neue daten zum lesen bereitstehen!



  • da drauf kann ich mich halt nicht verlassen da ich genau weiß wieviele daten schon an den pc gesendet wurden über das PDIUSBD12D und dieser Chip mir die Kommunikation auch bestätigt das heißt wenn ich statts 400 nur 272 empfange und beim nächsten mal dann 528 dann muß windows die daten intern gepuffert haben und mir keni event gegeben haben.

    Jetzt ist halt die frage wie ich windows dazu bringe mir wirklich alle events zu geben.

    MfG Maik Hänig


  • Mod

    Das habe ich doch schon geschrieben. Du kannst Dich einfach nicht darauf verlassen, dass immer 400 Byte in einem Stück gelesen und geschrieben werden.
    Wie intern gepuffert wird weißt Du eben doch nicht. Welche physikalischen Blöcke intern verwendet werden weißt Du nicht!

    Woher weißt Du das ReadFle eben nicht doch wieder Daten liefert nachdem du 272 Zeichen empfangen hast. Was passiert wenn Du einfach nochmal ReadFile ausführst?
    Diese Antwort muss ich überlesen haben, denn gestellt hatte ich diese Frage schon!

    Also bleibt Dir nur übrig ein entsprechendes Protokoll zu verwenden. Also immer eben 400 Bytes zu lesen und die Verarbeitung erst zu beginnen wenn diese eben voll sind.
    Ohne solche Protokolle wirst Du nicht weit kommen. Es gibt natürlich auch noch intelligentere Protokolle aber das wirst Du selber wissen.



  • wenn du oben den Code ankuckst siehst du das dieses Readfile von einer while schleife umgeben ist, das heißt das readfile wird sofort wieder ausgeführt. Oder meinst du das readfile in de completition routine nochmal auszuführen.

    Mir würde es ja nix ausmachen wenn die restlichen Daten die zu den 400 Fehlen etwas später kommen würden. Aber sie kommen halt erst mit dem nächsten richtigen empfangsevent.

    Das heißt wenn später in der richtigen applikation keine neuen daten gesendet werden und einmal welche Fehlen wird das dann als Fehler erkann und es wird eine neue übertragung ausgefürt dort kommen dann ja natürlich zuviele Daten an so dass man schon 2 Fehlversuche hat deshalb ist es ja einfacher das Problem lösen kann.


  • Mod

    Korrekt! Deine Schleife müsste funktionieren.
    Dann würde ich das Problem in dem Device sehen, der verwendet wird.

    Nur noch eine Frage am Rande: Du verwendest einen Manual Reset Event, und sonst wartet auf diesen Event auch niemand?



  • ich verwende keinen manuellen reset sollte ich das tun?

    ich verwende als treiber den windows usb smaple treiber aus dem ddk.

    und das device ist ein PDIUSBD12D das aber die daten als gesendet bestätigt, da es ein interruppt auslöst wenn die daten gesendet worden.

    MfG Maik


  • Mod

    Manual Reset is OK! Probleme gibt es mit AutoReset, wenn eben mehrfach evtl. WaitForSingleObject ausgeführt wird.

    Zu dem Device und dem Treiber kann ich nicht sagen.

    Versuch es doch mal in einer nntp Gruppe:
    microsoft.public.development.device.drivers
    oder evtl.
    microsoft.public.win32.programmer.kernel

    Evtl. ist den Jungs schon so etwas untergekommen.



  • wenn der fall eintritt und ich zu wenig daten bekommen und ich in den Puffer dem ich dem Readfile übergebe hinein schaue sind die Daten schon enthalten aber ich habe noch kein Event bekommen.

    MfG Maik


  • Mod

    Jetzt verstehe ich gar nichts mehr. Welcher Puffer?

    Du gibst einen Leseauftrag. Dieser returniert und sagt Dir es wird ein Event gesetzt wenn Daten da sind, in der entsprechenden OVERLAPPED Struktur steht auch wie viele Daten übertragen wurden.

    Es wird keinen neuen Event geben ohne das ReadFile neu aufgerufen wird. Denn erst ReadFile setzt den Event zurück und nun kann der Mechanismus von vorne losgehen.

    Jetzt fällt mir gerade was an Deinem Code auf!
    Du prüfst ja gar nicht den Rückgabewert von ReadFile!!!
    Nur wenn ReadFile 0 returniert UND GetLastError ERROR_IO_PENDING returniert darfst Du GetOverlappedResult aufrufen.

    Ansonsten hast Du ja die Daten!
    Liegt hier Dein Fehler!



  • also ich fasse nochmal zusammen

    Ich habe jetzt folgenden thread:

    while(!ubThreadExit)
    {
    if (INVALID_HANDLE_VALUE != hRead)
    {

    // Empfangsevent?
    if (WAIT_IO_COMPLETION == WaitForSingleObjectEx(ov.hEvent, 500, true))
    {
    ReadFileEx(hRead, RxBuffer, 256, &ov, ReadFileIOCompletionRoutine);
    }
    }
    }

    meine Completition Routine siet folgendermaßen aus:

    VOID CALLBACK ReadFileIOCompletionRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
    {
    DWORD Error;
    unsigned long ulNBytesRead;

    if ((pUSBRxHandler) && (dwNumberOfBytesTransfered > 0))
    pUSBRxHandler(RxBuffer, dwNumberOfBytesTransfered, pUSBTag);
    }

    Jetzt tritt der Fehler auf das manchmal nicht 400 Bytes ankommen aber die Fehlenden beim nächsten event mit.
    Wenn ich nun nachdem die Bytes fehlen im debugger opause mache sind die fehlenden daten schon im RxBuffer (Variable wird Readfile als Buffer übergeben)
    ich bekomme halt nur kein Empfangsevent damit die Readfile Completition Routine aufgerufen wird

    Achso in der anderen version vom ersten Thread ist der selbe Fehler und da habe ich deinen Rat befolgt mal den Rückgabewert von Readfile gefprüft:

    Error = ReadFile(hRead, RxBuffer, 256, &ulNBytesRead, &ov);
    if ((0 == Error) && (ERROR_IO_PENDING != GetLastError()))
    {
    pUSBRxHandler(RxBuffer, ulNBytesRead, pUSBTag);
    }

    aber es ändert sich nix der betritt dieses if auch nicht

    MfG Maik



  • ich hab jetzt noch das writefile nach writefileEx umgestellt bringt auch nix

    MfG Maik


Log in to reply