Forum: Mikrocontroller und Digitale Elektronik Virtual COM Port - CTS übertragen


von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich suche wie man das CTS Signal über VCP zum PC überträgt. Auf der
Homepage www.usb.org sind die Statusleitungen im Dokument "PSTN120.pdf"
beschrieben, jedoch nicht CTS.
Abschnitt:
6.5 PSTN Subclass Specific Notifications
6.5.4 SerialState

Kann man CTS überhaupt empfangen und zum PC senden?
Oder steht das in einem anderen Dokument/Spezifikation?

Grüße Markus

von Jim M. (turboj)


Lesenswert?

Markus M. schrieb:
> Kann man CTS überhaupt empfangen und zum PC senden?

Man könnte das auf TX oder RX "Carrier" Signale abbilden, aber die viel 
größere Frage ist: Wozu?

Normalerweise macht das USB Device den UART Flow Control. Wenn die 
Gegenstelle mittels CTS mitteilt das sie nix empfangen will, dann wird 
einfach nix gesendet.

Laufen jetzt die USB Device Fifos voll, werden einfach keine Daten mehr 
vom PC angenommem (NAK auf Bulk EP OUT). Es gehen keine Daten verloren.

Übrigens hatte ich auch schon recht kaputte UART Implementationen hier, 
die CTS bei jedem Byte kurz anschalten. Das könnte man über USB CDC gar 
nicht schnell genug abbilden.

Damit schränkt man auch die Auswahl von UAB2UART Chips IMHO auf (echte?) 
FTDI-Chips ein, denn viele andere Chipsorten brauchen ein (paar) Byte(s) 
um auf CTS zu reagieren bei schnellen Baudraten.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wenn die Handshakeleitungen im eigentlichen Sinn genutzt werden, kann 
das CDC-Device natürlich den Kram selbständig abwickeln.

Wenn aber eine Bitbanging-Anwendung umgesetzt wird, bei der die 
Handshakeleitungen als simple Ein- oder Ausgänge genutzt werden, dann 
ist das mit so einem CDC-Device nicht umsetzbar.

Die klassische PC-UART, die 8250, die kannte letztlich nur diese 
Betriebsart, die sogenannte "Hardwareflussteuerung" fand hier in 
Software im UART-Devicetreiber statt. Die UART selbst kannte eine 
derartige Betriebsart gar nicht, der war es komplett egal, welchen 
Zustand die Handshakeleitungen hatten.
Das war auch mit der um FIFOs erweitertern 16550 nicht anders, auch 
diese hatten keine Unterstützung für echtes Hardwarehandshake.

Und damit eigneten sich all' diese PC-UARTs wunderbar für den 
Bitbanging-Missbrauch, wie er u.a. auch in manchen AVR-ISP-Adaptern 
umgesetzt wurde.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ja, genau diese Steuerleitungen brauche ich im PC Programm, da damit 
aktuelle Zustände erfasst werden. Also diese Leitungen werden 
"Missbraucht" für extra Features. Aktuell geht es um einen Nachbau einer 
alten Hardware, die Software ist auch schon so alt und kann ich deshalb 
nicht mehr "Updaten".

von Jim M. (turboj)


Lesenswert?

Markus M. schrieb:
> Ja, genau diese Steuerleitungen brauche ich im PC Programm

Das geht dann nicht gut über USB, da hier signifikante Latenzen 
auftreten.

Abhilfe: PCI oder PCIe <-> RS232 Karte benutzen.

Oder Projekt völlig in einen µC gießen, also komplett neu entwickeln.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Jim M. schrieb:
> Das geht dann nicht gut über USB, da hier signifikante Latenzen
> auftreten.

Das ist natürlich nur relevant, wenn hier auch tatsächlich ein 
kritisches Timing dahinterhängt. Sofern es nur um das reine Erfassen 
irgendwelcher Zustände und nicht die schnelle Reaktion darauf geht, kann 
man das schon auch über USB abwickeln.


