Forum: Mikrocontroller und Digitale Elektronik STM32G4 mit MCP2517FD: Wie bekomme ich alle CAN-Nachrichten in TeraTerm


von Kevin R. (kevin_r715)


Lesenswert?

Hallo zusammen,

Ich arbeite gerade an einer CAN-FD Schnittstelle und habe folgendes 
Problem:
- mein Ziel ist es mindestens 100 (random erzeugte) CAN FD Nachrichten 
pro Sekunde zu senden (Übertragungsgeschwindigkeit: 2Mbit/s) und diese 
auch auf zum Beispiel TeraTerm sichtbar zu machen.

Es sollen die ID und die "Nachricht" in einer Konsole dargestellt 
werden. UART ist meines Wissens nach zu langsam (bekomme maximal 
70Nachrichten/Sek mit sprintf und HAL_USART_Transmit bei einem Array mit 
einer Länge von 32) und die CDC-USB-Lib von STM mit einem Virtual 
COM-Port bekomme ich nicht wirklich zum laufen. Das CAN FD Interface 
läuft schon ziemlich gut. Die Nachrichten können gesendet und gelesen 
werden, lediglich die USB-Anbindung fehlt. Wenn das Interface ohne 
Nachrichtenübertragung an den PC läuft, dann schafft das Interface mind. 
3000Nachrichten/Sekunde. Sobald ich jedoch die Nachrichten an den PC 
weiterleiten möchte, fällt der Wert auf ein Minimum.

Ich bräuchte Unterstützung mit der Datenübertragung, mit dem ich den in 
einer For-Schleife erzeugten Nachrichten Array uint8_t txd[64] effizient 
an den PC schicken kann. Der STM32G431KB hat einen FS-USB.

Später sollen mit der gleichen Schnittstelle auch die empfangenen 
Nachrichten an den PC gesendet werden.

Wenn Ihr weitere Informationen braucht dann meldet euch bitte. Ich werde 
die Informationen schnellst möglichst nachtragen.

von Kevin M. (arduinolover)


Lesenswert?

UART kann je nach Controller auch deutlich mehr als 2MBit/s, du solltest 
halt nicht die Blocking Funktion benutzen. Hier bietet sich der Versand 
über DMA an. Der empfangende Adapter muss die hohe Datenrate natürlich 
auch unterstützen.

USB CDC ist mit der HAL eigentlich ganz simpel. In Cube aktivieren und 
einfach die FS_Transmit (alt. HS_Transmit) Funktion benutzen.

: Bearbeitet durch User
von N00B (Gast)


Lesenswert?

Sendest du die Daten als String?
Sonst wäre es vielleicht noch eine Möglichkeit, ein halbwegs als Hex 
lesbares Format zu wähle und die Daten binär über die UART zu schieben.

von N00B (Gast)


Lesenswert?

Wie schnell ist denn die UART aktuell?
Wie schnell ist sprintf eigentlich auf so einem Chip? Bei 100 msgs/sec 
kann ich mir gut vorstellen, dass das noch passt, aber bei deutlich 
mehr? (Wenn das RX dann hinzukommt)

von Kevin R. (kevin_r715)


Lesenswert?

Kevin M. schrieb:
> mehr als 2MBit/s, du solltest halt nicht die Blocking Funktion benutzen. Hier 
bietet sich der Versand über DMA an.

Hallo zusammen,

DMA Implementierung hat deutlich länger gedauert als ich dachte. Läuft 
jetzt. Habe noch mal recherchiert wie weit ich die Baudrate aufdrehen 
kann bei dem Chip: 21,25Mbaud. Komme damit auf ca. 250 komplette CAN-FD 
Nachrichten, welche in teraterm bestaunen kann. Das läuft stabiler als 
ich dachte bei so hohen Baudraten.

Die Nachrichten sehen wie folgt aus, ein Beispiel:
ID: 2015
10 11 12 13 14 15 16 ... 73
ID: 2016
20 21 22 23 ... 83

N00B schrieb:
> Sonst wäre es vielleicht noch eine Möglichkeit, ein halbwegs als Hex
> lesbares Format zu wähle und die Daten binär über die UART zu schieben.

Danke für den Hinweis. Ich werde jetzt erstmal die o. g. Rate 
akzeptieren und in einer späteren Verbesserungsphase nochmal an dieser 
Stelle Hand anlegen.
Wenn es soweit ist werde ich mich sehr wahrscheinlich nochmal melden.

Werde im nächsten Schritt den Receiver Part noch  zum Interrupt umbauen. 
die meisten Codes die verfügbar sind, fragen lediglich zyklisch den PIN 
ab, ob dieser Low oder High ist. Finde ich nicht ganz so fein.

