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
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.
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.
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?
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.
Das mit der idle line detection funktioniert nun prima, danke.
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.
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.
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.
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.
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?
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?
X4U schrieb: > STM Prozessoren keine Queue in den seriellen > Schnittstellen? Nö wozu, es gibt doch DMA...
Dr. Sommer schrieb: > Nö wozu, es gibt doch DMA... War nur ne Frage, gibt Prozessoren die das können.
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
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
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.