Allerdings nicht mit CDC, sondern, wenn es eine serielle Schnittstelle 
bleiben soll, nur mit dedizierten USB-UART-Lösungen mit proprietärem 
nicht-CDC-Protokoll, wie es z.B. die FTDI-UARTs verwenden.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Auf der USB-Seite nehme ich einen STM32F0xx, den kann ich als VCP 
programmieren wie ich mag. Es gibt im CubeMX gute Vorlagen. Nur diese 
zusätzliche Ansteuerung der Steuerleitungen sowie das Übertragen der 
Statusleitungen muss man noch selbst rein machen. Und da sich ST mit dem 
VCP Treiber natürlich an die USB Spec von usb.org halten muss wollte ich 
deren Möglichkeit nutzen.
Alternativ müsste ansonsten eine eigener Treiber geschrieben werden, der 
das kann. Denn die Windows API unterstützt bei nativen COM Ports schon 
immer die Übertragung der Steuerleitungen. Doch eine Treiberentwicklung 
ist enorm schwierig, nur der kleinste Fehler und es kommt zum 
BlueScreen, daher wollte ich bestehende und verifizierte Treiber 
einsetzen.

Nun suche ich wie das USB Telegramm aufgebaut sein muss damit das CTS 
Signal durch den Treiber an die Win API geschickt wird.

Hier ist beschrieben wie man den "SERIAL_STATE" übertragen kann (für 
DCD/DSR):
https://community.st.com/thread/30737

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Markus M. schrieb:
> Nun suche ich wie das USB Telegramm aufgebaut sein muss damit das CTS
> Signal durch den Treiber an die Win API geschickt wird.

Das geht mit CDC nicht, wie Du schon herausgefunden hast.

Es gibt kein USB-Telgramm für CDC, das dieses Signal transportiert, also 
gibt es auch im CDC-Gegenstück des USB-Hosts keinen Mechanismus, diese 
Information an die Serial-API von Windows durchzutunneln.

Daher kannst Du auch den VCP-Treiber von ST nicht verwenden.


Was Du machen könntest, wäre das Nachbilden des Verhaltens einer der 
USB-UARTs, die ein proprietäres Protokoll verwenden, damit Du deren 
Devicetreiber für Dich einsetzen kannst.

FTDI ist recht gut dokumentiert (in Form der Linux-Treiber-Sourcen), 
allerdings wendet FTDI auch einigen Aufwand auf, um Nachbildungen zu 
entlarven.

Da es aber auch für Bausteine von Prolific, SiLabs o.ä. 
Linux-Treiber-Sourcen gibt, könntest Du auch versuchen, das Verhalten 
eines dieser Bausteine mit Deinem µC nachzubilden, um den jeweils 
dazugehörenden Devicetreiber nutzen zu können.


Wenn das nicht möglich ist/zu umständlich ist, solltest Du überlegen, ob 
das Steuerverhalten der CTS-Leitung in Deiner Anwendung wirklich 
zwingend benötigt wird. Benutzt Du denn alle Handshakeleitungen? RI 
ist so ein gerne übersehener Kandidat, diese Leitung kommt durch CDC 
durch.

von Jim M. (turboj)


Lesenswert?

Markus M. schrieb:
> Alternativ müsste ansonsten eine eigener Treiber geschrieben werden, der
> das kann.

Oder man baut das USB Interface eine bekannten USB2UART nach. So haben 
wir hier mal einen CP210x auf einem Silabs 8051F340 emuliert.

Source für das Protokoll war der entsprechende Treiber im Linux Kernel, 
dort kann man nachsehen welche Byte Sequenzen gesendet werden.

Verkaufen würde ich sowas allerdings nicht - das war ein internes 
Projekt für einen RS485 Bus Monitor.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Ich habe gerade nochmal in der Software vom PC-Programm nachgeschaut, 
ich war damals schon so klug dass ich auch DSR als Steuersignal erkenne 
:-)
Das Programm hatte ich vor 15 Jahren geschrieben, da vergisst man 
manchmal was.

Dankeschön für eure Antworten, was meine Internetrecherche auch 
bestätigt hat.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Da du beide Seiten (PC-Programm und Hardware) selbst kontrollierst, 
kannst du die VCP-Krücke auch ganz weglassen, und ein eigenes 
USB-Protokoll ("vendor specific") implementieren. Vom PC aus kannst du 
da z.B. per libusb drauf zugreifen - seit Windows 8 geht das auch ohne 
manuelle Treiberinstallation indem man ein "WinUSB Device" 
implementiert, siehe z.B. USB-Tutorial mit STM32, Abschnitt "Eigene 
Anwendung für PC-Seite". Ist aus User-Sicht dann noch einfacher als ein 
VCP/COM-Port - anschließen, Anwendung starten, läuft (keine Auswahl 
COM-Port).

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Das Tutorial hatte ich gestern Abend auch schon gesehen und 
durchgelesen. Ich habe Win7 und das PC Programm kann ich nicht mehr 
ändern, da zu alt (und den Compiler müsste ich erst noch 
suchen/installieren).

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Achso :) Unter Windows 7 ist's aber auch kein großes Problem, man muss 
im Gerätemanager nur "winusb.sys" als Treiber auswählen oder das 
Programm "Zadig" das machen lassen. Alternativ eine eigene .inf + .cat 
Datei erstellen und die die winusb.sys laden lassen - Windows 7 erlaubt 
ja noch einigermaßen einfach die Installation selbst-signierter Treiber.
Das Programm lässt sich mit aktuellen Compilern nicht überetzen? Was für 
ne Sprache/Umgebung ist das denn?

