USB Gerät (Master Pipe) auslesen



  • hi,

    ich versuche seit Tagen vergebens ein USB Gerät mit streams auszulesen.

    Über die Winapi bekomme ich die filesystem adresse des USB Devices:
    std::string path = "\?\usb#vid_04cc&pid_1a64&mi_01#6&31d4e9aa&0&0001#{28d78fad-5a12-11d1-ae5b-0000f803a8c2}"

    Mit den Windowsfunktionen ReadFile und WriteFile habe ich auch schon Transfers hinbekommen.

    HANDLE m_hFile;
    			m_hFile = CreateFile(path.c_str(),
    				GENERIC_READ | GENERIC_WRITE,
    				FILE_SHARE_READ | FILE_SHARE_WRITE, 
    				NULL, // no SECURITY_ATTRIBUTES structure
    				OPEN_EXISTING, 
    				NULL, // special attributes
    				NULL // No template file
    				);
    
    				COMMTIMEOUTS ct;
    		ct.ReadIntervalTimeout = 100; //The maximum time allowed to elapse between the arrival of two bytes on the communications line, in milliseconds.
    		ct.ReadTotalTimeoutMultiplier = 0; //The multiplier used to calculate the total time-out period for read operations, in milliseconds. For each read operation, this value is multiplied by the requested number of bytes to be read.
    		ct.ReadTotalTimeoutConstant = 100; // A constant used to calculate the total time-out period for read operations, in milliseconds.
    		ct.WriteTotalTimeoutMultiplier = 0; //The multiplier used to calculate the total time-out period for write operations, in milliseconds.
    		ct.WriteTotalTimeoutConstant = 100; //A constant used to calculate the total time-out period for write operations, in milliseconds.
    		SetCommTimeouts(m_hFile, &ct);
    
    			U32 err = GetLastError();
    			//send read command
    			U32 bufHeader[2];
    			U32 bytesWritten;
    			bufHeader[0] = 0x00000006; // next command: read 4 bytes from
    			bufHeader[1] = 0x00e00000; //this addr
    			WriteFile(m_hFile, bufHeader, 8, &bytesWritten, NULL);
    
    			U32 readvalue;
    			U32 _bytesRead;
    			ReadFile(m_hFile, &readvalue, 4, &_bytesRead, NULL);
    

    Wenn ich aber mit den Windowsfunktionen eine leere Pipe gelesen habe, blockierte der Aufruf obwohl die COMMTIMEOUTs passend gesetzt waren.

    Deshalb möchte ich mit iostreams arbeiten (möchte später eh auch Linux benutzen).
    Das Problem ist, dass ich mit den streams den Pfad nicht öffnen kann. hier 3 Wege, auf denen ich es probiert habe.

    bool streamOpened;
    
    std::ifstream is;
    std::filebuf * fb;
    fb = is.rdbuf();
    fb->open (path.c_str() , std::ios::binary | std::ios::in);
    streamOpened = fb->is_open();  // FALSE
    
    std::ifstream infile;
    infile.open (path.c_str(), std::ifstream::in);
    streamOpened  = infile.is_open();  //FALSE
    
    std::ifstream * inputStream;
    inputStream = new std::ifstream();
    inputStream->open(path.c_str(), std::ifstream::binary);
    streamOpened = *inputStream;//FALSE
    

    Was mache ich bloß falsch?

    Gruß

    Martin



  • Mit den C++ Streams wird das wohl nicht gehen. Du könntest aber vermutlich die Boost Iostreams Wrapper für FILE* bzw. HANDLE verwenden (FILE* bin ich jetzt nicht sicher ob's das gibt, HANDLE 99% sicher).
    Dann wäre nurmehr der Code zum Öffnen der Datei und anlegen des Wrappers für Windows und Linux unterschiedlich.

    Was das Blockieren angeht: wieso denkst du, dass du da mit iostreams mehr Glück hättest?

    Dass die COMM Timeouts nicht berücksichtigt werden wundert mich auch nicht weiter, da USB kein COMM Interface ist. Vermutlich wird es eigene IOCTLs geben mittels derer du eine Timeout-Zeit festlegen kannst.
    Vielleicht könntest du auch OVERLAPPED IO + CancelIo(HANDLE) verwenden - ist aber natürlich komplizierter, und funktioniert auch nicht mit iostreams Wrappern.



  • danke für deine Antwort Hustbaer.

    Habe nach langem googlen beschlossen auf die LibUSB umzusteigen. Die benutzt intern IOCTLs und bietet Funktionen wie usb_bulk_read(device, endpoint, Buffer, size, timeout);

    Gruß

    Martin


Anmelden zum Antworten