USB-Port ansprechen
-
Sorry, da hab' ich vorhin bei beiden geträumt. Langer Praktikumstag gewesen.
-King- schrieb:
baschti schrieb:
Ich bekomme 0xCC oder 204 zurück.
Von wem oder was?
Vom Adapter oder der SPS.
-
baschti schrieb:
Sorry, da hab' ich vorhin bei beiden geträumt. Langer Praktikumstag gewesen.
Ach, das ist das ganze Geheimnis. Dann bin ich beruhigt.
baschti schrieb:
Vom Adapter oder der SPS.
Aha. Wobei sich 0xCC eher nach einer nicht initialisierten Stack-Variable anhört, evetuell Aufgrund einer fehlgeschlagenen Funktion (die hätte initialisieren sollen). Ansonsten bin ich mir noch immer unklar darüber, ob die Werte nun gut oder schlecht sind. Und außerdem sind das 260 Bytes, die die SPS liefern sollte. Ein schlichtes 204 ist irgendwie ganz schön wenig ...
-
-King- schrieb:
Ein schlichtes 204 ist irgendwie ganz schön wenig ...
Habe ich mir auch so gedacht. Mal kucken, wo der Fehler liegt.
Ich danke Dir erstmal recht herzlich für Deine Hilfe.
-
Du hast mich falsch verstanden. Du übergibst doch einen Buffer mit einer Größe von 261 Byte. Davon wird jetzt ein Byte auf 0xCC gesetzt. Von welchem Byte reden wird denn nun? Und ist das jetzt gut oder schlecht? Betrifft das alle Bytes? Schlägt vielleicht ReadFile fehl (eine Prüfung hast Du ja noch nicht eingebaut)? Mit welchem Fehlercode schlägt ReadFile fehl, wenn überhaupt?
-
Mahlzeit!
Habe meine Fehler beseitigt. So, denke ich, funktionierts, da ja Write/ReadFile bei Misserfolg NULL zurückgeben:WriteFile(... if(WriteFile == 0) { CloseHandle(hTreiber); printf("Can't write to device."); printf("Error: %u\n", GetLastError()); } SetLastError(0) ReadFile(... if...
Beide schlagen bei mir demnach nicht fehl. Aber trotzdem stehe ich ein bisschen auf dem Schlauch. Ich würde sagen 0xCC ist der ReportID, aber wo muss er dann in der Anweisung stehen und warum empfange ich mit ReadFile immer 0xCC?
Das mit dem HidP_GetUsageValue habe ich jetzt so gemacht:
HIDP_VALUE_CAPS ValueCaps; PUSHORT ValueCapsLength; ValueCapsLength = &Capabilities.InputReportByteLength; HidP_GetValueCaps(HidP_Input, &ValueCaps, ValueCapsLength, PreparsedData); printf("%s0x%X\n", "Input - ReportID: ", ValueCaps.ReportID); . . .
Resultat:
Input - GetValueCaps: Input - ReportID: 0xCC Input - BitField: 0xCCCC Input - BitSize: 0xCCCC Input - LinkCollection: 0xCCCC Input - LinkUsage: 0xCCCC Input - LinkUsagePage: 0xCCCC Output - GetValueCaps: Output - ReportID: 0xCC Output - BitField: 0xCCCC Output - BitSize: 0xCCCC Output - LinkCollection: 0xCCCC Output - LinkUsage: 0xCCCC Output - LinkUsagePage: 0xCCCC
-
baschti schrieb:
WriteFile(... if(WriteFile == 0)
Da der Funktions-Pointer nicht NULL ist, wird hier Falle eines Fehlschlags niemals true rauskommen. Das geht so:
if(!WriteFile(...)) { // Fehlschlag }
Das Selbe gilt logischerweise auch für ReadFile. Der Aufruf von SetLastError ist an dieser Stelle zwar nicht schädlich, aber überflüssig.
baschti schrieb:
HIDP_VALUE_CAPS ValueCaps; PUSHORT ValueCapsLength; ValueCapsLength = &Capabilities.InputReportByteLength;
Und was ist nun der Inhalt von ValueCaps? Ist die Capabilities-Struktur korrekt gefüllt?
baschti schrieb:
HidP_GetValueCaps(HidP_Input, &ValueCaps, ValueCapsLength, PreparsedData); printf("%s0x%X\n", "Input - ReportID: ", ValueCaps.ReportID); . . .
Resultat:
Zum Resultat kann ich gern etwas sagen. Aber erstmal sagst Du mir, ob HidP_GetValueCaps fehlschlägt oder nicht (--> die Prüfung fehlt hier). Wenn wenn die Funktion fehlschlagen sollte: Was sagt GetLastError?
Außerdem darfst Du nicht einfach &ValueCaps schreiben. Da wird ein Array in der Größe ValueCapsLength erwartet, das passt bei Dir nur zufällig. In jeder anderen Anwendung kommt es hier zum Crash. Deswegen habe ich auch weiter oben new verwendet.
-
baschti schrieb:
ValueCapsLength = &Capabilities.InputReportByteLength;
Das ist natülich falsch! Wenn schon, dann so:
ValueCapsLength = &Capabilities.NumberInputValueCaps;
Das habe ich leider im Eifer des Gefechts weiter oben bereits falsch vorgemacht. Sorry!
-
Hab's jetzt mal so gemacht, wie Du's gesagt hast:
HIDP_CAPS Capabilities; PHIDP_PREPARSED_DATA PreparsedData; HIDP_REPORT_TYPE HidP_Input; USHORT ValueCapsLength; HIDP_VALUE_CAPS* pValueCaps = new HIDP_VALUE_CAPS[ValueCapsLength]; . . . HidD_GetPreparsedData(hTreiber, &PreparsedData); HidP_GetCaps(PreparsedData, &Capabilities); printf("%s%d\n", "Usage: ", Capabilities.Usage); printf("%s0x%X\n", "Usage Page: ", Capabilities.UsagePage); printf("%s%d\n", "Input Report Byte Length: ", Capabilities.InputReportByteLength); . . . ValueCapsLength = Capabilities.NumberInputValueCaps; printf("Input - GetValueCaps:\n\n"); if(!HidP_GetValueCaps(HidP_Input, pValueCaps, &ValueCapsLength, PreparsedData)) { CloseHandle(hTreiber); printf("Error: %u\n", GetLastError()); } printf("ValueCaps: 0x%X\n", pValueCaps); printf("%s0x%X\n", "Input - ReportID: ", pValueCaps.ReportID);
nur bekomme ich jetzt den Fehler:
error C2228: Der linke Teil von '.ReportID' muss eine Klasse/Struktur/Union sein
Wenn ich die letzte Anweisung auskommentiere, bekomme ich für
pValueCaps: 0x431D40
und keinen Fehler über GetLastError().
Vorhin dachte ich, das wäre schon die gefüllte ValueCaps-Struktur:baschti schrieb:
Resultat:
Input - GetValueCaps: Input - ReportID: 0xCC Input - BitField: 0xCCCC Input - BitSize: 0xCCCC Input - LinkCollection: 0xCCCC Input - LinkUsage: 0xCCCC Input - LinkUsagePage: 0xCCCC Output - GetValueCaps: Output - ReportID: 0xCC Output - BitField: 0xCCCC Output - BitSize: 0xCCCC Output - LinkCollection: 0xCCCC Output - LinkUsage: 0xCCCC Output - LinkUsagePage: 0xCCCC
Ich verzweifle gleich!
-
baschti schrieb:
nur bekomme ich jetzt den Fehler:
error C2228: Der linke Teil von '.ReportID' muss eine Klasse/Struktur/Union sein
Hast den Begriff Pointer schon mal gehört? Hast Du new überhaupt schon mal benutzt?
printf("%s0x%X\n", "Input - ReportID: ", pValueCaps->ReportID);
Und da es sich um ein Array handelt, kannst Du das auch so machen:
printf("%s0x%X\n", "Input - ReportID: ", pValueCaps[i].ReportID);
Für i gilt:
0 <= i < Capabilities.NumberValueCaps
Und bevor Du wieder mit mir schimpfst: Bewusst schrieb ich nur NumberValueCaps. Je nach gewünschtem Report verwendest Du natürlich Number -Input/ Output/ Feature - ValueCaps.
BTW: Es scheint mir angebracht, auch auf delete hinzuweisen. Wenn Du also mit den HIDP_VALUE_CAPS-Structs fertig bist, Freigabe nicht vergessen:
delete [] pValueCaps;
-
Ich gelobe Besserung. Hab' manchmal Probleme mich zurecht zu finden.
ok?Input - GetValueCaps: ValueCaps: 0x431D90 Input - ReportID: 0xFD Input - BitField: 0x0 Input - BitSize: 0x43 Input - LinkCollection: 0x0 Input - LinkUsage: 0x31 Input - LinkUsagePage: 0x0
Output - GetValueCaps: ValueCaps: 0x431D90 Output - ReportID: 0xFD Output - BitField: 0x0 Output - BitSize: 0x43 Output - LinkCollection: 0x0 Output - LinkUsage: 0x31 Output - LinkUsagePage: 0x0
Kannst Du mir bitte noch was zum Resultat sagen, was Du vorhin angesprochen hast, was ich jetzt damit anfange? Danke
Ich glaube, ich brauche echt erstmal Urlaub.
-
Mit diesem Resultat kannst Du gar nicht anfangen. Alle Werte auf 0xCD sagen nicht so sehr viel aus. Da stimmt noch etwas nicht.
BTW: Die HidP_-Funktionen geben einen Status-Code direkt zurück. So, wie es auch in der Hilfe beschrieben steht. Du kannst nicht einfach mit if(!HidP_ auf Fehlschlag testen.
NTSTATUS stat; stat = HidP_GetValueCaps(...); if(HIDP_STATUS_SUCCESS == stat) { // Ok } else { printf("Error: 0x%08X\n", stat); }
-
Habe meinen Fehler gefunden, schau nochmal bitte, hab's weiter oben editiert.
-
Ist ReportCount = 6 und IsRange = TRUE? Ist 0xFD als ReportID tatsächlich richtig (kannst mit Deinem Sniffer schauen, was das Gerät auf den GET_REPORT Request antwortet)? Irgendwie sieht das doch anders aus, als ich es erwartet hätte. Vielleicht kannst Du noch ein paar andere Felder der Struktur aufdröseln.
Was ist denn jetzt eigentlich aus den ReadFile/ WriteFile-Aufrufen geworden, funktionieren die jetzt?
-
Ich gehe Deinen Fragen gleich mal nach. Was für Werte hättest Du erwartet?
War vorhin in der MSDN zu NTSTATUS, habe dort leider nur die Bereiche für Fehler, Erfolge, Informationen,... gefunden. Gibt es da eine Auflistung der Fehler?
Ich habe meine printf-Anweisungen der VALUE_CAPS-Struktur in die if-Schleife geschrieben und komischerweise einen Fehler 0xC0110222 (oder so ähnlich) bekommen. Hatte ValueCapsLength zunächst mit 0 initialisiert.
ReadFile gibt immer noch 0xCC zurück, obwohl kein Fehler kommt.
-
baschti schrieb:
Ich gehe Deinen Fragen gleich mal nach. Was für Werte hättest Du erwartet?
Jedenfalls andere. Einmal 43 Bit passen nicht so richtig zu einer Report-Länge von 261 Bytes, jedenfalls für meinen Geschmack.
baschti schrieb:
War vorhin in der MSDN zu NTSTATUS, habe dort leider nur die Bereiche für Fehler, Erfolge, Informationen,... gefunden. Gibt es da eine Auflistung der Fehler?
Gültige Werte stehen in der Hilfe. Wenn Du Dir beispielsweise mal bei HidP_GetValueCaps den 'Return Value' anschaust:
MSDN schrieb:
HidP_GetValueCaps returns one of the following status values.
HIDP_STATUS_SUCCESS
- The routine successfully returned the capability data.HIDP_STATUS_INVALID_PREPARSED_DATA
- The preparsed data is not valid.Die komplette Auflistung findest Du in <hidpi.h>.
baschti schrieb:
Ich habe meine printf-Anweisungen der VALUE_CAPS-Struktur in die if-Schleife geschrieben und komischerweise einen Fehler 0xC0110222 (oder so ähnlich) bekommen. Hatte ValueCapsLength zunächst mit 0 initialisiert.
Ich tippe auf 'oder so ähnlich'. Aber davon ab: Du sagst der Funktion, daß Du ein Array in der Größe 0 übergibst. Deswegen füllt die Funktion nun 0 Strukturen. Wenn die Funktion zurückkehrt, ändert sie ValueCapsLength auf die tatsächlich ausgefüllten Strukturen. Es muß 0 bleiben, es ist auch rein gar nichts passiert (wie auch?).
Und bitte sage nicht 'if-Schleife'. Da zieht sich alles zusammen, das ist doch keine Schleife.
baschti schrieb:
ReadFile gibt immer noch 0xCC zurück, obwohl kein Fehler kommt.
Als direkten Return-Value, ja? Dann schauen wir doch schnell mal in die Hilfe zu ReadFile und lesen, was dort unter 'Return Values' steht:
MSDN schrieb:
If the function succeeds, the return value is nonzero.
Es hat funktioniert! Du hast erfolgreich Daten vom Gerät empfangen. Dann nehme ich an, daß Du auch erfolgreich Daten an das Gerät senden kannst, ja?
-
-King- schrieb:
Und bitte sage nicht 'if-Schleife'. Da zieht sich alles zusammen, das ist doch keine Schleife.
uarghhh... , dafür kannst Du mich steinigen. Ist mir beim Schreiben nicht aufgefallen - if-Anweisung.
Danke für die Tips. Ich setze das gleich mal um. Tut mir leid, wenn das von mir manchmal nicht so perfekt rüberkommt.
Bevor ich ins Praktikum gekommen bin, hatte ich eher ein beschränktes Wissen über hardwarenahe Programmierung und nie gedacht, dass mir das soviel Spass macht und ich doch relativ weit bisher gekommen bin, auch Dank Deiner Hilfe. (Obwohl manchmal bei mir trotzdem einer auf der Leitung steht )
-
Was ist denn das fürn Praktikum? Und nein, ich bin nicht neugierig. Interessieren tut's mich aber doch.
(ein klein wenig OT wird uns flenders hoffentlich nachsehen)
-
Mahlzeit!
Ist das Betriebs-Praktikum im Rahmen meines Studiums (Maschinenbau) - nicht schlagen, dass ich ein Student bin - über 20 Wochen. Dabei soll ich das Programm schreiben, womit ich beliebige Variablen aus der SPS lesen und bei Bedarf ändern kann. Die SPS steuert eine Prüfpresse. Die Geräte sind leider nicht so teuer um eine MPI- oder Ethernet-Verbindung zu verwenden, wozu es Software gibt (komischerweise zu USB nicht).
Und Schwupps..., da war mein Thema geboren.Leider hat bei mir in der Firma keiner Ahnung mit USB bzw. C/C++ umzugehen und so hab' ich mich ans Forum gewandt.
-
baschti schrieb:
- nicht schlagen, dass ich ein Student bin
Was? Wie kommst Du denn darauf? Ich wünschte, ich hätte studiert ...
Aber so, wie Du das sagst, hast Du wohl schon einige Nackenschläge abbekommen, was?
-
Manchmal schon, Vorurteile von wegen faul, ständig frei, die haben doch nur den Lenz und nichts zu tun. Aber das ist halb so wild.
Wir hören lieber auf, sonst kriegen wir von den Mods noch eins auf die Mütze.