von Joachim (Gast)


Lesenswert?

Niklas G. schrieb:
> Unter Windows 7 ist's aber auch kein großes Problem, man muss
> im Gerätemanager nur "winusb.sys" als Treiber auswählen oder das
> Programm "Zadig" das machen lassen.

Das geht zwar prinzipiell.
Er wird aber danach kein "COM" Device mehr haben (vom Windows mit dem 
Standadrdtreiber "USBSER.SYS" belegt), sondern ein freies "USB Device".
Da seine Software aber die bestehenenden COM-Ports abfragt, kommt er 
nicht mehr an das Gerät heran.
Ich habe das gleiche Problem mit meinem CDC-Device gehabt. Nachdem ich 
gemerkt hatte, dass "USBSER.SYS" eine Krücke ist, habe ich mein Gerät 
als eigenes Gerät mit WinUSB im Windows installiert.
Jetzt muss ich aber seitens der Applikation "zu Fuß" mein Gerät anhand 
der GUIDs in der Inf-Datei suchen. Es gibt im WinUSB keine Routinen zum 
Auffinden der Geräte. Du kannst Dich mit dem Gerät nur dann verbinden 
bzw. ein Handle auf das Gerät bekommen, wenn Du den Windows-"Devicepfad" 
kennst.
Um den zu bekommen, muss man sich zunächst durch die Windows-API 
durchwurschteln, was (in meinem Fall) ohne Vorkenntnis eine mittlere 
Herausforderung war. Oder in der Registry versuchen, das Gerät anhand 
der VID/PID zu finden, was aber auch wieder ohne Vorkenntnis ein Problem 
ist.

Gruß

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Joachim schrieb:
> Da seine Software aber die bestehenenden COM-Ports abfragt, kommt er
> nicht mehr an das Gerät heran.

Hier gäbe es noch den --umständlichen-- Ansatz, ein Programm zu bauen, 
das auf der einen Seite die Kommunikation via winusb abwickelt und auf 
der anderen Seite mit einer seriellen Schnittstelle kommuniziert.

Dieses Programm könnte man mit einem "virtuellen Nullmodem" à la com0com 
mit dem eigentlichen Programm verknüpfen ...


Allerdings scheint Markus das Problem schon längst gelöst zu haben, 
indem er einfach eine anderen Handshakeleitung verwendet.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Joachim schrieb:
> Er wird aber danach kein "COM" Device mehr haben (vom Windows mit dem
> Standadrdtreiber "USBSER.SYS" belegt), sondern ein freies "USB Device".
Ja natürlich, das war ja der Sinn der Sache.

Joachim schrieb:
> Da seine Software aber die bestehenenden COM-Ports abfragt, kommt er
> nicht mehr an das Gerät heran.
Die Software müsste er natürlich umprogrammieren. Bei direkter 
USB-Ansteuerung statt über VCP hat man mehr Kontrolle und Flexibilität 
und kann auch das Timing besser steuern, wenn man das braucht. Die 
Probleme mit Flusskontrolle und Erkennung von Paket-Anfängen erübrigen 
sich auch. Daher würde ich einen solchen Umbau nicht sofort als Problem 
sehen.

Joachim schrieb:
> Es gibt im WinUSB keine Routinen zum
> Auffinden der Geräte.
Kann sein. Ich verwende WinUSB indirekt über libusb, damit es auch unter 
Linux geht. Mit libusb kann man ein Gerät direkt über VID&PID finden:

http://libusb.sourceforge.net/api-1.0/group__libusb__dev.html
1
libusb_device_handle* libusb_open_device_with_vid_pid(libusb_context* ctx, uint16_t vendor_id, uint16_t product_id)     
2
3
Convenience function for finding a device with a particular idVendor/idProduct combination.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.