STM32duino braucht kein DTR Signal mehr

OP #8049961
Lesenswert?

Mir ist gerade zufällig eine Änderung an der USB-CDC Schnittstelle aufgefallen:

Früher konnte ich den virtuellen COM Port nicht ohne Setzen des DTR Signals nutzen. Ein simpler Befehl wie

1
cat /dev/ttyACM0

brachte keine Ausgabe zustande, weil DTR dabei nicht eingeschaltet wurde. Außerdem blieben die Sketche immer nach einer Weile stehen, wenn der Ausgabepuffer voll lief.

Das ist nun nicht mehr so. Inzwischen geht es einfach mit dem cat Befehl. Und der Ausgabepuffer läuft nicht mehr voll, wenn der Port geschlossen ist.

: Bearbeitet durch User
OP #8049970
Lesenswert?

Niklas G. schrieb:

Oder wurde DTR als "Geöffnet-Indikator" missbraucht?

War wohl so. Früher reichte der cat Befehl nicht, es ging nur mit einem Terminalprogramm.

Allerdings: Ich wohl habe nicht genau genug hin geschaut. Wenn ich nämlich HTerm benutze und dort DTR aus schalte, stoppt die Übertragung sofort. Es sei denn, ich rufe vorher

1
SerialUSB.dtr(false);

dann stopp sie nicht. Das verunsichert mich nun.

Kann es sein, dass der cat Befehl von Linux neuerdings das DTR Signal setzt? In dem Fall wäre die entscheidende Änderung gar nicht im Arduino Core, sondern in Linux.

: Bearbeitet durch User
OP #8049984
Lesenswert?

Niklas G. schrieb:

Ob der Port in einer Anwendung geöffnet ist oder nicht weiß die CDC-Firmware doch überhaupt nicht

Offenbar weiß sie das zumindest nach einem Timeout. Auszug aus USBSerial.cpp:

1
size_t USBSerial::write(const uint8_t *buffer, size_t size)
2
{
3
  size_t rest = size;
4
  while (rest > 0 && CDC_connected()) {
5
    // Determine buffer size available for write
6
    auto portion = (size_t)CDC_TransmitQueue_WriteSize(&TransmitQueue);
7
    // Truncate it to content size (if rest is greater)
8
    if (rest < portion) {
9
      portion = rest;
10
    }
11
    if (portion > 0) {
12
      // Only if some space in the buffer exists.
13
      // TS: Only main thread calls write and writeSize methods,
14
      // it's thread-safe since IRQ does not affects
15
      // TransmitQueue write position
16
      CDC_TransmitQueue_Enqueue(&TransmitQueue, buffer, portion);
17
      rest -= portion;
18
      buffer += portion;
19
      // After storing data, start transmitting process
20
      CDC_continue_transmit();
21
    }
22
  }
23
  return size - rest;
24
}

Auszug aus usbd_cdc_if.c:

1
bool CDC_connected()
2
{
3
  /* Save the transmitStart value in a local variable to avoid twice reading - fix #478 */
4
  uint32_t transmitTime = transmitStart;
5
  if (transmitTime) {
6
    transmitTime = HAL_GetTick() - transmitTime;
7
  }
8
  return ((hUSBD_Device_CDC.dev_state == USBD_STATE_CONFIGURED)
9
          && (transmitTime < USB_CDC_TRANSMIT_TIMEOUT)
10
          && dtrState);
11
}

Die Abfrage von CDC_connected() ist wohl dafür entscheidend, dass der Ausgabepuffer nicht mehr voll läuft, wenn der Port geschlossen ist.

Aber eigentlich würde ich gerne klären, warum es heute mit dem cat Befehl funktioniert, vor ein paar Monaten aber nicht. Falls jemand dazu etwas weiß, wäre super.

: Bearbeitet durch User
Persönliche Seite #8050006
Lesenswert?

Hans W. schrieb:

dann stopp sie nicht.

