Forum: Mikrocontroller und Digitale Elektronik RS485 DMA zuverlässiges Protokoll


von Bert S. (kautschuck)


Lesenswert?

Hi,

Ich übertrage zwischen mehreren uC über RS485 Daten, welche mit dem DMA 
empfangen werden, wobei ein Paket immer 8 Byte ist und eine 8 Byte 
Adresse den Start/Identifikation des Slaves sowie den Stop eines 
Datenstreams angibt. Ein CRC check ist implementiert um die Daten auf 
Korrektheit zu prüfen. Das funktioniert soweit eigentlich sehr gut, 
jedoch sobald mal ein Byte verloren geht, ist der DMA Buffer um ein Byte 
verschoben, was sich dann nicht mehr so schnell erholt.

Wie genau kann ich das System bei einem solchen Datenverlust am besten 
zurücksetzen?

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

CAN funktioniert fast genau wie dein Protokoll, und kümmert sich 
automatisch um solche Probleme...
Manche UART's (z.B. die der STM32) sind in der Lage auf Lücken zwischen 
den Paketen zu reagieren und einen IDLE-Interrupt auszulösen; da 
könntest du das DMA neu aufsetzen, egal wie viele Bytes schon empfangen 
wurden.

von Bert S. (kautschuck)


Lesenswert?

Danke, da ich STM32 verbaut habe, schaue mir mal das mit dem Idle 
Interrupt an.

von m.n. (Gast)


Lesenswert?

Für Dein Problem halte ich den Empfang per DMA für eine schlechte 
Lösung. DMA bietet sich für größere Datenblöcke an, andernfalls ergibt 
sich kein Vorteil beim Empfänger.

von Thomas E. (picalic)


Lesenswert?

m.n. schrieb:
> DMA bietet sich für größere Datenblöcke an, andernfalls ergibt
> sich kein Vorteil beim Empfänger.

Ein einzelner DMA Interrupt vs. 8 Interrupts beim Empfang ohne DMA - ist 
das etwa kein Vorteil?
Oder wenn die Datenrate hoch und ISR-Latenzen krtisch sind - ist der 
Empfang ohne CPU-Belastung kein Vorteil?

von Win DJ Ammer (Gast)


Lesenswert?

Na. Eben, wenn die Recovery nicht so trivial ist ...
Das einfachste fuer verlorene Bytes waere ein Timeout.

Richtig, wenn die CPU Last hoch ist, macht DMA sicher Sinn. Schoen wenn 
man ein so einfaches Protokol mit fester Blocklaenge verwenden kann. 
Sonst wuerd ich DMA eher fuer groessere Blocklaengen verwenden.

Da wir nichts von der Anwendung wissen, koennen wir daher auch nicht 
drueber auslassen.

von Bert S. (kautschuck)


Lesenswert?

Das mit der idle line detection funktioniert nun prima, danke.

von Thomas E. (picalic)


Lesenswert?

Win DJ Ammer schrieb:
> Schoen wenn
> man ein so einfaches Protokol mit fester Blocklaenge verwenden kann.
> Sonst wuerd ich DMA eher fuer groessere Blocklaengen verwenden.

Auch mit variabler oder unbekannter Blocklänge, ja sogar bei einzelnen 
Bytes kann man die CPU gut entlasten, indem die Daten per DMA z.B. in 
einen Ringpuffer geschrieben werden. Außer vielleicht, falls die Daten 
gleich direkt in der Rx-ISR verarbeitet werden, sehe ich DMA immer im 
Vorteil, unabhängig von der Datenmenge.

von Dirk B. (Gast)


Lesenswert?

Thomas E. schrieb:
> Auch mit variabler oder unbekannter Blocklänge, ja sogar bei einzelnen
> Bytes kann man die CPU gut entlasten, indem die Daten per DMA z.B. in
> einen Ringpuffer geschrieben werden.
bei der Methode können dann aber schnell die Daten über die Daten, bspw. 
Blockanfang, Adressblock,...) die bei Zeit definierten Übertragungen im 
zeitlichen Abstand (tw. als 'timeouts' bezeichnet) einzelner Bytes 
zueinander übertragen werden, verloren gehen.

