Forum: Mikrocontroller und Digitale Elektronik STM32duino braucht kein DTR Signal mehr


von Hans W. (hanswieland)


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
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Hans W. schrieb:
> wenn der COM Port
> nicht geöffnet ist.

Ob der Port in einer Anwendung geöffnet ist oder nicht weiß die 
CDC-Firmware doch überhaupt nicht... Oder wurde DTR als 
"Geöffnet-Indikator" missbraucht?
von Hans W. (hanswieland)


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
von Hans W. (hanswieland)


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
von Niklas G. (erlkoenig) Benutzerseite


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.
von Ob S. (Firma: 1984now) (observer)


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...
von Hans W. (hanswieland)


Lesenswert?

Niklas G. schrieb:
> Klingt als wäre dieses Verhalten konfigurierbar und jetzt eben Default.

So etwas in der Art vermute ich auch. Am Modemmanager liegt es 
jedenfalls wohl nicht.
: Bearbeitet durch User
von G. K. (zumsel)


Lesenswert?

von Hans W. (hanswieland)


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
von Niklas G. (erlkoenig) Benutzerseite


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.
von G. K. (zumsel)


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.
von Niklas G. (erlkoenig) Benutzerseite


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.
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.