Klingt als wäre dieses Verhalten konfigurierbar und jetzt eben Default.

Hans W. schrieb:

Kann es sein, dass der cat Befehl von Linux neuerdings das DTR Signal setzt?

Glaube ich kaum, cat weiß ja nichts von Serial-Ports. Eher ist es irgendeine Einstellung im Kernel oder etwas das per stty gesetzt wird...

Hans W. schrieb:

Offenbar weiß sie das zumindest nach einem Timeout. Auszug aus USBSerial.cpp:

Ist aber nur eine Heuristik/geraten...

Auf sowas sollte man sich sowieso nicht verlassen, das ist alles zu vage/unterspezifiziert.

(Firma: 1984now) #8050187
Lesenswert?

Niklas G. schrieb:

Glaube ich kaum, cat weiß ja nichts von Serial-Ports.

Genau so ist das. Das ist halt der Nachteil des Konzepts "alles ist eine Datei".

Eher ist es irgendeine Einstellung im Kernel oder etwas das per stty gesetzt wird...

Kommt drauf an, wer eigentlich die Schnittstelle öffnet. Der muss sie passend konfigurieren. Nachträgliche Änderungen sind u.U. zwar möglich, aber nicht uneingeschränkt. Wenn die Schnittstelle für ein Terminal benutzt wird, sind die Einschränkungen sogar ziemlich erheblich. Von diesem Terminal selber aus kann man natürlich nur die Einstellungen der "Gegenseite" ändern. Die müssen aber jederzeit kompatibel zu den Einstellungen der lokalen Schnittstelle bleiben, sonst ist's erst mal Essig mit der Kommunikation...

OP #8050341
Lesenswert?

Kann ein Moderator den Titel korrigieren? Er liest sich wie eine (falsche) Aussage. Ist blöd für Suchmaschinen und KI.

STM32duino braucht scheinbar kein DTR Signal mehr

Wäre wohl besser. Oder

Braucht STM32duino kein DTR Signal mehr?

Das wäre nett. Danke.

: Bearbeitet durch User
Persönliche Seite #8050352
Lesenswert?

Ob S. schrieb:

Genau so ist das. Das ist halt der Nachteil des Konzepts "alles ist eine Datei".

Der eigentliche Fehler besteht darin, CDC-ACM für etwas zu zweckentfremden, das kein Analog-Modem mit AT-Commands ist, denn genau dafür und nur dafür wurde CDC-ACM erfunden. Und da ist der Port permanent "geöffnet" durch den Treiber des Betriebssystems, um spontan ankommende Daten (z.B. "RING" als URC) zu verarbeiten.

#8050426
Lesenswert?

Niklas G. schrieb:

Der eigentliche Fehler besteht darin, CDC-ACM für etwas zu zweckentfremden, das kein Analog-Modem mit AT-Commands ist, denn genau dafür und nur dafür wurde CDC-ACM erfunden. Und da ist der Port permanent "geöffnet" durch den Treiber des Betriebssystems, um spontan ankommende Daten (z.B. "RING" als URC) zu verarbeiten.

Und was soll diese Daten verarbeiten wenn nix geöffnet ist? Und ein "RING" vom Treiber im Kernelspace verarbeiten zu lassen ist ein Design aus der Hölle.

Persönliche Seite #8050429
Lesenswert?

G. K. schrieb:

Und was soll diese Daten verarbeiten wenn nix geöffnet ist?

Eine Modem Management Software die eingehende Anrufe verarbeiten kann. Ich glaub Windows macht das von Haus aus, unter Linux wär's der Modem-Manager, der eben den Port permanent offen hat.

G. K. schrieb:

Und ein "RING" vom Treiber im Kernelspace verarbeiten zu lassen ist ein Design aus der Hölle.

Muss ja nicht im Kernelspace sein, der "Treiber" kann ja auch ein Userspace-Dienst/Daemon sein.

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