Hallo zusammen, folgende Situation: über UART werden bytes empfangen die zusammengehängt ein telegramm mit variabler länge ergeben die dann beim vollständigen empfang weiter bearbeitet werden. Soweit sogut, ISR schreibt Bytes in einen empfangspuffer und wenn telegrammende erkannt, wirds weitergereicht und zeitunkritisch verarbeitet. Problem: Innerhalb der ersten paar bytes kommt eine Information die ausgewertet werden muss und bevor das letzte byte des telegramms empfangen wurde muss bereits eine antwort etsprechend der auswertung gesendet werden. Die auswertung kann unterschiedlich lange dauern und es kann nicht sichergestellt werden das bis zum nächsten empfangsbyte alles fertig ist. Einfache Lösung: hardware uart empfangspuffer ausnützen um zeit für die ISR zu gewinnen und in der ISR die Auswertung machen und entsprechend antworten Frage: gibts eine elegantere Lösung die ohne hardware rx puffer auskommt? theoretische gedanken dazu: ISR darf nicht ins unterbrochene programm zurückspringen sondern an die stelle der auswertfunktion welche selbst wieder von der ISR unterbrochen werden darf, wenn auswertfunktion fertig spring zurück ins ursprüngliche programm. Ist sowas mit zb. einem avr denkbar? Wenn ja wie realisiert man das praktisch, wenn nein gibts andere methoden? danke jedem der darüber nachdenkt :)
Du könntest in der ISR einen Zustandsautomaten realisieren, durch den alle Bytes erst durch müssen, bevor du sie in den Puffer schreibst. Wenn dein Sonderbehandlungsbyte kommt, wird direkt ausgewertet. Nachtrag: Vielleicht könnte man mit setjmp/longjmp arbeiten, um die ISR aus dem normalen Kontrollfluss ausbrechen zu lassen... aber wenn die Auswertung zu lange dauert und zu häufig kommt, riskierst du schon aus Prinzip einen Stack-Overflow, egal wie du es anstellst.
:
Bearbeitet durch User
> gibts eine elegantere Lösung die ohne hardware rx puffer auskommt? Mir ist noch nicht klar, warum es nicht möglich ist, dieses eine Byte aus dem Input (die 'Information') in eine gesonderte Variable zu stellen, ein Flag zu setzen, welches dann in der Hauptschleife ausgewertet wird, dadurch die Antwort generiert wird, die dann per UART wieder rausgeht. Die ISR kann derweilen ja nach Input fleissig weiter das Telegramm zusammensammeln. Von solchen Spielchen > ISR darf nicht ins unterbrochene programm zurückspringen sondern > an die stelle der auswertfunktion welche selbst wieder von der > ISR unterbrochen werden darf, wenn auswertfunktion fertig spring > zurück ins ursprüngliche programm. die letztlich immer auf eine Stackmanipulation hinauslaufen, würde ich jedoch dringend abraten. Meistens ist das ein bereits halbgedrückter Auslöser auf der Pistole, mit der man sich dann selber ins Bein schiesst.
:
Bearbeitet durch User
Meist gibt eine detaillierte Analyse des Eingangs- und Ausgansprotokolls, deren kausale Zusammenhänge und die zeitlichen Verhältnisse bereits Informationen darüber, ob das überhaupt möglich ist, und ob dazu besonders ausgefuchste Tricks nötig sind; wobei letzteres eher darauf hinweist, dass die Geschwindigkeit des uC nicht ausreicht. Du kannst uns gerne diese Details posten, so das wir Dir eine zweite Meinung dazu geben können. Im übrigen stimme ich Karl Heinz bei, das ausgefuchste Tricks mit longjmp, Stackmanipulation etc. eher problematisch sind und vermieden werden sollten. Auch darin, dass Deiner Beschreibung nach, nichts dagegen spricht, bei auftreten der fraglichen Information ein Flag zu setzen und in den Lücken des weiteren Empfangs diese zu verarbeiten und die Antwort zu preparieren.
Franz schrieb: > Die auswertung kann unterschiedlich lange dauern und es kann nicht > sichergestellt werden das bis zum nächsten empfangsbyte alles fertig > ist. Das ist doch kein Problem. Die ISR bekommt auf jeden Fall ein FIFO und wird reentrant programmiert, was nicht sehr schwer sein dürfte. Jedes neue Byte kommt ins FIFO, danach wird der Interrupt wieder freigegen und die Auswertung bei Bedarf gestartet.
Franz schrieb: > Innerhalb der ersten paar bytes kommt eine Information die ausgewertet > werden muss und bevor das letzte byte des telegramms empfangen wurde > muss bereits eine antwort etsprechend der auswertung gesendet werden. Kann ich mir nicht vorstellen :-/ Ich verstehe das so: Der Sender schickt ein Datenpaket raus. Mitten im Empfang schickt der Empfänger eine Antwort. Was soll der Sender damit? Die Datenübertragung stoppen? Schnell das Datenpaket noch mal ändern? Anhand der Antwort die nächsten Daten bereitstellen? Oder was?
Also gemäß der Problembeschreibung mußt du sowohl die Daten vom UART abholen, höchstwahrscheinlich per ISR, als auch eine Sonderroutine starten die die eine Information auswertet und antwortet. Jetzt ist die Frage: Ist jedes Telegramm so gebaut, so daß diese Auswertung immer erfolgen muß bei jeder Nachricht? Zwei Strategien: Eine kleine ISR holt die Daten ab und aktiviert auch im Hauptprogramm zusätzlich eine weitere Programmunterbrechung um in die Auswerteroutine zu wechseln. Das hat was von nesteted Interrupts, denn es muß wohl eine echte Unterbrechung des Hauptprogramms sein um die Auswertung sofort zu starten, da die Antwort zeitkritisch ist. Ein Flag auf das das Hauptprogramm erst dann reagiert, wenn es dieses kontrolliert, wird da wohl nicht reichen. Zusätzlich kommt es vor das die kleine ISR die Auswwerteroutine selbst auch noch unterbricht, soll sie aber nicht erneut starten. Da behalt mal einer den Überblick. Alternativ können beide Operationen in einer ISR verschmolzen werden. Da aber während der Berechnung noch weitere Bytes abgeholt werden müssen, wird das auch wieder unübersichtlich, denn entweder läuft dann die ISR während des gesammten Transfers oder die ISR muß selbst erkennen wann sie länger als ein Byte läuft und dann flxibel mehr als ein Byte abzuholen bis die Auswertung komplett ist und dann bei Nachfolgenden Aufrufen nur noch die Kurzfassung der ISR ausführen bis das Telegramm fertig ist. Um aus dem Dilemma herauszukommen muß entweder die CPU schnell genug sein um die Auswertung zwischen zwei Bytes zuverlässig zu erledigen, oder das Protokoll muß entflochten werden. Müssen Empfang und Antwort wirklich atomar sein? Kann man das wirklich nicht splitten in Empfang und Antwort? Das harmoniert irgendwie nicht so wirklich mit dem Grundgedanken von ISRs. Die baut man eigentlich so, daß sie ihre Sache zwischendurch als jeweils abgeschlossenen Vorgang erledigen und die CPU nicht länger belegen/sperren. Daher wird in der Regel von komplexen ISRs abgeraten. Stattdessen nu mehrere byteweise Interrupts verschiedener Handlungsstränge (empfangen auswerten, senden) über ein Protokoll in einer rechenzeitabhängigen und daher nicht, oder nur schwer vorhersagbaren Reihenfolge zu verknüpfen ist noch weit weniger empfehlenswert als überlange ISRs.
danke für alle bisheringen kommentare.... das ganze ist mehr eine theoretische überlegung und sondierung welche möglichkeiten es noch zur optimierung gäbe um maximale flexibilität und stabilität zu gewährleisten. momentan fahre ich mit der einfachen variante alles in der isr auszuwerten und die antwort zu generieren, dabei muss ich aber darauf achten das die auswertung nicht zu lange dauert was gewisse einschränkungen mit sich bringt....(details darf ich hierzu leider nicht bekannnt geben) die Variante mit dem setzen eines Flags welches in der hauptschleife die auswertung triggert hab ich auch schon überlegt aber hier muss ich dann sicherstellen das ein schleifendurchlauf+auswertfunktion im worst case nicht länger dauert als der empfang des kleinsten telegramms was die flexibilität stark einschränkt (die libary wird von mehreren entwicklern verwendet) oder gibt es eine möglichkeit ohne OS direkt aus der isr heraus auf das flag im hauptprogramm zu reagieren? Das Stackmanipulationen gefährlich sind ist mir bewusst, jedoch einmal sauber implementiert dürfte es problemlos laufen...
Franz schrieb: > maximale flexibilität und > stabilität zu gewährleisten. Das ist weder das Eine noch das Andere. Es ist eine hochspezialisierte Optimierung und Aufgrund der Verschachtelung unübersichtlich und daher fehlerträchtig und sehr schwer wartbar. Franz schrieb: > dabei muss ich aber darauf > achten das die auswertung nicht zu lange dauert was gewisse > einschränkungen mit sich bringt.... Schneller im Sinne von Rechenzeit wird es dadurch auch nicht. Dadurch kannst du nur idle Zeiten und somit Vergeudung von Rechenzeit reduzieren. Unterm Strich kommt also nur dann etwas Gutes dabei heraus, wenn in der aktuellen Fassung Idle-Zeiten sind, die man einsparen kann, und der dafür zusätzlich nötige Overhead im Code geringer ist. Daher solltest du zunächst erstmal das Potential, das in den Leerlaufzeiten der aktuellen Fassung vergraben ist, abschätzen. Franz schrieb: > (details darf ich hierzu leider nicht > bekannnt geben) Es muß ja nicht sooo detailliert sein. Aber wie heißt es so schön: Keine Arme, keine Kekse. Je weniger man über das Problem und die Zielsetzung weiß, umso weniger können wir helfen. Man kann das "Wie" nicht ohne das "Was" lösen. Versuche daher das Problem neu zu formulieren. Mir scheint Du hättest gerne eine Art Softwarelösung für DMA für einen isochronen Datentransfer, während die ISR die Auswertung und Antwortfunktion übernimmt. Und das auch noch flexibel? Da würd ich mich eher nach einem anderen Controller mit Hardare-DMA und oder größerem Empfangspuffer umsehen. Man kann zwar optimieren, aber: Wer nicht vorhandene Hardware emuliert muß dafür Rechenzeit opfern. Schneller wird es nicht.
:
Bearbeitet durch User
Franz schrieb: > Das Stackmanipulationen gefährlich sind ist mir bewusst, jedoch einmal > sauber implementiert dürfte es problemlos laufen... Stackmanipulationen != sauber implementiert
Franz schrieb: > danke für alle bisheringen kommentare.... Bitte. > das ganze ist mehr eine theoretische überlegung und sondierung welche > möglichkeiten es noch zur optimierung gäbe um maximale flexibilität und > stabilität zu gewährleisten. Das hätten wir gerne vorher gewusst. > momentan fahre ich mit der einfachen variante alles in der isr > auszuwerten und die antwort zu generieren, Bis auf Sonderfälle eher negativ. Wobei das schwer einzusehen ist, wenn es denn in einem konkreten Fall geht. Aber im negativen Fall verpasst Du einen Interrupt. Das ist im Falle des UART noch OK, falls das Zeichen rechtzeitig abgeholt wird, bevor, der dritte Interrupt auftritt. Aber, wenn Du grundsätzlich ein Flag benutzt, dann musst Du darauf nicht so sehr achten und gewinnst ein klein wenig Zeit, die entscheidend sein kann. Die Zeit für die Verarbeitung des ersten Zeichens (1. INT) ist bei dieser Methode prinzipiell auf max. 2 nachfolgende Zeichen begrenzt. Bei der Flag-Methode aber ist die Zeit aber durch die Methode prinzipiell unbegrenzt (mal abgesehen davon ob und das das Protokoll ein anderes Zeitlimit einführt). > dabei muss ich aber darauf > achten das die auswertung nicht zu lange dauert was gewisse > einschränkungen mit sich bringt....(details darf ich hierzu leider nicht > bekannnt geben) Darauf musst Du sowieso achten. Nur das eben, wie oben beschrieben, Deine Grenzen bei der Direkt-Verarbeitung prinzipiell enger sind, als bei der Flag-Methode. > die Variante mit dem setzen eines Flags welches in der hauptschleife die > auswertung triggert hab ich auch schon überlegt aber hier muss ich dann > sicherstellen das ein schleifendurchlauf+auswertfunktion im worst case > nicht länger dauert als der empfang des kleinsten telegramms was die > flexibilität stark einschränkt (die libary wird von mehreren entwicklern > verwendet) oder gibt es eine möglichkeit ohne OS direkt aus der isr > heraus auf das flag im hauptprogramm zu reagieren? Deine Flexibilität ist durch die Flag-Methode grösser als bei der Direktverarbeitung. Wenn das nächstfolgende Telegramm minimal klein ist, dann musst Du in beiden Fällen bis dahin fertig sein. Falls Du eine sehr lange Hauptschleife hast, kannst Du eine Priorität für das Flag einführen. > Das Stackmanipulationen gefährlich sind ist mir bewusst, jedoch einmal > sauber implementiert dürfte es problemlos laufen... Sauber implementiert geht alles. Das ist nicht die Frage. Es ist nur recht kompliziert das sauber zu implementieren im Vergleich zu der Flag-Methode und wesentlich einfacher zu warten und zu debuggen.
Carsten R. schrieb: > Schneller im Sinne von Rechenzeit wird es dadurch auch nicht das nicht aber durch die entkopplung von der isr hätte ich länger zeit für die auswertung und damit werden die einschränkungen auf protokollseite minimiert Carsten R. schrieb: > Versuche daher das Problem neu zu formulieren. du hast es praktisch ja schon auf den Punkt getroffen Carsten R. schrieb: > Da würd ich mich > eher nach einem anderen Controller mit Hardare-DMA und oder größerem > Empfangspuffer umsehen. Das ganze soll aber möglichst hardwareunabhängig sein, daher käme nur eine softwarelösung in frage. Ich wollte eigentlich nur sicher gehen das ich nicht etwas übersehe aber wie es aussieht gibt es dazu keine einfache Lösung (außer hardware, puffer, rechenpower)
Bitflüsterer schrieb: > Falls Du eine sehr > lange Hauptschleife hast, kannst Du eine Priorität für das Flag > einführen. An der Stelle hakt es bei mir im Verständnis. Wie wird sichergestellt daß das Flag auch wirklich früh genug "abgeholt" wird? Priorität alleine reicht nicht. Das Hauptprogramm muß sehr spezielle Anforderungen diesbezüglich erfüllen oder man dürfte dies nicht dem Hauptprogram überlassen, sondern müßte unterbrochen werden und von einer Sekundärroutine aus der Library, die automatisch mit dem Empfang gestartet wird, abgearbeitet werden. Das wäre das gehampel was ich oben schon beschrieben hatte. Als Alternative bliebe noch ein Echtzeit OS, welches garantiert, daß das Flag in einer vorgegebenen Zeit abgeholt wird, sofern ein solches OS in Frage kommt. Franz schrieb: > Problem: > Innerhalb der ersten paar bytes kommt eine Information die ausgewertet > werden muss und bevor das letzte byte des telegramms empfangen wurde > muss bereits eine antwort etsprechend der auswertung gesendet werden. Ich hatte es so verstanden, daß die Antwort raus sein muß bevor die eingehende Nachricht komplett angekommen ist. Sind denn die minimale Telegrammlänge und die Auswertefunktion schon festgelegt oder soll das auch noch flexibel sein?
:
Bearbeitet durch User
Carsten R. schrieb: > Bitflüsterer schrieb: >> Falls Du eine sehr >> lange Hauptschleife hast, kannst Du eine Priorität für das Flag >> einführen. > > An der Stelle hakt es bei mir im Verständnis. Wie wird sichergestellt > daß das Flag auch wirklich früh genug "abgeholt" wird? Priorität alleine > reicht nicht. Es gibt eine Reihe von Umständen die wir hier möglicherweise nicht alle erfassen, die aber alle ein Rolle spielen. Beschränkt wir uns aber auf folgendes (nur um des Gesprächs willen; das muss nicht so fixiert bleiben): 1. Im Telegramm ist ein Byte auf das "sofort" reagiert werden muss. 2. Die Hauptschleife enthält Vorgänge welche die Bearbeitung des unter 1. genannten Sonder-Bytes unerwünscht verzögert dann setze ich eine "Priorität" wie folgt ein.
1 | main () { |
2 | int State = 1; |
3 | while (1) { |
4 | |
5 | if (Flag = 1) { Sonderbehandlung (); Flag = 0; } |
6 | |
7 | switch (State) { |
8 | case 1: LangerVorgang1 (); State = 2; break; |
9 | case 2: LangerVorgang2 (); State = 3; break; |
10 | case 3: LangerVorgang3 (); State = 1; break; |
11 | default: break; |
12 | }
|
13 | }
|
14 | }
|
Dazu gibts noch einige Varianten. Sind die Vorgänge noch zu lang, unterteile ich sie in kürzere. > Das Hauptprogramm muß sehr spezielle Anforderungen > diesbezüglich erfüllen Ich will das nicht verneinen, sehe aber, abgesehen von der Zeitforderung keine eigentlich speziellen Anforderungen. Habe ich da was übersehen? > ... oder man dürfte dies nicht dem Hauptprogram ... Was meinst Du mit "dies"? > ... überlassen, sondern müßte unterbrochen werden und von einer > Sekundärroutine aus der Library, die automatisch mit dem Empfang > gestartet wird, abgearbeitet werden. Ich kannt Dir nicht folgen. Wenn ich Dich recht verstehe, dann meinst Du, dass die Einführung einer Priorität erfordert, dass das Hauptprogramm unterbrochen wird. Soweit würde ich das auch tun, in dem ich das Hauptprogramm in kleine Abschnitte unterteile, zwischen denen jeweils das Flag geprüft wird. Aber was macht und soll die Sekundärroutine? ------ Mir fällt dabei ohnehin noch ein Aspekt auf. Der TO sieht ein gewisses Telegramm, bei dem, mittendrinn, eine Teilinformation sofort behandelt werden muss. Konzeptionell aber ist das gleichwertig zu zwei Telegrammen. Eines bis zu der Sonderinformation. Und das nachfolgende um das ehemal monolithische Telegramm zu komplettieren. Gibt es einen Grund warum das nicht so betrachtet wird. Dann würde jedenfalls die Komplikation entfallen, einen Sonderfall zu haben.
Ein wenig hängt das alles davon ab, wie streng eigentlich die "sofortige" Reaktion aufzufassen ist. Es ist schon etwas Besonderes, das vor Beendigung des Telegramms mit einer Antwort reagiert werden soll. Welche Baudrate eigentlich? Wenn das wirklich wortwörtlich erfüllt werden muss, dann bleiben eigentlich nur zwei Varianten. Schnellerer Prozessor oder eben wirklich die Behandlung im RX-Interrupt. Der zweite Fall ist eher zu vermeiden - dabei bleibe ich - aber gut, wenn es denn nicht anders geht, macht man das halt so, und dazu können wir sicher hier auch Tips geben. Das ist nur eben so selten, dass man dafür eine Bestätigung haben möchte, ehe man sich damit wirklich beschäftigt. Mir ist ein 30 Jahren sowas nicht untergekommen; aber das kann einfach Zufall sein. Na, ja. Ist ja ohnehin alles nur theoretisch und der TO geht auch auf meine Antworten nicht ein. Da kann ich wohl nichts weiter beitragen und ziehe mich aus dem Thread zurück.
>Konzeptionell aber ist das >gleichwertig zu zwei Telegrammen. Eines bis zu der Sonderinformation. >Und das nachfolgende um das ehemal monolithische Telegramm zu >komplettieren. Sehe ich ähnlich. Man müsste ja auch für das 1. Telegramm eine Checksumme haben.
Carsten R. schrieb: > Sind denn die minimale Telegrammlänge und die Auswertefunktion schon > festgelegt oder soll das auch noch flexibel sein? minimal habe ich 3Byte zeit und die auswertfunktion ist fix in ihrer funktion aber fariabel in der benötigten zeit (der angenommene worst case ist der begrenzende faktor hinsichtlich protokoll) Bitflüsterer schrieb: > Aber im negativen Fall verpasst Du > einen Interrupt. nein da ich die auswertfunktion ja in ihrer dauer auf ein max. begrenze damit ich eben keinen interrupt verpasse... Bitflüsterer schrieb: > Darauf musst Du sowieso achten. Nur das eben, wie oben beschrieben, > Deine Grenzen bei der Direkt-Verarbeitung prinzipiell enger sind, als > bei der Flag-Methode. das stimmt, nur bei der ISR auswertung muss ICH in der ISR drauf achten und bei der Flag methode der anwender in der hauptschleife. Das zerhacken der Hauptschleife ist natürlich eine möglichkeit aber das verkompliziert die ganze sache schon ungemein und erschwert die restliche programmierung.... Bitflüsterer schrieb: > Gibt es einen Grund warum das nicht so betrachtet wird. Dann würde > jedenfalls die Komplikation entfallen, einen Sonderfall zu haben. Das ist eigentlich kein Problem da ich bereits im ersten byte sehe obs soweit kommt oder nicht, btw. sind 99% aller telegramme so zu behandeln... Carsten R. schrieb: > Als Alternative bliebe noch ein Echtzeit OS, > welches garantiert, daß das Flag in einer vorgegebenen Zeit abgeholt > wird, sofern ein solches OS in Frage kommt. habe ich weiter oben schon mal geschrieben das eine lösung ohne OS erstrebenswert wäre, jedoch könnte mans damit schön erschlagen das stimmt... Tut mir lei Bitflüsterer das ich auf deine obigen Fragen nicht eingegangen bin aber ich habs erst jetzt gelesen, hat sich leider überschnitten und dein letzter Post beinahe auch :) Bitflüsterer schrieb: > Ein wenig hängt das alles davon ab, wie streng eigentlich die > "sofortige" Reaktion aufzufassen ist. Sofort heißt im worst case vom auftreten der Information bis 3Byte später bei einer Baudrate von 19200 Bitflüsterer schrieb: > Schnellerer Prozessor oder eben wirklich > die Behandlung im RX-Interrupt. wie hilft hier ein schneller prozessor wenn ich nicht in der ISR bin? da kann ich dir nicht ganz folgen? Bitflüsterer schrieb: > Das ist nur eben so selten, dass man dafür eine Bestätigung haben > möchte, ehe man sich damit wirklich beschäftigt. Mir ist ein 30 Jahren > sowas nicht untergekommen; aber das kann einfach Zufall sein. Mir wärs auch lieber anders aber das ist leider ein faktor den ich nicht ändern kann :) MCUA schrieb: > Sehe ich ähnlich. Man müsste ja auch für das 1. Telegramm eine > Checksumme haben. wie genau hilft hier eine Checksumme?
Daten kommen rein, ISR schribt in Fifo. Nach dem der header vollständig empfangen wurde, Info ans Hauptprogramm. Das verarbeitet die Headerinfo und sendet die Antwort. Zwischenzeitlich läuft der Empfang des Telegramms weiter, und wenn das vollständig ist, geht dessen Verarbeitung los. Ob die Auswertungen des headers im Hauptprogramm oder in einer unterbrechbaren ISR oder in einer ununterbrechbaren ISR oder mit Stackmanipulation oder sonstwie gemacht wird, am der benötigten Zeit zum Empfangen des headers, dessen Auswertung, und dem Senden der Antwort ändert sich gar nichts (bis vielleicht auf ein paar Prozessorzyklen durch einen Funktionaufruf mehr oder weniger) Es braucht die Zeit, die es eben dafür braucht. Der Empfang des Telegramms darf während dessn auch nicht ausgesetzt werden, weil sonst Zeichen verloren gehen. Eine ununterbrechbare ISR, die zumindest die paar % Rechenleistung einsparen würde, die zum Schreiben der Empfangsdaten in den SoftwareFifo benötigt wird, ist daher nur dann eine Lösung, wen der verwendete Prozessor einen riesigen Hardware-Empfangspuffer für die UART hat. Der o.a. AVR hat das nicht. Passt das Timimng nicht zur Aufgabestellung, ist entweder der Prozessor zu langsam, oder die Aufgabestellung falsch. In diesem speziellen Fall vermute ich letzteres. Oliver
Bitflüsterer schrieb: >> Das Hauptprogramm muß sehr spezielle Anforderungen >> diesbezüglich erfüllen > Ich will das nicht verneinen, sehe aber, abgesehen von der Zeitforderung > keine eigentlich speziellen Anforderungen. Habe ich da was übersehen? Nein, ich meine genau den von dir beschriebenen Aufbau. Das Programm muß alle x Takte, abhängig von der Baudrate und minimalen Messagelänge, das Flag pollen. So eine library kann ich nicht in jede Software importieren, zumindest wenn es zuverlässig funktioneren soll. Zusätzlich dürfen keine größeren nicht unterbrechbaren Blöcke im Programm sein. Das gilt aber ohnehin für Software die Interruptfähig sein soll. Gleichzeitig muß aber auch sichergestellt sein, daß andere Interrupts die Ausführung dr Auswertung und Antwort nicht über die Deadline hinaus verzögern. Unter Umständen müssen also alle anderen Interrupts, abgesehen vom UART-Empfang, (vorrübergehend) maskiert oder deaktiviert werden Ein Echtzeit-OS garantiert nur in einer Festgelegten Zeit zu reagieren, kann aber nicht die Beendigung in einer Festgelegten Zeit garantieren. Das wäre eine sehr spezielle Software. Bitflüsterer schrieb: > Was meinst Du mit "dies"? Die zuvor genannte Abholung des Flags. Bitflüsterer schrieb: > Ich kannt Dir nicht folgen. Wenn ich Dich recht verstehe, dann meinst > Du, dass die Einführung einer Priorität erfordert, dass das > Hauptprogramm unterbrochen wird. Soweit würde ich das auch tun, in dem > ich das Hauptprogramm in kleine Abschnitte unterteile, zwischen denen > jeweils das Flag geprüft wird. Aber was macht und soll die > Sekundärroutine? Nicht ganz. Die Unterbrechung ist auf jeden Fall erforderlich. Ich nannte dazu zwei Wege. Entweder das Hauptptrogramm weist die oben genannten speziellen Eigenschaften auf unterbricht sich selbst regelmäßig und pollt zusätzlich das Flag. Mir mißfällt es aber eine library zu nutzen die nur dann zuverlässig funktioniert wenn ich sie immer schnell und rechtzeitig polle. Oder das Main-Programm wird vorübergehend aktiv bei Telegrammbeginn unterbrochen und von der Sekundärroutine vorrübergehend bis Auswertungsende/Antwort verdrängt. Ich nenne sie Sekundärroutine, weil sie nicht primär vom Programmierer aktiv aufgerufen wird, sondern automatisch von der library gestartet wird. Dies könnte durch die byte-recieve-ISR initiert werden. Ist aber auch etwas hampelig, weil man dann einen doppelten Programmwechsel hat (ISR+Sekundärroutine), aber machbar. Dafür entfallen dann aber viele Bedingungen an das Hauptprogramm in das die library eingebunden werden soll. Allerdings müßte die Sekundärroutine immer noch unter umständen konkurrierende Interrupts vorrübergehend maskieren (siehe oben, da das Problem noch nicht gelöst ist). Das ist aber für eine Library nicht schön, da dies Seiteneffekte auf das Mainprogramm haben kann, sehr wahrscheinlich sogar. Von allen genannten Softwarelösungen scheint mir dies noch die Praktikabelste zu sein. Es ist machbar, muß aber sehr sauber programmiert werden, weil sonst z.B. Fehler durch race conditions auftreten, welche sehr schwer zu lokalisieren sind und deren sporadische nicht nachvollziehbare Fehler oft auch als Hardwarefehler/Instabilitäten Fehlinterpretiert werden.
:
Bearbeitet durch User
Franz schrieb: Merkwürdig. Nach Deinem letzten Post verstehe ich noch weniger als vorher. > Carsten R. schrieb: >> Sind denn die minimale Telegrammlänge und die Auswertefunktion schon >> festgelegt oder soll das auch noch flexibel sein? > > minimal habe ich 3Byte zeit und die auswertfunktion ist fix in ihrer > funktion aber fariabel in der benötigten zeit (der angenommene worst > case ist der begrenzende faktor hinsichtlich protokoll) Äh... Moment. Ist das Protokoll vorgegeben oder definierst Du das selbst? Warum ist die Laufzeit der Auswertungsfunktion variabel? Eine Abhängigkeit vom übergeben Datum ist ja normal, aber sonst? Siehe unten? > Bitflüsterer schrieb: >> Aber im negativen Fall verpasst Du >> einen Interrupt. > > nein da ich die auswertfunktion ja in ihrer dauer auf ein max. begrenze > damit ich eben keinen interrupt verpasse... Wie soll das gehen? Angenommen, der Programmcode der Funktion und die Taktfrequenz ist konstant, wie soll da die Laufzeit verändert werden? > Bitflüsterer schrieb: >> Darauf musst Du sowieso achten. Nur das eben, wie oben beschrieben, >> Deine Grenzen bei der Direkt-Verarbeitung prinzipiell enger sind, als >> bei der Flag-Methode. > > das stimmt, nur bei der ISR auswertung muss ICH in der ISR drauf achten > und bei der Flag methode der anwender in der hauptschleife. Oh. Moment mal. Was für ein Anwender? Davon hast Du nichts geschrieben! Wieso hat der Anwender die Möglichkeit die Hauptschleife zu beeinflussen? > Das zerhacken der Hauptschleife ist natürlich eine möglichkeit aber das > verkompliziert die ganze sache schon ungemein und erschwert die > restliche programmierung.... Uups. Wieso das denn? Seltsam. Ich halte das für ziemlich simpel. > Bitflüsterer schrieb: >> Gibt es einen Grund warum das nicht so betrachtet wird. Dann würde >> jedenfalls die Komplikation entfallen, einen Sonderfall zu haben. > > Das ist eigentlich kein Problem da ich bereits im ersten byte sehe obs > soweit kommt oder nicht, btw. sind 99% aller telegramme so zu > behandeln... Ah. Noch eine Salamischeibe... > Carsten R. schrieb: >> Als Alternative bliebe noch ein Echtzeit OS, >> welches garantiert, daß das Flag in einer vorgegebenen Zeit abgeholt >> wird, sofern ein solches OS in Frage kommt. > > habe ich weiter oben schon mal geschrieben das eine lösung ohne OS > erstrebenswert wäre, jedoch könnte mans damit schön erschlagen das > stimmt... > > Tut mir lei Bitflüsterer das ich auf deine obigen Fragen nicht > eingegangen bin aber ich habs erst jetzt gelesen, hat sich leider > überschnitten und dein letzter Post beinahe auch :) > > Bitflüsterer schrieb: >> Ein wenig hängt das alles davon ab, wie streng eigentlich die >> "sofortige" Reaktion aufzufassen ist. > Sofort heißt im worst case vom auftreten der Information bis 3Byte > später bei einer Baudrate von 19200 Also "Fernseh-Sofort". Meine Güte. Da hast Du ja massig Zeit. > Bitflüsterer schrieb: >> Schnellerer Prozessor oder eben wirklich >> die Behandlung im RX-Interrupt. > wie hilft hier ein schneller prozessor wenn ich nicht in der ISR bin? da > kann ich dir nicht ganz folgen? > > Bitflüsterer schrieb: >> Das ist nur eben so selten, dass man dafür eine Bestätigung haben >> möchte, ehe man sich damit wirklich beschäftigt. Mir ist ein 30 Jahren >> sowas nicht untergekommen; aber das kann einfach Zufall sein. > > Mir wärs auch lieber anders aber das ist leider ein faktor den ich nicht > ändern kann :) Darum geht es nicht sondern darum ob "sofort" wirklich sofort heisst oder eben, wie wir erfahren haben "Ewigkeiten" später. Bei 8MHz hast Du 12500! Befehle Zeit. In der Zeit dekodiert Dir Karl Heinz ein Video. Lach.
Hi >Passt das Timimng nicht zur Aufgabestellung, ist entweder der Prozessor >zu langsam, oder die Aufgabestellung falsch. In diesem speziellen Fall >vermute ich letzteres. Kann es sein, des der Controller hier total unterschätzt wird? Bei z.B. 11.059MHz und 19200Bd dauert ein Byte ca. 5600 Prozessortakte. Zumindest in Assembler ist das ein halber Roman an Quelltext. MfG spess
Franz schrieb: > Bitflüsterer schrieb: >> Schnellerer Prozessor oder eben wirklich >> die Behandlung im RX-Interrupt. > wie hilft hier ein schneller prozessor wenn ich nicht in der ISR bin? da > kann ich dir nicht ganz folgen? Beispielsweise wenn die CPU schnell genug wäre um in der Byte-Recieve-ISR beim ersten Byte auch gleich die Auswertung und Antwort erledigen zu können. Dann wäre das Ding im ersten Lauf mit einer if-Verzweigung bei Byte 1 erledigt. Mit Assembler und ausreichend hohem CPU-Takt wäre das vielleicht möglich von dem Datenverlust durch Übrlauf des kleinen Harwarepuffers. Dann wäre der Mindesttakt aber Vorraussetzng für die Nutzung der library. Die Grenze hast Du aber ohnehin schon, nur liegt sie aktuell niedriger als bei der großen ISR. Das hängt natürlich von der Auswertungsfunktion selbst ab und wieviele andere Interrupts da noch in Konkurrenz stehen könnten.
Carsten R. schrieb: > So eine library kann ich nicht in jede Software > importieren, ... Häh? Wieso Du? Hat jetzt Frank das Problem ist bist Du seine Reinkarnation? Ich glaube, wir werden hier gerade von einem Troll veralbert.
Bitflüsterer schrieb: >> Bitflüsterer schrieb: >>> Darauf musst Du sowieso achten. Nur das eben, wie oben beschrieben, >>> Deine Grenzen bei der Direkt-Verarbeitung prinzipiell enger sind, als >>> bei der Flag-Methode. >> >> das stimmt, nur bei der ISR auswertung muss ICH in der ISR drauf achten >> und bei der Flag methode der anwender in der hauptschleife. > > Oh. Moment mal. Was für ein Anwender? Davon hast Du nichts geschrieben! > Wieso hat der Anwender die Möglichkeit die Hauptschleife zu > beeinflussen? Er wid wohl den Programmierer und Nutzer der Lirary meinen und nicht den Anwender des fertigen Gerätes.
Bitflüsterer schrieb: > Carsten R. schrieb: > >> So eine library kann ich nicht in jede Software >> importieren, ... > > Häh? Wieso Du? Hat jetzt Frank das Problem ist bist Du seine > Reinkarnation? > > Ich glaube, wir werden hier gerade von einem Troll veralbert. NEIN! Wir sind definitiv verschiedene Leute, oder ich weiß nichts von meiner multiplen Persönlichkeit. :D Ich hätte auch schreiben können: kann man. Wobei... natürlich kann man, aber ich würde es nicht tun wollen und ich glaube nicht, daß ICH so eine library sinnvoll fehlerfrei nutzen könnte. Ich laufe dann Amok mit solchen Race-Condidions die dann irgendwann auftauchen. Ich kann es aber nicht ausschließen daß andere das hinbekommen. ;-)
Franz schrieb: > Problem: > Innerhalb der ersten paar bytes kommt eine Information die ausgewertet > werden muss und bevor das letzte byte des telegramms empfangen wurde > muss bereits eine antwort etsprechend der auswertung gesendet werden. Das Problem ist also, beim echten Namen genannt: beschissenes, nicht durchdachtes Protokoll verwendet. > Einfache Lösung: > hardware uart empfangspuffer ausnützen um zeit für die ISR zu gewinnen > und in der ISR die Auswertung machen und entsprechend antworten Schlecht, du schreibst doch selber, daß die Auswertung eine unbestimmte Zeit dauern kann und sowas gehört nicht in eine ISR, zumindest nicht in den exklusiven Teil. > theoretische gedanken dazu: > ISR darf nicht ins unterbrochene programm zurückspringen sondern an die > stelle der auswertfunktion welche selbst wieder von der ISR unterbrochen > werden darf, wenn auswertfunktion fertig spring zurück ins ursprüngliche > programm. Ist sowas mit zb. einem avr denkbar? Ja klar. Man kann jede ISR in zwei Teile zerlegen, einen, der exklusiv abgearbeitet wird und einen, der unterbrechbar ist. Das Problem ist nur: Dieses Vorgehen birgt die Gefahr des Supergau (Stack->Heap) in sich. Man muß deshalb bei unkalkulierbarer Laufzeit Vorkehrungen treffen, um genau dies zu vermeiden. Am besten wäre, die Laufzeit kalkulierbar zu machen. Wenn Z.B. sichergestellt ist, daß die Generierung der "vorläufigen Antwort" _mit Sicherheit_ spätestens dann abgeschlossen ist, wenn die Frage vollständig eingetroffen ist, dann ist der Knoten bereits aufgelöst. Und die Anwendung des Prinzips besteht einfach in einem sei() in der ISR, welches den exklusiven Teil (Datenregister->Puffer und Verwaltung des Puffers) vom Rest (Generierung der vorläufigen Antwort) trennt. Beachte aber: während der nichtexlusive Teil der ISR läuft, kann dieser zwar durch Interrupts unterbrochen werden, aber main() steht weiterhin vollständig still, solange die ISR läuft. Das kann Probleme bei anderen Sachen hervorrufen, bei allen, die vollständig oder teilweise in main() laufen und darauf angewiesen sind, wenigstens halbwegs regelmäßig abgearbeitet zu werden. Deswegen ist es eine ziemlich schlechte Idee, die beiden Ansätze Polling in main() (ggf. mit kurzen ISRs) und interruptorientierte Programmierung mit unterbrechbaren ISRs zu kreuzen. Manchmal geht's nicht anders, aber in der Regel versucht man, entweder konsequent den einen oder konsequent den anderen Ansatz durchzuziehen, weil sonst über kurz oder lang kaum noch beherrschbare Timingprobleme die Folge sind.
Ich bin auch raus. Erstes Byte kommt an, dann Interrupt. Antwort soll raus sein vor Ende der Message? Im Register oder raus auf den Bus? Für Letzteres muß ich es schon ein Byte früher in den UART stecken. Bei nur 3 Byte habe ich also nur ein Byte Zeit für die Auswertung. Wieviele Takte das sind, hängt vom Haupttakt ab. So oder so muß es im Worst-Case zwischen zwei Interrupts passen. Damit kann man es auch gleich in die ISR packen, da es sofort erledigt werden muß. Entweder es paßt da rein oder es paßt da nicht rein. So oder so sind alle überlegungen fürn A... Da die Informationen mal wiedr Scheibchenweise kamen. Hau es mit Assembler komplett in die ISR. Wenn es dann nicht paßt ist es einfach nicht möglich rechtzeitig zu antworten, egal wie Du es aufteilst.
:
Bearbeitet durch User
Bitflüsterer schrieb: > Ich glaube, wir werden hier gerade von einem Troll veralbert. nein Carsten hat nur das problem genau erkannt, wohingegen wir: Bitflüsterer schrieb: > Merkwürdig. Nach Deinem letzten Post verstehe ich noch weniger als > vorher. anscheinend nicht zusammen finden :) Bitflüsterer schrieb: > Ist das Protokoll vorgegeben oder definierst Du das selbst? Warum ist die Laufzeit der Auswertungsfunktion variabel? Protokoll ist vorgegeben....weil sie je nach konfiguration (die während der Laufzeit geschiet) unterschiedlich viel prüfen muss!? Bitflüsterer schrieb: >> nein da ich die auswertfunktion ja in ihrer dauer auf ein max. begrenze >> damit ich eben keinen interrupt verpasse... > Wie soll das gehen? Angenommen, der Programmcode der Funktion und die > Taktfrequenz ist konstant, wie soll da die Laufzeit verändert werden? vielleicht falsch ausgedrückt, ich begrenze nicht die auswertfunktion an sich sondern die anzahl der prüfungen die sie durchführt (was mir gleichzeitig die protokolleinschränkungen beschert) Bitflüsterer schrieb: > Was für ein Anwender? Davon hast Du nichts geschrieben! > Wieso hat der Anwender die Möglichkeit die Hauptschleife zu > beeinflussen? Andere Entwickler, hab ich weiter oben mal erwähnt, hat Carsten auch verstanden weshalb er zurecht von einer libary spricht, das ist genau der punkt... Bitflüsterer schrieb: > Bei 8MHz hast Du 12500! Befehle Zeit. In der Zeit dekodiert Dir Karl > Heinz ein Video. Lach. Zeit ist relativ, nicht alles hat die komplexität eines lauflichts und wie Carsten richtig erkannt hat ist es für eine libary essentiell nicht größere ununterbrechbare brocken zu haben und so wenig anforderungen wie möglich an den anwender zu stellen.... Carsten R. schrieb: > Oder das Main-Programm wird vorübergehend aktiv bei Telegrammbeginn > unterbrochen und von der Sekundärroutine vorrübergehend bis > Auswertungsende/Antwort verdrängt. Ich nenne sie Sekundärroutine, weil > sie nicht primär vom Programmierer aktiv aufgerufen wird, sondern > automatisch von der library gestartet wird. Dies könnte durch die > byte-recieve-ISR initiert werden. Ist aber auch etwas hampelig, weil man > dann einen doppelten Programmwechsel hat (ISR+Sekundärroutine), aber > machbar. Dafür entfallen dann aber viele Bedingungen an das > Hauptprogramm in das die library eingebunden werden soll. genau sowas war mein gendanke im ersten post.... Carsten R. schrieb: > Beispielsweise wenn die CPU schnell genug wäre um in der > Byte-Recieve-ISR beim ersten Byte auch gleich die Auswertung und Antwort > erledigen zu können. So hätte ichs auch verstanden Bitflüsterer schreibt aber ODER Rx Interrupt, somit meint er wohl was anderes? spess53 schrieb: > Kann es sein, des der Controller hier total unterschätzt wird? es ist ja kein unlösbares Problem (läuft ja schon), ich hab ja nur nach optimierungsmöglichkeiten gefragt, man lernt ja schließlich nie aus :) c-hater schrieb: > Am besten wäre, die Laufzeit kalkulierbar zu machen. Wenn Z.B. > sichergestellt ist, daß die Generierung der "vorläufigen Antwort" _mit > Sicherheit_ spätestens dann abgeschlossen ist, wenn die Frage > vollständig eingetroffen ist, dann ist der Knoten bereits aufgelöst. das ist machbar, mach ich ja jetzt bereits, die laufzeit ist zwar variabel aber der worst case wird so begrenzt das er reinpasst... c-hater schrieb: > Man kann jede ISR in zwei Teile zerlegen, einen, der exklusiv > abgearbeitet wird und einen, der unterbrechbar ist. schau ich mir mal genauer an, danke
Franz schrieb: > Carsten R. schrieb: >> Beispielsweise wenn die CPU schnell genug wäre um in der >> Byte-Recieve-ISR beim ersten Byte auch gleich die Auswertung und Antwort >> erledigen zu können. > > So hätte ichs auch verstanden Bitflüsterer schreibt aber ODER Rx > Interrupt, somit meint er wohl was anderes? Ich meine genau den. Ich habe das Ding nur der Funktion nach benannt und nicht abgekürzt. Es soll ja etwas hardewareunabhängig sein und wer weiß welche Abkürzungen in zukünftig unterstützten Chips an den entsprechenden Interruptflags stehen.
Franz schrieb: > Innerhalb der ersten paar bytes kommt eine Information die ausgewertet > werden muss und bevor das letzte byte des telegramms empfangen wurde > muss bereits eine antwort etsprechend der auswertung gesendet werden. Klingt sehr merkwürdig, wer denkt sich denn solche verrückten Protokolle aus. Das Senden geht aber auch nicht sofort, sondern braucht je nach Baudrate und Byteanzahl seine Zeit. Muß der MC das Senden vor dem letzten Empfangsbyte begonnen oder schon abgeschlossen haben? Franz schrieb: > Frage: > gibts eine elegantere Lösung die ohne hardware rx puffer auskommt? Wieso? Hat Dein komischer MC einen RX-Puffer, den man abschalten kann und für was anderes benutzen? Ich mache im UART-Interrupt immer nur eine FIFO, die mindestens 2 Pakete speichern kann. Dann kann man eins in aller Ruhe parsen und das nächste geht nicht verloren. Und der TX-Interrupt sollte auch eine FIFO haben, die mindestens eine Antwort aufnehmen kann, um das unnütze Warten zu vermeiden.
Franz schrieb: > c-hater schrieb: >> Man kann jede ISR in zwei Teile zerlegen, einen, der exklusiv >> abgearbeitet wird und einen, der unterbrechbar ist. > schau ich mir mal genauer an, danke Gleiches hatte ich Dir schon weiter oben empfohlen und als unproblematisch bezeichnet. Beim Durchlesen anderer Beiträge hier fällt auf, wieviel Angst bei der Verwendung von Interrupts im Spiel ist. Den Code in Assembler, LIBs oder main() zu verlagern, bringt doch keinen Vorteil. Und dass während der Interruptausführung main() warten muß, ist doch klare Kloßbrühe. Wenn dann irgendwo 19200Baud genannt werden, ist doch eher Langeweile im µC vorprogrammiert.
lange Rede kurzer Sinn, Sobald man (Anfangs)Bytes auswerten will, muss man es schon bis da hin auch als (eigenes) Protokoll betrachten. (also sollte es auch schon bis dahin überlegt sein)
Franz schrieb: > ISR darf nicht ins unterbrochene programm zurückspringen sondern an die > stelle der auswertfunktion welche selbst wieder von der ISR unterbrochen > werden darf, wenn auswertfunktion fertig spring zurück ins ursprüngliche > programm. Ist sowas mit zb. einem avr denkbar? Wenn ja wie realisiert > man das praktisch, wenn nein gibts andere methoden? Wenn man weiss, was man tut, ganz einfach sei(). Danach ist die ISR für den Empfang weiterer Daten unterbrechbar, die Auswertung kann aber stattfinden und die Antwort gesendet werden und am Ende führt der reti wieder ist Hauptprogramm. Wie auch schon von anderen empfohlen. Man muss nur ein wenig aufpassen, dass a) der Stack ausreicht (muss man aber sowieso) und b) die Auswertungen sich nicht "überholen". Im Grunde ist das ein verschachtelter Interrupt bzw. ein Interrupt, dessen Priorität verringert wird. LG, Sebastian
:
Bearbeitet durch User
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.