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.
> 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.
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.
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?
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
intState=1;
3
while(1){
4
5
if(Flag=1){Sonderbehandlung();Flag=0;}
6
7
switch(State){
8
case1:LangerVorgang1();State=2;break;
9
case2:LangerVorgang2();State=3;break;
10
case3: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.
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.
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