> Außer viellejbicht, falls die Daten
> gleich direkt in der Rx-ISR verarbeitet werden, sehe ich DMA immer im
> Vorteil, unabhängig von der Datenmenge.
der Vorteil nicht zu viele Informationen über die Daten zu habem ist 
natürlich unabhängig von der Menge ;-)

NB.: wenn die CPU entlastet werden muss, dann kann es helfen die Folgen 
der vorigen Überlastung zu analysieren. Wenn die CPU gemütlich in einer 
Schleife asynchrone Bytes inkl. der Zeiten verarbeitet und ganze Blöcke 
zeit kontrollierten Prozesse die per ISR ("Scheduler") aufgerufen 
werden, zur Verarbeitung übergibt, dann lässt sich eine Überlastung 
besser beseitigen indem einfach ein anderer Task eine niedrigere 
Priorität bekommt.

von Thomas E. (picalic)


Lesenswert?

Dirk B. schrieb:
> bei der Methode können dann aber schnell die Daten über die Daten, bspw.
> Blockanfang, Adressblock,...) die bei Zeit definierten Übertragungen im
> zeitlichen Abstand (tw. als 'timeouts' bezeichnet) einzelner Bytes
> zueinander übertragen werden, verloren gehen.

Wenn etwas wichtiges verloren gehen kann, ist etwas falsch 
implementiert. DMA ist ja auch keine "Methode" zur Verarbeitung der 
Daten, sondern nur ein Daten-Transportmechanismus. Die Auswertung des 
Protokolls muss immer in geeigneter Weise separat vorgenommen werden.
Zeitliche Informationen über Pausen im Datenstrom kann man z.B. über den 
bereits genannten IDLE-Interrupt erhalten - warum soll man die CPU dann 
mit dem stupiden Empfang jedes einzelnen Bytes unnötig beschäftigen?
Manche USARTs der STM32-Familien haben auch eine "Character 
Match"-Funktion und können einen Interrupt auslösen, wenn ein bestimmtes 
Byte erkannt wird.

Dirk B. schrieb:
> NB.: wenn die CPU entlastet werden muss, dann kann es helfen die Folgen
> der vorigen Überlastung zu analysieren.

Es geht nicht darum, daß es irgendwo wegen "Überlastung" klemmt, sondern 
darum, die CPU nicht unnötig mit Standardkram zu belasten, der besser 
von der Hardware direkt selbst erledigt werden kann. Ein USART-Interrupt 
für jedes Zeichen produziert jedesmal den entsprechenden ISR-Overhead. 
Besser weniger ISR-Aufrufe und die Daten dann als Block verarbeiten.

von Dirk B. (Gast)


Lesenswert?

Thomas E. schrieb:
> Dirk B. schrieb:
>> bei der Methode können dann aber schnell die Daten über die Daten, bspw.
>> Blockanfang, Adressblock,...) die bei Zeit definierten Übertragungen im
>> zeitlichen Abstand (tw. als 'timeouts' bezeichnet) einzelner Bytes
>> zueinander übertragen werden, verloren gehen.
>
> Wenn etwas wichtiges verloren gehen kann, ist etwas falsch
> implementiert.
Ja, einige Implementierungen können für etliche Protokolle wichtige 
Daten "Blockanfang", "Adressblock" " zeitlichen Abstand kodiert" nicht 
empfangen und sind darauf angewiesen bspw. konkret:"Blockanfang" mit 
"etwas" zu vertuschen.

