STM32&USB: WinAPI

Gast #5610692
Lesenswert?

Hallo.
Ich bin gerade am Umsetzen eines alten Projektes von RS232 auf USB.
Verwende dafür einen STM32 mit USB FS.

Bisher wurde Windows-seitig immer auf eine Nachricht von der RS232 
gepolled.
Ich frag mich jetzt, ob man dies eleganter (z.B. per Windows Message) 
lösen kann. (Btw Win32, kein .Net.)

Viele Dank
Pepe.
Gast #5610791
Lesenswert?

Die aktuelle Lösung ist Thread-basiert. Die will ich ja eigentlich nicht 
mehr.
Overlapped I/O hab ich mir schon angesehen. Aber die Beschreibung hat 
mich eher abgeschreckt. Außerdem geht dies eigentlich nicht in die 
Richtung, die ich suche.

Meine "normale" Kommunikation an mein USB Gerät kann synchron erfolgen. 
Der PC schickt einen Befehl raus, das Gerät antwortet sofort (<5ms).

Dann passiert vielleicht für einige Sekunden erstmal wieder nichts vom 
PC aus. In dieser Zeit kann es aber vorkommen, dass das Gerät eine 
Message schickt (weil irgendwas eingetreten ist). In der aktuellen 
Lösung wird ständig gepolled, damit ich diese Ereignisse sofort 
mitbekomme.

Also eigentlich bräuchte nur ein Event/Message/CallBack, dass mir 
mitteilt, dass was angekommen ist. Da erscheint mir - wenn ich es 
richtig verstanden habe - Overlapped I/O nicht das Richtige.

Oder liege ich da falsch?
Persönliche Seite #5610801
Lesenswert?

Pepe schrieb:
> Da erscheint mir - wenn ich es
> richtig verstanden habe - Overlapped I/O nicht das Richtige.

Genauso funktioniert das aber unter Windows. Normale Win32-C-Programme 
kennen erstmal keine "Callbacks", "Events" oder "Messages". Stattdessen 
brauchst du in der main()-Funktion eine main-Schleife, die das Win32-API 
wiederholt nach eingetretenen Ereignissen abfragt; das geht über die 
WaitForMultipleObjects-Funktion. Diese kehrt zurück, sobald etwas 
passiert ist. Dies gilt z.B. für GUI-Ereignisse (Mausklicks, Fenster 
geschlossen), kann aber auch für I/O genutzt werden, indem man eben 
Overlapped I/O nutzt, sodass die Funktion auch zurückkehrt, wenn z.B. 
per USB Daten ausgetauscht wurden. Frameworks wie MFC kapseln das und 
rufen dir nach der Rückkehr direkt eine Funktion ("Callback") auf, was 
die Sache vereinfacht, aber das Grundprinzip nicht verändert.
Wie behandelt deine Anwendung denn bisher asynchrone 
Ereignisse/Callbacks? Höchstwahrscheinlich sowieso (indirekt) über 
WaitForMultipleObjects. Das ganze ist aber wie gesagt stark vom bis 
jetzt nicht genannten Treiber abhängig.
Gast #5610819
Lesenswert?

Nicht über WaitForMultipleObjects. Sondern über ClearCommError wird 
abgefragt, ob Zeichen im Puffer stehen. Ansonsten bekomme ich die 
eingehenden Zeichen erst mit dem nächsten ausgehenden Befehl mit. Und 
das gefällt mir eben nicht.

Ich hatte auf ein Event wie WM_DEVICECHANGE gehofft. Einfach in den 
EventHandler reinhängen und drauf reagieren.

Dann werde ich wohl erstmal meinen Thread so umbauen, dass ich auch 
zwischen den Befehlen nach Zeichen im Puffer polle.
Persönliche Seite #5610835
Lesenswert?

Pepe schrieb:
> Ansonsten bekomme ich die
> eingehenden Zeichen erst mit dem nächsten ausgehenden Befehl mit. Und
> das gefällt mir eben nicht.

Heißt das du wartest überhaupt nie? Dann musst du sowieso umbauen.

Pepe schrieb:
> Ich hatte auf ein Event wie WM_DEVICECHANGE gehofft. Einfach in den
> EventHandler reinhängen und drauf reagieren.
Fast genauso kannst du es machen. Du musst halt statt GetMessage dann 
(Msg)MsgWaitForMultipleObjects aufrufen.
Gast #5610921
Lesenswert?

Letzten Endes wartet mein Thread auf die Antwort. Aber in dem Thread 
werden noch andere Themen behandelt (z.B. weitere IOs). Also möchte ich 
keine blockierende Lösung mit WaitFor...

Ich wollte eine elegantere Lösung finden.
Persönliche Seite #5610930
Lesenswert?

Pepe schrieb:
> Ich wollte eine elegantere Lösung finden.

Wie stellst du dir das denn genau vor? Willst du nicht-blockierend 
abfragen ob schon was angekommen ist? Ein hypothetisches Äquivalent zu 
WM_DEVICECHANGE könntest du ja so auch nicht nutzen, denn dafür musst du 
mit GetMessage blockierend warten, oder ständig PeekMessage aufrufen.
Am Elegantesten ist es eigentlich, auf alle I/O-Dinge per 
WaitForMultipleObjects zu warten. Wenn irgendwas fertig ist, reagierst 
du direkt darauf. So hast du nur diesen einzigen blockierenden Aufruf, 
der sich in einer Schleife befindet.
Persönliche Seite #5611351
Lesenswert?

Pepe schrieb:
> Aber in dem Thread werden noch andere Themen behandelt (z.B. weitere
> IOs). Also möchte ich keine blockierende Lösung mit WaitFor...

Deswegen gibt es ja WaitForMultipleObjects. Das blockiert nicht, sondern 
kann auf diverse Events gleichzeitig warten, und man bekommt 'raus, 
welches Event eingetrudelt ist, um darauf passend reagieren zu können.
Gast #5611910
Lesenswert?

Rufus Τ. F. schrieb:
> Deswegen gibt es ja WaitForMultipleObjects.

Und WaitForSingleObjectEx/WaitForMultipleObjectsEx. In Verbindung mit 
I/O completion routines ist das dann auch eher einfach zu programmieren.
Wenn man das Waitobject nicht noch für etwas anderes braucht, kann man 
dann acuh ganz darauf verzichten und SleepEx benutzen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren