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