> Die Auswertung des
> Protokolls muss immer in geeigneter Weise separat vorgenommen werden.
Nein ein solcher Trennungszwang besteht nicht. Für eine geplante 
Datenübertragung ist eine einfache Implementierung des Protokolls bspw. 
mit einer state-maschine oder einem µC und anschließender 
Datenauswertungg i.A. zieführender als das Protokoll in unspezifisch 
"geeigneter" Weise "auszuwerten" zu müssen.

> Zeitliche Informationen über Pausen im Datenstrom kann man z.B. über den
> bereits genannten IDLE-Interrupt erhalten - warum soll man die CPU dann
> mit dem stupiden Empfang jedes einzelnen Bytes unnötig beschäftigen?
ein Interrupt der unnötig beiläufige Prozesse unterbricht und damit 
andere u.U. kritischere, Interrupte aufwendiger macht ist eine häufig 
unnötige Beschäftigung mit solchen auch beiläufig zu erledigem Aufgaben. 
Natürlich kann auch eine aufwendige DMA <-> ISR <-> Daten <-> 
IDLE-Line-banging Implementierung funktionieren, wenn nichts dazwischen 
kommt und bspw. eine Implementierung keine geeignete Auswertung des 
Protokolls war ;-P

> Manche USARTs der STM32-Familien haben auch eine "Character
> Match"-Funktion und können einen Interrupt auslösen, wenn ein bestimmtes
> Byte erkannt wird.
warum auch nicht? auf der Ebene lassen sich auch bequem 
'in-band'-Protokolle definieren, die nur die zeitlichen Informationen 
bspw. eines Bytes nutzen und so dann auch einfach per DMA byteweise 
weiterverarbeitet werden können.
Im OT ging es aber um Pakete die erleslich auch 'out-of-band' Daten 
durch Datenabstand haben.

> Dirk B. schrieb:
>> NB.: wenn die CPU entlastet werden muss, dann kann es helfen die Folgen
>> der vorigen Überlastung zu analysieren.
>
> Es geht nicht darum, daß es irgendwo wegen "Überlastung" klemmt, sondern
> darum, die CPU nicht unnötig mit Standardkram zu belasten, der besser
> von der Hardware direkt selbst erledigt werden kann.
solch Empathie orientierter "Standardkram" wird für betroffene CPU 
häufig dann zur Belastung wenn eine CPU eine eigenverantwortliche 
Entscheidung treffen muss und nicht nur Standardkram.

> Ein USART-Interrupt
> für jedes Zeichen produziert jedesmal den entsprechenden ISR-Overhead.
> Besser weniger ISR-Aufrufe und die Daten dann als Block verarbeiten.
manche USARTs der STM32-Familien haben auch eine "Character 
Match"-Funktion und können einen Interrupt auslösen, wenn ein bestimmtes 
Byte erkannt wird, Für ein solches 1 Zeichen-Protokoll ist eine 
abschließende Behandlung in einer ISR u.U. sehr sinnvoll. Ein 
beiläufiger Prozess der jederzeit durch eine ISR unterbrochen werden 
kann und einfach mittels eines Flag aus einem regelmäßigen Prozess eine 
definiert(!) Zeitkontrolle beherrscht kann, wenn die zeitliche 
Blockverarbeitung gesichert ist, die einfachste und unbelastende 
Datenübertragung sein.

Viele Belastungen machen sich ja erst bemerkbar wenn die CPU so 
überfordert ist und nur noch undefinierten Standard nach Kramprotokoll 
irgendwie geeignet für irgendetwas auswertet.

von X4U (Gast)


Lesenswert?

Thomas E. schrieb:
> Ein einzelner DMA Interrupt vs. 8 Interrupts beim Empfang ohne DMA - ist
> das etwa kein Vorteil?

Sicher aber was hat das mit dem Protokoll und fehlenden Daten zu tun? 
Die Auswertung muss doch so oder so gemacht werden.

Wenn allerdings die Daten ohne DMA korrekt sind ... .

Noch ne Frage: Haben die STM Prozessoren keine Queue in den seriellen 
Schnittstellen?

von m.n. (Gast)