grüße
Kevin

von PittyJ (Gast)


Lesenswert?

Ich bin auch gerade beim Uart mit ähnlichen Anforderungen.
Bei dem habe ich auf
HAL_UART_Transmit_IT ()
umgestellt. Dazu noch ein passender Fifo-Buffer.
Zusammen mit der Einstellung der Schnittstelle auf 115200 Bits/Sekunde 
schaffe ich es locker, die Daten zum PC zu senden.

von Kevin R. (kevin_r715)


Lesenswert?

PittyJ schrieb:
> Ich bin auch gerade beim Uart mit ähnlichen Anforderungen.
> Bei dem habe ich auf
> HAL_UART_Transmit_IT ()
> umgestellt. Dazu noch ein passender Fifo-Buffer.
> Zusammen mit der Einstellung der Schnittstelle auf 115200 Bits/Sekunde
> schaffe ich es locker, die Daten zum PC zu senden.

Hey,

das hört sich gut an! Wie baust du denn die Nachrichten auf und richtest 
du den FIFO ein? -letzteres habe ich noch nie implementiert, zumindest 
nicht bewusst :)

Ich baue zum Beispiel die Nachrichten wie folgt auf:
1
 for(int i = 0;i <64;i++)
2
    {
3
      txd[i] =rand();
4
    }
versendet werden diese wie folgt:
1
  uint8_t n= sprintf(dma_buffer, "TRANS-CH%d ID %d : \r\n", index, SID);    //String conversion HEader+ID
2
  main_UART_TransmitFctKR(dma_buffer, n);      // DMA UART transmit function with while loop
3
  for (int i=0;i<64; i++)      // For Loop for message xxx -> improvment necessary
4
    {
5
     n = sprintf(dma_buffer, "%d ", txd[i]);
6
     main_UART_TransmitFctKR(dma_buffer, n);
7
    }
8
  main_UART_TransmitFctKR(bufferNL,nNL);      // creates new line at the end of the Message

Hier noch die "main_UART_TransmitFctKR(dma_buffer, n)"-Funktion:
1
  HAL_UART_Transmit_DMA(&huart2, buffer, length);
2
    while (HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY)
3
      {
4
      }

Würde mich freuen, wenn du deinen Code hier teilen könntest! Danke dir, 
PittyJ!

von PittyJ (Gast)


Lesenswert?

Kevin R. schrieb:
> Würde mich freuen, wenn du deinen Code hier teilen könntest! Danke dir,
> PittyJ!

Den Code darf ich nicht teilen, der gehört meinem Arbeitgeber.

Zur Struktur. Ich lege einen 10K Buffer an. Dann Fifo-Strukturen dazu, 
also hinten reinschreiben, vorne rauslesen.

Dan wird der Uart auf Interrupt Betrieb initialisiert, und der Callback 
Handler für RXComplete eingebaut. Und immer, wenn der aufgerufen wird, 
holt er sich ein paar Zeichen aus dem Fifo in einen Schreibbuffer. 
Dieser wird dann mit Transmit_IT im Hintergrund gesendet.

von Falk B. (falk)


Lesenswert?

Kevin R. schrieb:
> das hört sich gut an! Wie baust du denn die Nachrichten auf und richtest
> du den FIFO ein? -letzteres habe ich noch nie implementiert, zumindest
> nicht bewusst :)

Siehe FIFO, dort gibt es auch fertigen Quelltext.

von Falk B. (falk)


Lesenswert?

Kevin R. schrieb:
> - mein Ziel ist es mindestens 100 (random erzeugte) CAN FD Nachrichten
> pro Sekunde zu senden (Übertragungsgeschwindigkeit: 2Mbit/s) und diese
> auch auf zum Beispiel TeraTerm sichtbar zu machen.

Naja, man muss zwischen der Busgeschwindigkeit und der mittleren 
Datenrate unterscheiden. CAN hat bei max. 8 Byte/Paket 109Bit/Paket. 
Macht bei 2Mbit/s 18348 Pakete/s. Du willst aber nur 100, das sind nur 
10900 Bit/s. Selbst bei der verschwenderischen ASCII-Kodierung und noch 
bissel Krimskrams kommt man da bestenfalls auf Faktor 3, macht 
~30kbit/s. Jeder Standard-USRT schafft 115200 Bit/s brutto, was netto 
immer noch ~92kbit/s sind. Also vieeeeel Luft. Wie schon geschrieben, 
reicht ein FIFO.

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.