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
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.
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.
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".
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.
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.
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
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.
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.
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.
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).
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).
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?
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ß
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.