Lesenswert?

Thomas E. schrieb:
> Ein USART-Interrupt
> für jedes Zeichen produziert jedesmal den entsprechenden ISR-Overhead.

Na und? Das macht ein STM32 doch mit links.

> Besser weniger ISR-Aufrufe und die Daten dann als Block verarbeiten.

Solange man mit 8 Byte/Paket auskommt scheint das Datenvolumen nicht 
hoch zu sein.

Was noch offen geblieben ist: Mit welcher Baudrate wird denn gearbeitet? 
9600 oder sogar 19200 Bd?

von Dr. Sommer (Gast)


Lesenswert?

X4U schrieb:
> STM Prozessoren keine Queue in den seriellen
> Schnittstellen?

Nö wozu, es gibt doch DMA...

von X4U (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Nö wozu, es gibt doch DMA...

War nur ne Frage, gibt Prozessoren die das können.

von Bert S. (kautschuck)


Lesenswert?

m.n. schrieb:
> Was noch offen geblieben ist: Mit welcher Baudrate wird denn gearbeitet?
> 9600 oder sogar 19200 Bd?

115200 Bd/s. Das Protokoll habe ich jetzt auf Pakete der gösse 64 Byte 
angepasst.

: Bearbeitet durch User
von Dirk B. (Gast)


Lesenswert?

m.n. schrieb:
> Solange man mit 8 Byte/Paket auskommt scheint das Datenvolumen nicht
> hoch zu sein.
kannst du das Datenvolumen in klassischen Einheiten wie Byte/Sekunde 
o.ä. nennen und evtl. "scheint nicht so hoch" zumindest als Faktor zum 
16 Byte/Paket angeben?

> Was noch offen geblieben ist: Mit welcher Baudrate wird denn gearbeitet?
> 9600 oder sogar 19200 Bd?
wenn man solche Datenvolumen mit "19200 Bd?" erfragt, dann passen die 
wohl nicht mehr in 8 Byte/Paket

von Benjamin S. (recycler)


Lesenswert?

Du kannst dir einen Interrupt generieren lassen, wenn der Buffer halb 
voll ist.
Dabei startest du einen Timer der auf die letzten 4 Byte wartest. Sollte 
der DMA vorher fertig werden, so brichst du den Timer ab und verwendest 
die Daten normal bzw. führst sie der CRC Berechnung und Verarbeitung zu.
Wenn der Timervorher kommt, fehlt anscheinend was und du brichst den DMA 
ab und startest neu.

von m.n. (Gast)


Lesenswert?

Bert S. schrieb:
> 115200 Bd/s. Das Protokoll habe ich jetzt auf Pakete der gösse 64 Byte
> angepasst.

Nun gut, 115 kBd ist für mich noch kein Grund für DMA. Das sind ja 
gerade einmal 11 kHz Interruptrate, wobei der STM32 seine Interrupts 
zudem noch gut priorisieren kann.
Aber da Du die Paketgröße erhöht hast und die Sache funktioniert, lasse 
es so.

von Win DJ Ammer (Gast)


Lesenswert?

Allenfalls hat man auch ein EMV Problem wenn Packete resp Bytes verloren 
gehen.
-Allenfalls wurde vergessen den GND mitzufuehren.
-Allenfalls gibt es dynamische Potentialdifferenzen zwischen den beiden 
Seiten.
-Allenfalls wurde beim Layout geschlampt.

Denn 115k Ist ueberhaupt keine Geschwindigkeit fuer einen RS485 Treiber. 
Da gibt es welche mit 25MBit, und mit dem passenden Treiber gehen auch 
300m.

von Johannes S. (Gast)


Lesenswert?

Bert S. schrieb:
> Das mit der idle line detection funktioniert nun prima, danke.

Liest du hier noch mit? Mache gerade das gleiche, wie lange dauert es 
denn bis der Idle Interrupt nach einem Zeichen gefeuert wird?

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.