Forum: Mikrocontroller und Digitale Elektronik Verständnis AVR Interrupts


von Rainer V. (a_zip)


Lesenswert?

Hallo, habe jetzt doch Bedarf an einem Interrupt-gesteuerten System 
(basteln) und habe verstanden, dass der/die AVR immer nur einen 
Interrupt abarbeiten. Wenn während einer laufenden Interrupt-Routine 
weitere Interrupts auftreten, dann werden die aber nicht verworfen, 
sondern offensichtlich gespeichert. Und nun verstehe ich die Doc's (auch 
hier im ".net") nicht. Ist es so, dass gleich nach dem RETI der ersten 
Unterbrechung der nächste Interrupt ausgelöst wird? Oder muß ich da noch 
was verwalten?? Und weitere Frage, macht es einen Unterschied, ob der 
nächste Interrupt ein Externer oder ein Interner ist? Würde mich über 
eine erhellende Antwort freuen.
Danke und Gruß, Rainer
PS: dabei kommt mir noch die Frage, wieviele Interrupts die AVR denn 
überhaupt schachteln können...

: Gesperrt durch Moderator
von Falk B. (falk)


Lesenswert?

Rainer V. schrieb:
> Hallo, habe jetzt doch Bedarf an einem Interrupt-gesteuerten System
> (basteln) und habe verstanden, dass der/die AVR immer nur einen
> Interrupt abarbeiten.

Das machen andere Prozessoren eben so, denn sie haben nur eine CPU. Was 
du meinst ist die Unterbrechung von Interrupts durch höher priorisierte 
Interrupts. Das kann der AVR von hause aus nicht.

> Wenn während einer laufenden Interrupt-Routine
> weitere Interrupts auftreten, dann werden die aber nicht verworfen,
> sondern offensichtlich gespeichert.

Ja. Aber nur 1 von jeder Sorte. Kommen in der zeit mehr, geht einer 
verloren, siehe Interrupt.

> Und nun verstehe ich die Doc's (auch
> hier im ".net") nicht. Ist es so, dass gleich nach dem RETI der ersten
> Unterbrechung der nächste Interrupt ausgelöst wird?

Ja.

> Oder muß ich da noch
> was verwalten??

Nö. Die CPU bearbeitet maximal 1 ASM-Befehl.

> Und weitere Frage, macht es einen Unterschied, ob der
> nächste Interrupt ein Externer oder ein Interner ist?

Nö.

> PS: dabei kommt mir noch die Frage, wieviele Interrupts die AVR denn
> überhaupt schachteln können...

Vnn Haus aus gar keinen. Per Software soviel wie du willst (oder der 
Stack überläuft)

von Rolf M. (rmagnus)


Lesenswert?

Rainer V. schrieb:
> Hallo, habe jetzt doch Bedarf an einem Interrupt-gesteuerten System
> (basteln) und habe verstanden, dass der/die AVR immer nur einen
> Interrupt abarbeiten.

Nicht unbedingt. Man kann in einer ISR auch Interrupts wieder 
einschalten, dann kann sie durch andere ISRs unterbrochen werden. Man 
sollte sich nur sehr gut überlegen, ob man das wirklich braucht.

> Wenn während einer laufenden Interrupt-Routine weitere Interrupts auftreten,
> dann werden die aber nicht verworfen, sondern offensichtlich gespeichert.

So ähnlich. Ein Auftreten der Interrupt-Bedingung setzt das dazugehörige 
Interrupt-Flag. Sonst passiert in dem Moment erstmal nichts.

> Und nun verstehe ich die Doc's (auch hier im ".net") nicht. Ist es so, dass
> gleich nach dem RETI der ersten Unterbrechung der nächste Interrupt
> ausgelöst wird? Oder muß ich da noch was verwalten??

Nach jeder Instruktion prüft der AVR die Flags. Wenn für einen 
bestimmten Interrupt sowohl dessen Interrupt-Flag, als auch sein 
Interrupt-Enable-Flag und das globale Interrupt-Enable gesetzt ist, wird 
der Eintrag in der Interrupt-Vektor-Tabelle angesprungen. Wenn zu diesem 
Zeitpunkt mehrere Interrupts gleichzeitig anstehen, wir der Eintrag mit 
der niedrigsten Adresse genommen.
Da beim Einsprung in eine ISR das globale Interrupt-Enable automatisch 
gelöscht wird, kann sie per Default nicht durch einen anderen Interrupt 
unterbrochen werden. Wenn aber ein anderer Interrupt auftritt, wird 
dessen Interrupt-Flag gesetzt, und sobald aus der gerade laufenden ISR 
rausgesprungen wird, wird auch das globale Interrupt-Flag gesetzt, und 
es wird dann der Interrupt-Vektor des neuen Interrupts angesprungen.

> Und weitere Frage, macht es einen Unterschied, ob der nächste Interrupt ein
> Externer oder ein Interner ist? Würde mich über eine erhellende Antwort freuen.

Was verstehst du darunter? Interrupt ist Interrupt, egal ob der von 
einem Interrupt-Pin, einem Timer oder einem UART ausgelöst wird.

> Danke und Gruß, Rainer PS: dabei kommt mir noch die Frage, wieviele
> Interrupts die AVR denn überhaupt schachteln können...

Bis der Stack ausgeht.

: Bearbeitet durch User
von Pandur S. (jetztnicht)


Lesenswert?

Eine Interruptroutine sollte so kurz wie moeglich sein. also keine 
Float-exponentiation, keine UART Interaktion, sondern oft nur ein 
Register lesen, setzen und  ein Flag setzen.

von Falk B. (falk)


Lesenswert?

Pandur S. schrieb:
> Eine Interruptroutine sollte so kurz wie moeglich sein. also keine
> Float-exponentiation, keine UART Interaktion,

Soso, gilt das auch für die UART-Interrupts? ;-)

> sondern oft nur ein
> Register lesen, setzen und  ein Flag setzen.

Quark. Man kann schon ne ganze Menge mehr in einem Interrupt machen, 
wenn man weiß was man tut. Wenn ein Timer-Interrupt nur alle 10ms 
auftritt darf man in diesem auch mal 5ms was machen, WENN nicht andere, 
wichtige Interrupts auch noch aktiv sind!

von Carsten (Gast)


Lesenswert?

Hallo,
ich finde auf der Seite
http://weigu.lu/tutorials/avr_assembler/index.html
- Modul B - sind die Interrupts ganz gut beschrieben.
Sonst helfen die jeweiligen Datenblätter weiter
Gruß Carsten

von Rainer V. (a_zip)


Lesenswert?

Rolf M. schrieb:
> Da beim Einsprung in eine ISR das globale Interrupt-Enable automatisch
> gelöscht wird, kann sie per Default nicht durch einen anderen Interrupt
> unterbrochen werden. Wenn aber ein anderer Interrupt auftritt, wird
> dessen Interrupt-Flag gesetzt, und sobald aus der gerade laufenden ISR
> rausgesprungen wird, wird auch das globale Interrupt-Flag gesetzt, und
> es wird dann der Interrupt-Vektor des neuen Interrupts angesprungen.

Danke für die Antworten. Ich habe diese hier zitiert, weil sich mir dann 
die Frage stellt, wenn ich direkt in meiner I-Routine das globale 
Interrupt-Flag wieder setzte...geht das? Oder stürzt das ab? Und wenn 
ich es machen könnte, was passiert dann?! Sorry, aber ich versuche ein 
Gefühl für Interrupts zu bekommen...ja klar, könnte auch einfach mal 
machen...aber es sollten doch einige Fundamentals bei mir klar sein.
Danke und GRuß Rainer

von Cyblord -. (cyblord)


Lesenswert?

Rainer V. schrieb:
> Danke für die Antworten. Ich habe diese hier zitiert, weil sich mir dann
> die Frage stellt, wenn ich direkt in meiner I-Routine das globale
> Interrupt-Flag wieder setzte...geht das?

Es geht. Damit kannst du verschachtelte Interrupts erlauben.

> Oder stürzt das ab? Und wenn
> ich es machen könnte, was passiert dann?!

Es passiert nichts, solange nicht so viele Interrupts verschachtelt 
aufgerufen werden bis der Stack voll ist.

D.h. man kann es machen, aber man sollte wissen was man tut

von Rainer V. (a_zip)


Lesenswert?

Cyblord -. schrieb:
> Es geht. Damit kannst du verschachtelte Interrupts erlauben.

Danke...also nur für mein Verständnis...es kommt ein Int und die CPU 
rettet die nächste Adresse (aus der Hauptroutine) auf den Stack und 
springt in die Int-Routine. Wenn ich dort sofort wieder Interrupt 
erlaube und der kommt, dann landet die nächste Adresse (aus der 
Int-Routine) auf dem Stack und die neue Int-Routine wird abgearbeitet. 
Deren RETI führt dann zurück in die vorherige Interrupt-Routine. 
Richtig??? Es ist nicht leicht :-)
Gruß Rainer

von Wolfgang (Gast)


Lesenswert?

Rainer V. schrieb:
> Hallo, habe jetzt doch Bedarf an einem Interrupt-gesteuerten System
> (basteln) und habe verstanden, dass der/die AVR immer nur einen
> Interrupt abarbeiten.

Wie meinst du das?
Je nachdem, wie du es programmiert hast, kann eine laufende 
Interrupt-Routine natürlich auch von einem anderen Interrupt 
unterbrochen werden, so dass die Abarbeitung dazwischen geschoben wird. 
Das kommt immer drauf an, ob Interrupts freigegeben worden sind.

von Cyblord -. (cyblord)


Lesenswert?

Rainer V. schrieb:
> Wenn ich dort sofort wieder Interrupt
> erlaube und der kommt, dann landet die nächste Adresse (aus der
> Int-Routine) auf dem Stack und die neue Int-Routine wird abgearbeitet.
> Deren RETI führt dann zurück in die vorherige Interrupt-Routine.

Ja, genau wie bei verschachtelten Funktionsaufrufen.

von Jacko (Gast)


Lesenswert?

Du musst nix verwalten, aber EIN Befehl im "normalen Ablauf" wird
nach RETI ausgeführt, bevor die nächste "gespeicherte"
Interruptanforderung bedient wird.
- When the AVR exits from an interrupt, it will always return to the
- main program and execute one more instruction before any pending
- interrupt is served.

Externe -, oder interne Interruptanforderung ist "wurscht". Der
entscheidende Unterschied ist, ob er durch ein Ereignis (wenig Probleme)
ausgelöst wird, oder durch einen Zustand (kann Probleme machen).
Die Möglichkeit, den externen INT0, oder INT1 mit Low-Pegel (!) zu
triggern, halte ich für eine dumme Sache, wenn ich keine SICHERE
Möglichkeit habe, vom µC aus wieder auf High-Pegel zu schalten...

Der Rest ist:
Grundregeln für Interrupts beachten und ERFAHRUNGEN SAMMELN!

von Wolfgang (Gast)


Lesenswert?

Jacko schrieb:
> Die Möglichkeit, den externen INT0, oder INT1 mit Low-Pegel (!) zu
> triggern, halte ich für eine dumme Sache, wenn ich keine SICHERE
> Möglichkeit habe, vom µC aus wieder auf High-Pegel zu schalten...

Richtig dumm wird es erst, wenn man in so einem Fall in der 
Interruptroutine die Interrupts wieder frei gibt ...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rainer V. schrieb:
> Wenn während einer laufenden Interrupt-Routine
> weitere Interrupts auftreten, dann werden die aber nicht verworfen,
> sondern offensichtlich gespeichert.

Nur wenn das I-Flag im SREG nicht gesetzt ist, was default ist.  Falls 
in der ISR eine SEI Instruktion ausgeführt wird bzw. SREG entsprechend 
gesetzt wird, kann eine ISR auch unterbrochen werden.  Auch von "sich 
selbst".

> Ist es so, dass gleich nach dem RETI der ersten
> Unterbrechung der nächste Interrupt ausgelöst wird?

Nein, es wird immer zuerst noch eine nicht-ISR Instruktion ausgeführt 
bevor die nächste anstehende IRQ triggert.  Es kommt also zu einer nicht 
maskierbaren Priority Inversion.  In einem sicherheitskritischen OS wäre 
das nicht so toll...  Marssonden sind desalb m.W. aber noch nicht 
abgestürzt.

> Oder muß ich da noch was verwalten??

Nein, die entsprechende IRQ muss aktiviert sein, und IRQs müssen global 
aktiviert sein.

> Und weitere Frage, macht es einen Unterschied, ob der
> nächste Interrupt ein Externer oder ein Interner ist?

Stehen mehrere IRQs gleichzeitig an, wird die mit der höchsten Priorität 
(der kleinsten Vector-Nummer) zuerst ausgelöst.

> PS: dabei kommt mir noch die Frage, wieviele Interrupts die AVR denn
> überhaupt schachteln können...

Bis der Platz auf dem Stack aus ist; bzw. bis der Stack in den anders 
genutzten Speicher bzw. Adressbereich hineinwächst: Heap, Static 
Storage, I/O-Bereich, ...

von Joachim B. (jar)


Lesenswert?

Falk B. schrieb:
> Wenn ein Timer-Interrupt nur alle 10ms
> auftritt darf man in diesem auch mal 5ms was machen

z.b. IRMP abfragen, mache ich seit Jahren so.
ukw hat die IRMP IRQ auch sehr sehr kurz gehalten meine letzte Messung 
ist lange her mit einer alten Version, 1,5µs und die stören im 10ms 
Timer IRQ nicht die Bohne, sogar im TIMER IRQ kann ich i2c lesen aus 
einem PCF8574(a)

von Rolf M. (rmagnus)


Lesenswert?

Rainer V. schrieb:
> Ich habe diese hier zitiert, weil sich mir dann
> die Frage stellt, wenn ich direkt in meiner I-Routine das globale
> Interrupt-Flag wieder setzte...geht das?

Ja.

> Oder stürzt das an?

Nein.

> Und wenn ich es machen könnte, was passiert dann?!

Das, was ich beschrieben habe. Es wird nach jeder Instruktion geprüft, 
ob
irgendein Interrupt-Flag und das dazugehörige Interupt-Enable-Flag (und 
eben das globale) gesetzt ist, und wenn ja, wird der entsprechende 
Interruptvektor angesprungen. Für den Prozessor spielt es da keine 
Rolle, ob du gerade in einer ISR bist oder nicht. Der geht nicht in 
einen speziellen Zustand oder sowas, sondern führt einfach eine 
Instruktion nach der anderen aus, wie sonst auch.

> Sorry, aber ich versuche ein Gefühl für Interrupts zu bekommen...

Ja, und man denkt da oft zu kompliziert. Gerade beim AVR ist es 
eigentlich sehr einfach, aber es muss halt mal "klick" machen.

Falk B. schrieb:
> Pandur S. schrieb:
>> Eine Interruptroutine sollte so kurz wie moeglich sein. also keine
>> Float-exponentiation, keine UART Interaktion,
>
> Soso, gilt das auch für die UART-Interrupts? ;-)

Ich vermute, gemeint ist, dass man keine Debug-Prints per UART aus der 
ISR heraus machen sollte oder irgendwelche Protokolle mit Handshake. 
Halt nix, wo man erst auf den Abschluss einer Übertragung warten muss.

>> sondern oft nur ein
>> Register lesen, setzen und  ein Flag setzen.
>
> Quark. Man kann schon ne ganze Menge mehr in einem Interrupt machen,
> wenn man weiß was man tut.

Es ist aber eher selten nötig, und wenn man es vermeidet, ist man 
bezüglich späterer Erweiterungen in der Regel flexibler.

> Wenn ein Timer-Interrupt nur alle 10ms auftritt darf man in diesem auch
> mal 5ms was machen, WENN nicht andere, wichtige Interrupts auch noch
> aktiv sind!

Und auch das Hauptprogramm mal für 5 ms am Stück unterbrochen werden 
darf.

von Rainer V. (a_zip)


Lesenswert?

Johann L. schrieb:
> Bis der Platz auf dem Stack aus ist; bzw. bis der Stack in den anders
> genutzten Speicher bzw. Adressbereich hineinwächst: Heap, Static
> Storage, I/O-Bereich, ...

OK, habe ich jetzt etwas verstanden. Also eine Interrupt-R kann 
unterbrochen werden, wenn dort sofort das Interrupt-Enable gesetzt wird. 
Ich muß also nachhalten, wann, wo ,welche Routine aktiviert wurde. 
Scheint mir erst mal nicht trivial (und ich hoffe doch stark, dass im 
Weltraum keine AVR's werkeln :-) OK, ich mache mir mal Gedanken, wie man 
das implementieren würde!
Meine konkrete Anwendung besteht aus mehrenen Arduino-Nano, die jeweils 
von mehreren "Unter-Nanos" Daten bekommen. Die Nanos mit den 
"Unter-Nanos dran" spreche ich von "Hauptnanos" an und diese Anfrage 
soll nicht "nachrangig" beantwortet werden. Ich habe also das Problem, 
dass sowohl ein "untergeordneter" Sender einen Nano anspricht, obwohl 
der arbeitet, und auch der Master eine Anfrage gleichzeitig schickt. Ich 
weiß, dass man das durch eine "rigerose Hirarchie" in den Griff bekommen 
kann, aber ich möchte nicht alle möglichen Sender pausenlos ins Nivana 
senden lassen. Vielleicht ist diese Beschreibung auch zu 
unverständlich...ich bitte um Nachsicht...
Gruß Rainer

von Cyblord -. (cyblord)


Lesenswert?

Rainer V. schrieb:
> Meine konkrete Anwendung besteht aus mehrenen Arduino-Nano, die jeweils
> von mehreren "Unter-Nanos" Daten bekommen. Die Nanos mit den
> "Unter-Nanos dran" spreche ich von "Hauptnanos" an und diese Anfrage
> soll nicht "nachrangig" beantwortet werden.

Das ist ein total komplexes System und kein Anfängerprojekt.
In der Realität nimmt man für solche Sachen recht komplexe 
Netzwerkprotokolle oder Feldbusse her.

von Rainer V. (a_zip)


Lesenswert?

Cyblord -. schrieb:
> Das ist ein total komplexes System und kein Anfängerprojekt.
> In der Realität nimmt man für solche Sachen recht komplexe
> Netzwerkprotokolle oder Feldbusse her.

Hallo, ja, das weiß ich, auch weil ich nicht wirklich Anfänger bin 
(trotzdem aber Bastler). Aber vor Int habe ich mich bisher eben 
gedrückt! Bis zu einem bestimmten Punkt gehts auch ohne...und die 
Herausforderung für meinen bescheidenen Rahmen ist für mich ok. Habe 
früher beruflich mit diesen Sachen zu tun gehabt und ehrlich, bis ich 
ein Ethernet, ein Profibus, ein COM-Net und was auch immer, dazu 
bekomme, zusammenzuspielen, zumal ich auf der Controllerseite 
sitze...niemals wäre ein Raumschiff in den Orbiter gekommen...
Gruß Rainer

von Veit D. (devil-elec)


Lesenswert?

Rainer V. schrieb:

> Meine konkrete Anwendung besteht aus mehrenen Arduino-Nano, die jeweils
> von mehreren "Unter-Nanos" Daten bekommen. Die Nanos mit den
> "Unter-Nanos dran" spreche ich von "Hauptnanos" an und diese Anfrage
> soll nicht "nachrangig" beantwortet werden. Ich habe also das Problem,
> dass sowohl ein "untergeordneter" Sender einen Nano anspricht, obwohl
> der arbeitet, und auch der Master eine Anfrage gleichzeitig schickt. Ich
> weiß, dass man das durch eine "rigerose Hirarchie" in den Griff bekommen
> kann, aber ich möchte nicht alle möglichen Sender pausenlos ins Nivana
> senden lassen.

Wenn die Daten erst über 2 Signalwege müssen kann die Anforderung an die 
Reaktionszeit nicht so sehr hoch sein, soll aber dennoch zügig 
stattfinden, denke ich. Ich weiß nicht wie du die Kommunikation 
untereinander aufbaust, wenn du nicht in ein Master Slave Problem inkl. 
Kollisionserkennung reinrutschen möchtest, dann lasse immer den "Master" 
den/die Slaves abfragen. Der "Slave" darf nicht von selbst irgendwelche 
Daten senden. Dann kannste vielleicht folgendes machen.

Die "normalen Nanos" sind jeweils die Master für ihre Unter-Nanos 
(Slaves). Diese Master fragen der Reihe nach im Kreis ihre Slaves 
zyklisch nach neuen Daten ab und erhalten sie auch. Dein Haupt-Nano ist 
der Master für die "normalen Nanos", seine Slaves wiederum. Auch hier 
lässt du den Master zyklisch oder bei Bedarf der Reihe nach seine Slaves 
("normalen Nanos") abfragen.

Jetzt ist die Frage bei dir, die du dir stellen musst folgende. Sollen 
die Master<>Slaves jeweils getrennte Busse haben, sodass diese jederzeit 
unabhängig vom übergeordneten Master mit ihren Slaves kommunizieren 
können. Oder sollen die alle an einem Bus hängen und der Haupt-Nano 
redet darauf nur mit den normalen Nanos und der mit den Unter-Nanos. 
Wobei dann letzteres keinen großen Sinn macht. Dann kann der Haupt-Nano 
auch gleich mit allen reden. Wenn doch mit einem Bus gedacht, dann 
behalte das Prinzip bei. Nur der Master quatscht den Slave an und wartet 
auf Antwort. Der angesprochene Slave ist dann Master und quatscht seinen 
Slave an. Der Slave antwortet seinem Master und der antwortet wieder als 
Slave seinem Master. Wenn die Antwort rückwärts erfolgt ist, fragen der 
Haupt-Master seinen nächsten Slave ab. Dabei ist jederzeit klar, wer 
fragt und antworten muss.

Wichtig ist ein sauberes Protokoll für die Kommunikation zu erstellen. 
Der Hardwareaufbau ist dabei das geringste Problem.  :-)

: Bearbeitet durch User
von Der Checker (Gast)


Lesenswert?

>Wichtig ist ein sauberes Protokoll für die Kommunikation zu erstellen.

Und sowas soll Spaß machen?

Planen, entwerfen und dieser ganze Nonsens ist was für nachdenkliche 
Typen und verkopfte Theoretiker - kurz Loser. Für solche 
Langweiligkeiten sollte einem die Zeit zu schade sein. Die investiert 
man besser in das Schreiben von Programmcode. Was soll schon 
schiefgehen? Man kann doch alles zu jeder Zeit wieder ändern! Also kommt 
man auch so zum Ziel. Einfach mal machen ist das Motto der Winner, oder 
erzähl ich hier Blödsinn? Ruhig auch mal als Noch-Nicht-so-Erfahrener an 
was Schwieriges wagen, das zeugt von Mut und von der Bereitschaft, an 
solchen Aufgaben zu wachsen.

Logo, dass es mal hier oder da hakt, aber dafür gibts Lösungen. Den 
Debugger zum Beispiel. Oder den Watchdog. Oder man ersetzt den 
Controller durch einen anderen, wenn nur noch ein Hardwarefehler als 
Ursache in Frage kommt. In Internetforen kann man Experten um Rat 
bitten. Wenn das alles aber nicht geholfen hat, dann sollte man wirklich 
das Interrupt Enable in allen Interrupts setzen. Kommt einer 
Verdoppelung der Controllerleistung gleich. Gratis! Somit praktisch 
garantiert, dass es danach reibungslos läuft.

Ja, das sind die Tricks, die den Profi zum Profi machen. Jetzt weißt Du 
Bescheid. Leg los. Viel Erfolg.

von Cyblord -. (cyblord)


Lesenswert?

Rainer V. schrieb:

> Hallo, ja, das weiß ich, auch weil ich nicht wirklich Anfänger bin
> (trotzdem aber Bastler). Aber vor Int habe ich mich bisher eben
> gedrückt! Bis zu einem bestimmten Punkt gehts auch ohne...und die
> Herausforderung für meinen bescheidenen Rahmen ist für mich ok. Habe
> früher beruflich mit diesen Sachen zu tun gehabt und ehrlich, bis ich
> ein Ethernet, ein Profibus, ein COM-Net und was auch immer, dazu
> bekomme, zusammenzuspielen, zumal ich auf der Controllerseite
> sitze...niemals wäre ein Raumschiff in den Orbiter gekommen...
> Gruß Rainer

Evt. reicht auch schon sowas wie CAN oder LIN. Aber irgendein Protokoll 
on Top brauchst du trotzdem noch.
Aber man sollte ich bei vielen Controller, und SubControllern schon mal 
schauen wie es andere machen und grade in Fahr- oder Flugzeugen gibt es 
diese Situation. Und die Antwort sind eben Busse wie CAN, LIN, Flexray 
oder AIRINC.
Zunehmend auch Ethernet, aber das muss für dich ja nicht sein.

Ich behaupte, ohne eine Strukturierte Kommunikation kommt man nicht ans 
Ziel. Einfach hier und da mal irgendwas senden und irgendwo wird 
vielleicht mal was empfangen, muss ins Chaos führen.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Johann L. schrieb:
>> PS: dabei kommt mir noch die Frage, wieviele Interrupts die AVR denn
>> überhaupt schachteln können...
>
> Bis der Platz auf dem Stack aus ist; bzw. bis der Stack in den anders
> genutzten Speicher bzw. Adressbereich hineinwächst: Heap, Static
> Storage, I/O-Bereich, ...

 Lol.
 AVR kann keine Interrupts schachteln, d.h. es kann von jedem Interrupt
 nur einer gemerkt werden.
 Wenn während einer INT0-isr Timer_1 dreimal zuschlägt, wird die
 Timer_1-isr nach der INT0-isr trotzdem nur einmal ausgeführt.
 M328P z.B. hat 26 Int-Vectors, soviel Stack*2 wird im schlimmsten Fall
 ohne dein Zutun verbraucht. Wieviel Stack einzelne isr verbraucht ist
 uninteressant, da der benutzte Platz auf dem Stack nach der isr wieder
 freigegeben wird.

 Und was die "Ratschläge" mit wiedersetzen des Interrupts Flag betrifft:
 Interrupts in der isr wieder freigeben ist schlicht gesagt dumm - nix
 ist so wichtig, daß die paar us nicht gewartet werden kann.
 Was ist wenn in irgendeiner isr dieselbe isr wieder zuschlägt?

 Ist diese isr re-entrant, was ist wenn der benötigte Pointer nicht
 rechtzeitig erhöht wurde, wenn I/O Register nicht ausgelesen ist?

 Isr soll, wie schon jemand geschrieben hat, so kurz wie nur möglich
 sein, am besten nur mit Flag setzen, ev. ein Byte reinschreiben und
 alles andere soll dann eine State-Machine in main() erledigen.

von Oliver S. (oliverso)


Lesenswert?

Marc V. schrieb:
> AVR kann keine Interrupts schachteln, d.h. es kann von jedem Interrupt
>  nur einer gemerkt werden.
>  Wenn während einer INT0-isr Timer_1 dreimal zuschlägt, wird die
>  Timer_1-isr nach der INT0-isr trotzdem nur einmal ausgeführt.
>  M328P z.B. hat 26 Int-Vectors, soviel Stack*2 wird im schlimmsten Fall
>  ohne dein Zutun verbraucht. Wieviel Stack einzelne isr verbraucht ist
>  uninteressant, da der benutzte Platz auf dem Stack nach der isr wieder
>  freigegeben wird.

Liest du auch, was du schreibst?

Defaultmässig ist beim AVR immer nur eine einzige ISR aktiv, die 
benötigt auf dem Stack den Platz für eine Rücksprungadresse plus das, 
was die ISR selber anlegt, unabhängig davon, wie viele Int-Vekoren der 
Prozessor hat.

Setzt man das I-Flag in den ISRs, dann können beliebig viele ISRs 
geschachtelt werden, bzw. so viele, bis der Stack überläuft.

Oliver

von Peter D. (peda)


Lesenswert?

Rainer V. schrieb:
> Sorry, aber ich versuche ein
> Gefühl für Interrupts zu bekommen

Gerade dann solltest Du Dir nicht gleich Schweinereien angewöhnen, 
sondern erstmal sicher und zuverlässig bleiben.
Gerade Interrupts, die etwas mehr tun sollen, löschen nicht ihr 
Interruptflag automatisch beim Eintritt, d.h. legen Dir die 
Bananenschale aus. Wenn Du unbedingt drauf ausrutschen willst, nur zu.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Oliver S. schrieb:
> Liest du auch, was du schreibst?

 Liest du auch, worauf du antwortest?

von Axel S. (a-za-z0-9)


Lesenswert?

Marc V. schrieb:
> Johann L. schrieb:
>>> PS: dabei kommt mir noch die Frage, wieviele Interrupts die AVR denn
>>> überhaupt schachteln können...
>>
>> Bis der Platz auf dem Stack aus ist

>  Lol.
>  AVR kann keine Interrupts schachteln,
> d.h. es kann von jedem Interrupt nur einer gemerkt werden.

Das sind zwei verschiedene Paar Schuhe. Auch µC mit schachtelbaren 
Interrupts haben i.d.R. nur ein "interrupt pending" bit pro Interrupt- 
Quelle. Sie können sich genauso wie der AVR nur einen Interrupt pro 
Quelle merken. Wenn Interrupts lange genug gesperrt sind (warum auch 
immer) und die gleiche Quelle mehrfach auslöst, dann gehen alle 
Interrupts bis auf einen verloren. Ist halt so.

>  Wieviel Stack einzelne isr verbraucht ist
>  uninteressant, da der benutzte Platz auf dem Stack nach der isr
>  wieder freigegeben wird.

Aber erst am Ende. Wenn eine ISR von einem (anderen) Interrupt 
unterbrochen wird, dann ist das genauso wie ein Funktionsaufruf. Es wird 
ein Stackframe erzeugt und die "neue" ISR aufgerufen. Je nach 
Schachtelungstiefe kann da durchauch einiges an Stackspace zusammen 
kommen.

>  Und was die "Ratschläge" mit wiedersetzen des Interrupts Flag betrifft:
>  Interrupts in der isr wieder freigeben ist schlicht gesagt dumm - nix
>  ist so wichtig, daß die paar us nicht gewartet werden kann.

Aha. Komischerweise haben viele andere µC (so ziemlich alle außer den 
AVR) schachtelbare Interrupts, oft sogar mit manuell vergebbaren 
Prioritäten. Das haben die Hersteller bestimmt deswegen eingebaut, weil 
es niemand braucht. </ironie>

>  Was ist wenn in irgendeiner isr dieselbe isr wieder zuschlägt?

Dann war der Programmierer dämlich. Bei einer Timer-ISR versteht es sich 
von selbst, daß die ISR nicht länger brauchen darf als ein 
Timer-Intervall. Und wenn man keine Kontrolle über das Zeitverhalten hat 
(z.B. Pin-Change Interrupt) dann muß man die Interrupt-Quelle (und nur 
die) innerhalb der ISR deaktivieren. µC mit schachtelbaren Interrupts 
machen das oft in Hardware. Erst wenn man das "interrupt pending" Bit 
manuell gelöscht hat, kann der gleiche Interrupt wieder zuschlagen. Also 
macht man das als letzte Aktion in der ISR und alles ist schick. Beim 
Z80 haben die Peripherie-Bausteine sogar auf dem Bus mitgelauscht, um 
die RETI Instruktion zu erkennen und erst danach wieder einen Interrupt 
auszulösen.

>  Isr soll, wie schon jemand geschrieben hat, so kurz wie nur möglich
>  sein, am besten nur mit Flag setzen, ev. ein Byte reinschreiben und
>  alles andere soll dann eine State-Machine in main() erledigen.

Das ist die Methode für Dummies. Macht man nichts mit verkehrt, aber man 
macht sich sehr wahrscheinlich viel mehr Arbeit als nötig. Kann man so 
machen, muß man aber nicht.

So lange das Zeitverhalten des Codes deterministisch ist, darf eine ISR 
auch 1000 Takte oder länger laufen. Und wenn es andere Interrupts gibt, 
die nicht so lange warten können, dann macht man die ISR eben 
unterbrechbar (AVR) bzw. priorisiert den anderen Interrupt höher. 
BTDTMT.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Axel S. schrieb:
> Aha. Komischerweise haben viele andere µC (so ziemlich alle außer den
> AVR) schachtelbare Interrupts, oft sogar mit manuell vergebbaren
> Prioritäten. Das haben die Hersteller bestimmt deswegen eingebaut, weil
> es niemand braucht. </ironie>

Ohne Prioritäten ist das Konzept halt wenig sinnvoll, und für einen 
vollwertigen Interrupt-Controller war auf den alten AVRs wohl nicht 
genügend Platz. Die neuen Modelle können da ja inzwischen auch mehr.

Oliver

von Rainer V. (a_zip)


Lesenswert?

Danke für die vielen Anregungen! Mein momentaner Entwurf geht 
tatsächlich von einer Master-Slave Topologie aus. Der Master fragt einen 
Slave und zwar so lange, bis der geantwortet hat. Natürlich mit einem 
Timeout... Der Slave seinerseits hat daneben drei Prozesse, die er 
anstößt und von denen einer seine Daten über ein Pulslängenprotokoll 
zurückgibt. Wenn ich dieses Paket unterbreche, sind die Daten 
ungültig/falsch. Eine Anfrage vom Master soll die laufenden Prozesse 
nicht unterbrechen, sondern erst bedient werden, wenn der Slave quasi 
"Idle" ist. Das sollte also alles nicht in eine verschachtelte 
"Interruptorgie" ausarten. Wollte eben nur fragen, ob ich den 
Interruptmechanismus beim AVR richtig verstanden habe. In den nächsten 
Tagen bekomme ich RS-422-Bausteine, mit denen ich die 
Halb-Duplex-Verbindung aufbauen will. Dann sehe ich weiter!
Gruß Rainer

von Veit D. (devil-elec)


Lesenswert?

Hallo,

eines musst du nochmal erklären was du vorhast, ich denke du verrennst 
dich in der Interruptorgie. Wofür benötigst du eine 
Interruptverschachtelung für die Kommunikation? Du musst nur die USARTs 
und das Protokoll richtig programmieren. Dann schickt der Master eine 
Anfrage raus und wartet auf Antwort. Während er wartet kann er andere 
Dinge machen. Ohnen jeden zusätzlichen Interrupt. Die USART Daten liest 
du nebenbei mit ein, diese Hardwareeinheit hat selbst Interrupts, dass 
reicht aus.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Axel S. schrieb:
>> Isr soll, wie schon jemand geschrieben hat, so kurz wie nur möglich
>> sein, am besten nur mit Flag setzen, ev. ein Byte reinschreiben und
>> alles andere soll dann eine State-Machine in main() erledigen.
>
> Das ist die Methode für Dummies.

 Nein, es ist eher andersrum  - zumindest beim AVR.
 Nur Dummies und LED-Blink "Programmer" versuchen, alles in der isr
 zu machen.

> Macht man nichts mit verkehrt, aber man
> macht sich sehr wahrscheinlich viel mehr Arbeit als nötig. Kann man so
> machen, muß man aber nicht.

 Wieso man sich damit viel mehr Arbeit macht, ist mir unklar...
 Gerade deswegen findet man State-Machine in jedem ernstzunehmendem
 Programm, welches mit Interrupts zu tun hat.
 Und isr, welche von einer anderen isr unterbrochen werden dürfen,
 sind sowas von unwichtig bzw. Zeitunkritisch, die sind doch nur dafür
 da, um nicht in der main() ständig unwichtige Sachen abfragen zu müßen,
 z.B. LichtSensor, TempSensor, um auf Helligkeits- und Temperatur-
 veränderungen zu reagieren - (Displays etc.).
 Nichts, wo man einen AVR einsetzt, braucht isr die unterbrochen
 werden muß, vorausgesetzt, man macht es nicht wie die Dummies und
 versucht sturr, alles in der isr zu erledigen.
 Und selbst wenn - 16000 Takte dauern gerade mal 1ms.
 Für wirklich zeitkritische Aufgaben delegiert man die Arbeit ganz
 einfach, aber das ist schon eine andere Klasse - weit über AVR.

: Bearbeitet durch User
Beitrag #6406585 wurde vom Autor gelöscht.
Beitrag #6406593 wurde von einem Moderator gelöscht.
von Rainer V. (a_zip)


Lesenswert?

Veit D. schrieb:
> eines musst du nochmal erklären was du vorhast, ich denke du verrennst
> dich in der Interruptorgie.

Hi, ich habe mich nicht in eine Interrupt-Orgie verrannt, sondern 
lediglich nach Verständnis gefragt! Ob ich mein Problem so oder so löse, 
hängt von ein paar Dingen ab...auch von den Infos, die hier bekommen 
habe. Und klar, dass jetzt wieder die gelangweilten Besserwisser 
aufschlagen...eigentlich viel zu spät! Vermutlich haben sie erst jetzt 
mein Problem verstanden, um es nun ausgiebig mißzuverstehn :-)
Gruß Rainer

Beitrag #6407182 wurde von einem Moderator gelöscht.
von Einer K. (Gast)


Lesenswert?

Rainer V. schrieb:
> Hi, ich habe mich nicht in eine Interrupt-Orgie verrannt, ..
Ja, nee, iss klar ....

Dutzende von µC sollen miteinander kommunizieren, und du beauskunftest 
ISR Interne, welche haarklein im Datenblatt erklärt werden.
Die Probleme liegen doch ganz woanders.
Fängt schon mit der Wahl/Erfindung des geeigneten Protokolls/Topologie 
an.
Danach kann man auch über Interrupts nachdenken.

Interrupts möglichst kurz:
Eine brauchbare Strategie.
Schlicht, einfach nachvollziehbar.

Automaten in ISR:
Schön für Protokolle.
z.B. I2C

Wiedereintrittsfähige ISR:
> Wer Funk kennt,
> nimmt lieber Kabel.
So ist es auch mit der "Interrupt Reentrance".

Die konsequente Variante:
https://de.wikipedia.org/wiki/Interrupt#Interrupt-Service-Routinen_als_Programmierprinzip

--------

Für welches Protokoll hast du dich entschieden?

von Hugo H. (hugohurtig1)


Lesenswert?


von Rainer V. (a_zip)


Lesenswert?

Arduino Fanboy D. schrieb:
> und du beauskunftest
> ISR Interne, welche haarklein im Datenblatt erklärt werden.

Ich habe gefragt, weil ich die "haarkleinen" Erklärungen eben nicht 
verstanden habe und zudem noch widersprüchliche bzw. fehlende Infos zum 
Interruptverhalten gefunden habe. Die oberlehrerhaften Aufforderungen, 
doch endlich einmal nur die Datenblätter zu studieren, dürfen aber 
selbstverständlich in einem Fachforum nicht fehlen...wenn dann aber 
jemand seitenweise versucht zu erklären, was er in einem Datenblatt 
nicht verstanden hat, dann kommen von den einschlägigen Spezialisten 
auch wieder nur die üblichen Anfeindungen. Da hift eben nur ignorieren, 
was ich persönlich auch (fast) immer mache!
Nochmals Dank an alle, die ihr Wissen geteilt haben!
Leider sind meine Schnittstellenbauteile heute nicht in der Post 
gewesen, sodass ich noch das ganze WE für Theorie habe.
Gruß Rainer

von Hugo H. (hugohurtig1)


Lesenswert?

Hugo H. schrieb:
> Beitrag "Re: AVR Interrupt-Verhalten"

"D.h. 1 Ereignis kann 'auf Halde' liegen ohne dass es 'übersehen' wird"

Aber immer nur das letzte Auftreten eines Ereignisses (das letzte Setzen 
eines bestimmten Interrupt-Bits) wird "abgearbeitet". Es wird weder 
gezählt noch in irgendeiner "Interrupt-Reihenfolge (zum jeweiligen 
Interrupt / -Bit) verarbeitet.

von Peter D. (peda)


Lesenswert?

Einige Feinheiten:

Das von Anfängern gerne in Interrupts gemachte CLI/SEI ist Quatsch. Die 
Interruptlogik sperrt Interrupts automatisch beim Sprung in die 
Vectortabelle. Ich kenne auch keine andere Architektur, wo sowas nötig 
wäre.

CLI sperrt Interrupts sofort.
SEI, RETI geben Interrupts erst nach dem nächsten Befehl frei. Das ist 
wichtig, z.B. für atomares SEI+SLEEP. Auch wird das Main immer noch 
ausgeführt, wenn man den AVR mit Interrupts zuballert.

von Hugo H. (hugohurtig1)


Lesenswert?

Hugo H. schrieb:
> Aber immer nur das letzte Auftreten eines Ereignisses (das letzte Setzen
> eines bestimmten Interrupt-Bits) wird "abgearbeitet". Es wird weder
> gezählt noch in irgendeiner "Interrupt-Reihenfolge (zum jeweiligen
> Interrupt / -Bit) verarbeitet.

Das bedeutet auch, dass keine Zeit / kein Zeitpunkt des Auftretens 
festgehalten wird (ein Timer z. B. läuft weiter) - das sollte man 
"verinnerlichen" (neben den ggf. auftretenden zeitlichen 
"Verschiebungen" durch den Prolog etc. einer Interrupt-Serviceroutine)

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ok, du halst also Slaves, die

1) Daten per PWM o.a. in die Welt senden und "gleichzeitgig"

2) Daten (auf Anfrage) zu einem Master senden (sollen).

ad 1)
* Ist das Soft-PWM? Nutzt du PWM-fähige Timer / Ports?
* Welcher Jitter ist tolerierbar?

Jitter kann man z.B. deduzieren, indem man die Port-Ausgabe zu Anfang 
ISR macht, und erst danch werden die neuen Daten Berechnet, z.B. 
ebenfalls in der ISR falls das passt.

ad 2)
* Wird per Software-Protokoll (welches?) zum Master gesendet?
* Was passiert, wenn ein Slave nicht antwortet?
* Gibt es Handshake-leitungen?

von c-hater (Gast)


Lesenswert?

Marc V. schrieb:

>  Nein, es ist eher andersrum  - zumindest beim AVR.
>  Nur Dummies und LED-Blink "Programmer" versuchen, alles in der isr
>  zu machen.

So ein Unsinn. Alles (oder zumindest das allermeiste) in ISRs 
abzuhandeln ist vielmehr oft der effizienteste Weg. Ereignisorientierte 
Programmierung mit sehr stark reduzierter Notwendigkeit für teueres 
Polling und teuere Verzweigungen, denn das passiert dabei teilweise 
(Verzweigungen in state machines) bzw. sogar vollständig (polling 
entfällt) in HARDWARE.

Man muss nur richtig programmieren können und nicht nur Wichsvorlagen 
zusammenschustern...

Allerdings gibt es natürlich auch oft Gegenindikationen. Die kann man 
sehr einfach erfassen. Immer dann, wenn man in einer ISR in die 
Versuchung kommt, auf irgendwas warten zu wollen (bzw. zu müssen), dann 
ist das Konzept einer rein ISR-basierten Struktur der Anwendung 
zumindest zu überdenken. Manchmal lohnt es, das trotzdem zu machen, oft 
aber auch nicht.

Trifft man hingegen nicht auf diese Versuchung, ist die rein 
ISR-basierte Anwendung (und das ist auch theoretisch beweisbar!) das 
ultima ratio. Jedenfalls so lange überhaupt Interrupts benutzt werden. 
Manchmal ist auch der komplette Verzicht darauf die effizienteste 
Lösung.

Man muss einfach nur wissen, was man tut. Du weißt das definitiv immer 
noch nicht (nach so vielen Jahren: schändlich, weil nix dazu gelernt)!

von Hugo H. (hugohurtig1)


Lesenswert?

c-hater schrieb:
> Man muss nur richtig programmieren können und nicht nur Wichsvorlagen
> zusammenschustern...

Nein - man muss sich VORHER gut überlegen, was man in Interrupts 
behandeln will. Auch in Assembler kann man (auf einem 8-Bit AVR) z. B. 
nicht 100.000 Interrupts pro Sekunde "behandeln". Weder mit 
"Wichsvorlagen" noch mit C-Hater-Programmen.

Gehirn einschalten (vor der Programmierung) ist angesagt - unabhängig 
von der Umsetzung in irgendeiner Programmiersprache.

Ja - ich weiß - kritische Teile in Assembler (mein Prof. lallte immer 
auch von "Assembler-Unterprogrammen ..." :-)).

Bisher kam ich (für meine Zwecke) meist ohne aus ...

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

c-hater schrieb:
> Marc V. schrieb:
>
>>  Nein, es ist eher andersrum  - zumindest beim AVR.
>>  Nur Dummies und LED-Blink "Programmer" versuchen, alles in der isr
>>  zu machen.
>
> So ein Unsinn. Alles (oder zumindest das allermeiste) in ISRs
> abzuhandeln ist vielmehr oft der effizienteste Weg.

Ungern, wirklich ungerne, gebe ich dir recht.
Alleine schon wegen dem Prinzip, und weil du öfter mal unanständig 
agierst.

Aber in diesem Fall muss ich sagen: Du hast Wahr!

In Sachen ISR, kann man ganz entspannt auf jeglichen Dogmatismus 
verzichten, und sich stattdessen besser nach der Decke strecken. Also an 
den Notwendigkeiten orientieren.

--

> Nur Dummies und LED-Blink "Programmer" versuchen, alles in der isr
> zu machen
Ein Seitenhieb auf Arduino?
Dann daneben getroffen, denn Wire, Serial usw. bestehen, u.A. aus in der 
ISR  implementierten Automaten.
Es ist also auch dort Tradition, die ISR nicht unnötig zu verschlanken.
Und das mit Fug und Recht.

von c-hater (Gast)


Lesenswert?

Hugo H. schrieb:

> Nein - man muss sich VORHER gut überlegen, was man in Interrupts
> behandeln will.

Natürlich.

> Auch in Assembler kann man (auf einem 8-Bit AVR) z. B.
> nicht 100.000 Interrupts pro Sekunde "behandeln".

Doch, das kann man. Bei 20MHz Systemtakt bedeutet das einfach nur, dass 
die ISR insgesamt nicht länger als 198 Takte dauern darf (wenn main 
einfach nur eine Endlosschleife ist mit worst case: rjmp Anfang). Der 
minimale Interrupt-Overhead sind 8 Takte, bleiben also 190 nutzbare 
Takte. Ein gelernter Assemblerprogrammierer kann in 190 Takten eine 
Menge Zeug tun...

Du nicht!

von Hugo H. (hugohurtig1)


Lesenswert?

Arduino Fanboy D. schrieb:
> Ungern, wirklich ungerne, gebe ich dir recht.
> Alleine schon wegen dem Prinzip, und weil du öfter mal unanständig
> agierst.
>
> Aber in diesem Fall muss ich sagen: Du hast Wahr!
>
> In Sachen ISR, kann man ganz entspannt auf jeglichen Dogmatismus
> verzichten, und sich stattdessen besser nach der Decke strecken. Also an
> den Notwendigkeiten orientieren.

Lese ich das richtig? Du argumentierst für "umfangreiche Aktionen" in 
der ISR? Flags setzen ja - aber ganze "Aktionen"? Da muss ich meine 
Meinung über Dich wohl revidieren.

von Hugo H. (hugohurtig1)


Lesenswert?

c-hater schrieb:
> Du nicht!

Die Regel sind max. 16 MHz - und es gibt Prolog und Epilog - aber Du 
bist ja der Über-Flieger und kannst alles. Chapeau. Mir doch egal :-)

Was macht denn die "MAIN" wenn nur ISR prozessiert werden? Irgendwo 
beißt Du Dich in den Hintern :-)

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Hugo H. schrieb:
> Du argumentierst für "umfangreiche Aktionen" in
> der ISR?

Ich sage:
> An den Notwendigkeiten orientieren!
Auch verstehe ich das Bestreben die ISR schlank zu halten.
(aber nicht um jeden Preis)

Hugo H. schrieb:
> Da muss ich meine
> Meinung über Dich wohl revidieren.
Wenn du mich bisher als Dogmat eingestuft hast, dann kann ich dich nur 
bitten dieses zu revidieren.

von Hugo H. (hugohurtig1)


Lesenswert?

Arduino Fanboy D. schrieb:
> Wenn du mich bisher als Dogmat eingestuft hast

Habe ich nicht - aber trotzdem ... :-(

von Einer K. (Gast)


Lesenswert?

Hugo H. schrieb:
> Was macht denn die "MAIN" wenn nur ISR prozessiert werden?
z.B. nut alles initialisieren und dann in der Schleife dauernd in den 
Schlafmodus schalten, sonst nix...

von Hugo H. (hugohurtig1)


Lesenswert?

c-hater schrieb:
> Der
> minimale Interrupt-Overhead sind 8 Takte, bleiben also 190 nutzbare
> Takte. Ein gelernter Assemblerprogrammierer kann in 190 Takten eine
> Menge Zeug tun...

Ja - Du "Super-Assembler-Programmierer" schaffts alles in einer ISR. 
Prolog und Epilog kannst Du vergessen (Du hast ja alles im Griff) und 
die restlichen Takte reichen immer.

Für wie doof hälst Du eigentlich alle hier?

Ich mag Deine Beiträge aber manchmal schwillt mir der Kamm.

von Rolf M. (rmagnus)


Lesenswert?

Hugo H. schrieb:
> Hugo H. schrieb:
>> Beitrag "Re: AVR Interrupt-Verhalten"
>
> "D.h. 1 Ereignis kann 'auf Halde' liegen ohne dass es 'übersehen' wird"
>
> Aber immer nur das letzte Auftreten eines Ereignisses (das letzte Setzen
> eines bestimmten Interrupt-Bits) wird "abgearbeitet".

Eigentlich das erste. Ab da ist es ja gesetzt. Durch weitere Auftreten 
des Interrupts ändert sich am Flag nichts mehr. Wobei das eher eine 
philosophische Frage ist, ob es nu n der erste oder letzte ist. Der 
Interrupt wird halt als "aufgetreten" markiert, und da es nur einen 
Marker (das Flag) gibt, gibt es nur die Info darüber, dass er 
aufgetreten ist, aber nicht wie oft.

von c-hater (Gast)


Lesenswert?

Hugo H. schrieb:

> Die Regel sind max. 16 MHz

Nicht in meiner AVR8-Welt. Die reicht offensichtlich weiter als deine...

> und es gibt Prolog und Epilog

Nö, in Assembler gibt es einen minimalen Interruptframe und der dauert 
bei den meisten AVR8 genau 8 Takte. Nur die ganz grossen mit 22-Bit PC 
und/oder die mit externem RAM brauchen ein paar Takte mehr. Das ist aber 
keine Geheimwissenschaft oder Raketentechnik, sonder steht schlicht im 
jeweiligen Datenblatt. Man muß es nur lesen...

Das, was du als "Prolog/Epilog" bezeichnest, ist überwiegend unnützer 
C-Bullshit. In Assembler lacht man darüber...

> aber Du
> bist ja der Über-Flieger und kannst alles.

Alles sicher nicht. Aber die AVR8 beherrsche ich doch noch 15 Jahren 
aktiver Entwicklungsarbeit wirklich nahezu perfekt. Bei den neueren 
klemmt's gelegentlich, da muss ich einfach auch noch das tun, was manche 
Leute nie tun: Lernen.

> Was macht denn die "MAIN" wenn nur ISR prozessiert werden?

I.d.R. nur eins: die MCU schlafen schicken. Genau genommen ist die 
Tatsache, dass in main nix weiter zu tun bleibt, das sichere Zeichen, 
dass man die optimale Lösung für die Anwendung gefunden hat...

von Rainer V. (a_zip)


Lesenswert?

Also, ich habe momentan 5 Slaves, die ich per RS422 anspreche und Daten 
haben möchte. Und wie schon geschrieben, haben die Slaves 3 Tasks, von 
denen ich eine nicht unterbrechen kann...ob das so sein/bleiben muß, 
lass ich mir noch mal durch den Kopf gehen. Ich habe jetzt (hoffentlich) 
verstanden, dass ich die Anfrage vom Master verliere, wenn der Slave in 
seiner "kritischen" Task werkelt oder ich lasse den Interrupt zu und 
zerstöre diese Task. Ohne jetzt nachgerechnet zu haben, denke ich, dass 
selbst die kürzeste Interrupt-Routine zu lang sein wird. Jetzt kann ich 
natürlich auch die Strategie des Master überdenken. Wie lange wartet der 
Master auf eine Antwort, fragt er nach diesem Timeout denselben Slave 
noch mal oder geht er zum nächsten oder ? Auch das Gesamttiming muß ich 
wohl noch mal für mich präzisieren. Gehe momentan davon aus, dass der 
Master etwa alle Sekunde neue Daten von allen Slaves haben muß. Das hört 
sich wie ewig an, bei Taktfrequenzen im MHz-Bereich, kann aber bei so 
einem System schon kurz genug sein.
Ich arbeite übrigens entweder in Assembler oder in Forth und für mich 
gibt es die Regel, dass eine Interrupt-Routine so kurz wie möglich zu 
sein hat, schlicht nicht! Das hängt einfach "davon" ab...
Gruß Rainer

von c-hater (Gast)


Lesenswert?

Rainer V. schrieb:

> Also, ich habe momentan 5 Slaves, die ich per RS422 anspreche und Daten
> haben möchte. Und wie schon geschrieben, haben die Slaves 3 Tasks, von
> denen ich eine nicht unterbrechen kann...

Warum kannst du diesen Task nicht unterbrechen? Das gibt es 
normalerweise nicht. Finde heraus, wie lange du ihn unterbrechen 
könntest, ohne seine Funktion zu gefährden!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

c-hater schrieb:
> Das, was du als "Prolog/Epilog" bezeichnest, ist überwiegend unnützer
> C-Bullshit. In Assembler lacht man darüber...

Falls du dich auf avr-gcc beziehst, das ist schon seit bereits 3 
Compiler-Versionen nicht mehr so.  Soviel zu "Lernen".

von Rolf M. (rmagnus)


Lesenswert?

c-hater schrieb:
> Nö, in Assembler gibt es einen minimalen Interruptframe und der dauert
> bei den meisten AVR8 genau 8 Takte.

Wie das? Wenn ein Interrupt eintritt, passiert folgendes:

- die aktuelle Instruktion wird fertig ausgeführt (0 bis 4 Takte)
- Sprung in die Interrupt-Vektor-Tabelle (4 Takte)
- üblicherweise RJMP zur ISR (2 Takte)
<Inhalt der ISR>
- RETI (4 Takte)

Macht zusammen 10 bis 14 für eine leere ISR und nicht "genau 8". Wenn 
man dann noch das SREG und wenigstens ein Register sichern will, damit 
die ISR auch was tun kann, kommen gleich nochmal 10 dazu. (PUSH R16, IN 
R16, SREG, PUSH R16 und am Ende das umgekehrte). Also sprich, so 20 bis 
24 und pro weiterem zu sicherndem Register nochmal 4, und dann kann man 
mal mit dem eigentlichen Inhalt der ISR anfangen.

von Ergo (Gast)


Lesenswert?

Die Moral von der Gschicht'

Anstatt immer über den Zaun zu gucken, muß man eben mit den Fähigkeiten 
und Beschränkungen der jeweiligen uC zurechtkommen und optimal innerhalb 
dieser Grenzen operieren.

Nur weil es vielleicht irgendwo etwas Besseres möglicherweise gibt, 
bedeutet das noch lange nicht, daß einfachere Architekturen nicht doch 
nützlich sind. Bis jetzt konnte ich meine Anwendungen auf jeden uC zum 
ordnungsgemäßen Laufen bekommen. Ich kann leider nicht nachvollzuziehen 
warum darüber so viel Gedöhns gemacht wird.

Firmen wie R&S konstruierten in den 80er Jahren beeindruckende Meßgeräte 
mit heutzutage vergleichbar sehr beschränkter uC Technik. Sie wußten 
eben das Beste aus der zur zur Verfügung stehenden Ressource 
herauszukitzeln und hatten fundierte Programmierkenntnisse. Man hatte 
auch nicht so viele Flausen im Kopf und beschränkte sich auf die 
wirklich notwendige Funktionalität.

Heutzutage ergeht man sich im Konsumerbereich in aus der Hand gehende 
Featureorgien und Spyware ist das Holy Grail der Entwickler und 
Marketiergurus.

OK. AVR hat gewisse Defizite. Das heißt aber noch lange nicht, der AVR 
wäre nutzlos nur weil gewisse Beschränkungen in engen Bereichen bei 
anderen Architekturen besser gelöst ist. Nicht jeder Entwickler stößt 
gegen solche Grenzen.

von c-hater (Gast)


Lesenswert?

Johann L. schrieb:

> Falls du dich auf avr-gcc beziehst, das ist schon seit bereits 3
> Compiler-Versionen nicht mehr so.  Soviel zu "Lernen".

Ah ja. Deann setze enfach eines der beiden von mir veröffentlichen 
Anwendungen (zu finden in Projekte & Code) in C um, meinetwegen auch im 
topaktuellen avr-gcc. Es wird dir nicht gelingen.

Erst, falls das doch der Fall wäre, gäbe es für mich etwas zu lernen...

Wird aber nicht passieren. Dazu müßte der Compiler weit über 
Funktionsebene optimieren können und eine Vorstellung über den Impact 
einer ISR in der Gesamtanwendung haben. Kann er aber nicht...

Du machst immer wieder denselben Fehler (wie einige andere auch): Du 
glaubst, weil ich es ablehne, diesen Scheiß freiwillig zu benutzen, 
hätte ich keine Ahnung davon...

Und: Du kannst NIX, was der Compiler nicht kann, jedenfalls nicht, ohne 
auf Asm zurückzugreifen. Also selbst wenn du mit solchen unfairen Tricks 
zu einer Lösung kommen solltest (was immerhin Kompetenz beweisen würde), 
würde das Ergebnis genauso "portabel" sein wie mein nativer 
Assemblercode. Also wäre die Verwendung von C und der ganze Sackstand 
damit absolut nutzlose Wichse...

Aber das können wir dann diskutieren, wenn du die C-Lösung fertig 
hast...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

c-hater schrieb:
> Johann L. schrieb:
>
>> Falls du dich auf avr-gcc beziehst, das ist schon seit bereits 3
>> Compiler-Versionen nicht mehr so.  Soviel zu "Lernen".
>
> Ah ja. Deann setze enfach eines der beiden von mir veröffentlichen
> Anwendungen (zu finden in Projekte & Code) in C um, meinetwegen auch im
> topaktuellen avr-gcc. Es wird dir nicht gelingen.
>
> Erst, falls das doch der Fall wäre, gäbe es für mich etwas zu lernen...

Du hättest ja schon was gelernt, wenn du nicht immer wieder veraltete 
Sachstände repetieren würdest.

> Und: Du kannst NIX, was der Compiler nicht kann,

Stimmt.  Es gibt aber Dinge, die der Compiler wesentlich schneller kann 
als ich, und wenn es nicht Resource-kritisch ist, hab ich mit ein paar % 
Overhead kein Problem.

: Bearbeitet durch User
von Rainer V. (a_zip)


Lesenswert?

c-hater schrieb:
> Warum kannst du diesen Task nicht unterbrechen? Das gibt es
> normalerweise nicht.

Ja, normalerweise...und ich meine, ich hätte schon geschrieben, dass es 
sich um ein "uraltes" Modul aus der Bastelkiste handelt, dass ich jetzt 
einfach mal benutzen will. Es taktet seine Daten in einem festen Frame 
von ca. 20ms alle Sekunde raus. Es kann nicht angestossen werden - 
ansonsten wäre das Problem natürlich vom Tisch. Und um es gleich zu 
sagen, diese Task läuft natürlich schon in einer Interrupt-Routine. 
Selbst wenn ich die Zeit, in der alle Slaves ihre Daten übermittelt 
haben müssen, auf 2s lege, muß ich doch quasi 6 asynchrone Ereignisse, 
die sich alle irgendwie blockieren können, in dieser Zeit "geschafft" 
haben. Muß mangels Hardware jetzt noch mal genauer in das Timing des 
Systems/Programms einsteigen.
Danke und gute Nacht, Rainer

von c-hater (Gast)


Lesenswert?

Rolf M. schrieb:

> Wie das? Wenn ein Interrupt eintritt, passiert folgendes:
>
> - die aktuelle Instruktion wird fertig ausgeführt (0 bis 4 Takte)

Das ist eine Sache, die einzig für die Latenz relevant ist, nicht aber 
für den Durchsatz. Wenn du nicht einmal das (oder auch nur den 
Unterschied) begriffen hast, tust du mir leid...

Die Sache ist einfach die: egal an welchem Punkt unterbrochen wurde, die 
von main sozusagen geklaute Zeit wird am Ende der ISR in main auch 
weniger gebraucht...

> - Sprung in die Interrupt-Vektor-Tabelle (4 Takte)

Genau genommen ist das die erste Hälfte des unumgänglichen 
Interruptframe. Allerdings stellst du das vollkommen falsch dar. Es gibt 
keinen "Sprung in die Interrupt-Vektor-Tabelle". Das passiert in 
Hardware ohne Taktkosten (wird nebenbei erledigt). Was kostet, ist das 
Ablegen der Rücksprungadresse der ISR auf dem Stack. Deswegen (und nur 
deswegen) variiert der Minimum-Frame. Bei 22Bit-PC müssen halt nicht nur 
zwei, sondern drei Bytes Returnadresse auf den Stack gelegt werden und 
bei externem RAM kosten ein Bytezugriff auf das SRAM halt (mindestens) 
drei und nicht nur zwei Takte.

> - üblicherweise RJMP zur ISR (2 Takte)

Das kann man in Assembler ggf. umgehen. In-place-ISR. Der Code der ISR 
fängt einfach direkt auf dem Vektor an.

> - RETI (4 Takte)

Da passiert die zweite Hälfte des unvermeidlichen Minimalframe. Aber das 
ist spiegelbildlich zu dem, was beim Interupteintritt passiert. 
Bestimmend ist der Aufwand, die Rücksprungadresse vom Stack zu holen.

Im Minumum bleibt für den Durchsatz halt 4 Takte für den Eintritt in die 
ISR und 4 Takte für den Return.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Rainer V. schrieb:
> Es taktet seine Daten in einem festen Frame von ca. 20ms
> alle Sekunde raus.

20ms sind doch ewig; in der Zeit sind schon Weltreicht aufgestiegen und 
wieder zerfallen...

20ms sind 20000 Ticks/MHz, bei 16MHz zum Beispiel 320000 Ticks. Ist 
Fortran oder dein OS / Task-System so ineffizient?

Oder entsprechen die 20ms der Frequenz, d.h. alle 20ms wird ein Puls der 
PWM ausgegeben?

Momentan ist immer noch unklar, wie die Nachrichtenformate genau 
aussehen, und welche Jitter etc. sie akzeptieren.

von c-hater (Gast)


Lesenswert?

Johann L. schrieb:

> Stimmt.  Es gibt aber Dinge, die der Compiler wesentlich schneller kann
> als ich, und wenn es nicht Resource-kritisch ist, hab ich mit ein paar %
> Overhead kein Problem.

Sprich: De facto gibst du also zu, dass ich in Assembler effizienteren 
Code produzieren kann als dein topaktueller Compiler. Nur um das mal 
(auch für die Dummies vollkommen zweifelsfrei) klarzustellen...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

c-hater schrieb:
> Johann L. schrieb:
>
>> Stimmt.  Es gibt aber Dinge, die der Compiler wesentlich schneller kann
>> als ich, und wenn es nicht Resource-kritisch ist, hab ich mit ein paar %
>> Overhead kein Problem.
>
> Sprich: De facto gibst du also zu, dass ich in Assembler effizienteren
> Code produzieren kann als dein topaktueller Compiler. Nur um das mal
> (auch für die Dummies vollkommen zweifelsfrei) klarzustellen...

Das ist keine Kunst, das kann ich auch.  Aber in 99% der Fälle brauch 
ich's eben nicht.  Ich genieße dann dass der Code in einem Augenblick 
übersetzt ist, und ich mich nicht mit Registerallokierung, Runterbrechen 
von Arithmetik, Jumpty-Jumps etc. rumplagen muss. Aber wenn man Zeit 
genug hat und ein ästethisches Bedürfnis danach hat, den endeffizienten 
Code zu klöppeln — bitteschön.

Aber lass uns nicht schon *wieder* in irgendwelche fruchtlosen, 
überflüssige Rants verfallen.  Zu dem Thema wurde wirklich schon alles 
geschrieben.

von c-hater (Gast)


Lesenswert?

Johann L. schrieb:

> Das ist keine Kunst, das kann ich auch.

Beweise es. Behaupten kann man viel...

> Aber in 99% der Fälle brauch
> ich's eben nicht.

Natürlich. Das ist völlig unstrittig. Brauchen tut man diese Kompetenz 
nur, wenn man aus gegebener Hardware das Maxium an Performance 
herausholen muss. Das ist relativ selten. Hardware ist heute zu billig 
geworden. Nimmt man halt einen potenteren Controller...

Aber: Wenn man in einer bestehenden Lösung noch ein bissel 
Funktionalität einbauen muss, obwohl diese bereits ausgereizt war, dann 
kann diese Kompetenz sehr nützlich sein. Und sich direkt massiv in (bei 
der Hardware gesparten) Euro auszahlen...

> Ich genieße dann dass der Code in einem Augenblick
> übersetzt ist, und ich mich nicht mit Registerallokierung, Runterbrechen
> von Arithmetik, Jumpty-Jumps etc. rumplagen muss. Aber wenn man Zeit
> genug hat und ein ästethisches Bedürfnis danach hat, den endeffizienten
> Code zu klöppeln — bitteschön.

Reiner Softwerker, alles klar...

von Theor (Gast)


Lesenswert?

Rainer V. schrieb:
> [...]
> Muß mangels Hardware jetzt noch mal genauer in das Timing des
> Systems/Programms einsteigen.
> Danke und gute Nacht, Rainer

Ich halte es für denkbar, dass Dir dabei noch folgendes Detail von 
Nutzen sein könnte:

Die Interrupts haben eine "Priorität".

Das bedeutet, dass, falls zu einem Zeitpunkt gleichzeitig zwei 
verschiedene, aktivierte Interrupts anhängig sind (pending), dann wird 
zuerst die ISR ausgeführt, welche in der Interrupt-Tabelle die 
niedrigere Adresse, und damit die höhere Priorität, hat.

Siehe z.B. das Datenblatt vom ATMega169 oder den ATTiny24A usw. und dort 
im Kapitel "Reset and Interrupt Handling". Die Kapitelnummer kann je 
nach Typ variieren. Soweit mir bekannt gilt das Gesagte für alle AVRs.

: gruss viel erfolg ;

von Rolf M. (rmagnus)


Lesenswert?

c-hater schrieb:
> Rolf M. schrieb:
>
>> Wie das? Wenn ein Interrupt eintritt, passiert folgendes:
>>
>> - die aktuelle Instruktion wird fertig ausgeführt (0 bis 4 Takte)
>
> Das ist eine Sache, die einzig für die Latenz relevant ist, nicht aber
> für den Durchsatz.

Natürlich ist die relevant. Denn wie du ja selbst schreibst, wird nach 
einem RETI oder CLI immer erst noch eine Instruktion ausgeführt, bevor 
der nächste Interrupt kommt. Du kannst also niemals die ISR zweimal 
direkt hintereinander ausführen, ohne dass du dazwischen auf die 
Abarbeitung einer Instruktion warten musst.

> Die Sache ist einfach die: egal an welchem Punkt unterbrochen wurde, die
> von main sozusagen geklaute Zeit wird am Ende der ISR in main auch
> weniger gebraucht...

Hast du nicht von einem Programm gesprochen, das alles in der ISR macht 
und dessen Hauptschleife nur aus einem RJMP zu sich selbst besteht? Dann 
hast du immer die zwei Takte an zusätzlicher Laufzeit zwischen zwei 
Ausführungen der ISR. Die hast du doch oben sogar selbst mit 
berücksichtigt.

>> - Sprung in die Interrupt-Vektor-Tabelle (4 Takte)
>
> Genau genommen ist das die erste Hälfte des unumgänglichen
> Interruptframe. Allerdings stellst du das vollkommen falsch dar. Es gibt
> keinen "Sprung in die Interrupt-Vektor-Tabelle". Das passiert in
> Hardware ohne Taktkosten (wird nebenbei erledigt). Was kostet, ist das
> Ablegen der Rücksprungadresse der ISR auf dem Stack.

Das ist für mich Teil des Sprungs in die Interrupt-Vektor-Tabelle, 
ähnlich wie bei einem CALL.

>> - üblicherweise RJMP zur ISR (2 Takte)
>
> Das kann man in Assembler ggf. umgehen. In-place-ISR. Der Code der ISR
> fängt einfach direkt auf dem Vektor an.

Das ist dann aber auch wieder so ein Spezialfall. Das ist halt der 
Unterschied. Du siehst es als Normal an, jede Menge Sonderfälle 
auszunuten, um noch einen oder zwei Taktzyklen zu sparen. Für mich ist 
der Normalfall erstmal einer, der sauber und ohne fiese Tricks auskommt 
und in der Regel immer so nutzbar ist. Nur, wenn mir der nicht ausreicht 
(was eher selten vorkommt), schaue ich, ob ich derartige Abkürzungen, 
die ja meistens auf die Übersichtlichkeit des Code einen negativen 
Einfluss haben, nehmen kann.

Beitrag #6409236 wurde vom Autor gelöscht.
von Joachim B. (jar)


Lesenswert?

c-hater schrieb:
> Bei 22Bit-PC müssen halt nicht nur
> zwei, sondern drei Bytes Returnadresse auf den Stack gelegt werden

nee so einfach ist das nicht!
https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set

es gib den mega 2560 der hat tatsächlich 3 Adressbytes für den RTI

(Rare) models with >128 KiB of ROM have a 3-byte program counter. 
Subroutine calls and returns use an additional byte of stack space, 
there is a new EIND register to provide additional high bits for 
indirect jumps and calls, and there are new extended instructions EIJMP 
and EICALL which use EIND:Z

aber der mega 1284p hat ja definitiv NICHT >128 KiB of ROM und somit 
wieder seine Ausnahmeregel:

Models with >64 KiB of ROM add the ELPM instruction and corresponding 
RAMPZ register. LPM instructions zero-extend the ROM address in Z; ELPM 
instructions prepend the RAMPZ register for high bits. This is not the 
same thing as the more general LPM instruction; there exist "classic" 
models with only the zero-operand form of ELPM (ATmega103 and 
at43usb320). When auto-increment is available (most models), it updates 
the entire 24-bit address including RAMPZ.

(Rare) models with >64 KiB of RAM address space extend the 16-bit RAM 
addressing limits with RAMPX, RAMPY, RAMPZ and RAMPD registers. These 
provide additional high bits for addressing modes which use the X, Y, or 
Z register pairs, respectively, or the direct addressing instructions 
LDS/STS. Unlike ROM access, there are no distinct "extended" 
instructions; instead the RAMP registers are used unconditionally.

und damit war mein Timing bei m1284p 10% langsamer als beim 328p
und nicht durch ein vermutetes und nicht vorhandenes drittes Adressbyte!

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Rolf M. schrieb:

> Natürlich ist die relevant. Denn wie du ja selbst schreibst, wird nach
> einem RETI oder CLI immer erst noch eine Instruktion ausgeführt, bevor
> der nächste Interrupt kommt.

Jepp. Genau deswegen ergab in meiner Rechnung ja auch 20.000.000/100.000 
nicht 200, sondern nur 198 Takte...

> Das ist für mich Teil des Sprungs in die Interrupt-Vektor-Tabelle,
> ähnlich wie bei einem CALL.

Du hast eben keine Ahnung von dem, was die Hardware tatsächlich tut...

> Das ist dann aber auch wieder so ein Spezialfall. Das ist halt der
> Unterschied. Du siehst es als Normal an, jede Menge Sonderfälle
> auszunuten, um noch einen oder zwei Taktzyklen zu sparen.

Wenn ich eine ISR habe, die alle 200 Takte aufgerufen wird, dann spare 
ich durch diese zwei Takte weniger in der ISR schonmal ein 1% Rechenzeit 
ein, ohne an möglicher Funktionalit der ISR zu verlieren. Wird die ISR 
hingegen alle 20 Takte ausgeführt, spare ich schon 10% Rechenzeit durch 
diesen Trick ein. Begreifst du die Konsequenz? Man muss einerseits 
abwägen, ob es sinnvoll ist. Und andererseits überhaupt die Möglichkeit 
haben, notfalls auf dieses Mittel zurückzugreifen. In Assembler habe ich 
sie. Ohne große Verrenkungen...

> Für mich ist
> der Normalfall erstmal einer, der sauber und ohne fiese Tricks auskommt

Fies sind solche Tricks nur für den, der sie nicht versteht. Das ist der 
Punkt. Die Hardware sagt was geht. Und es ist Aufgabe des 
Programmierers, sie bestmöglich zu nutzen.

Macht übrigens auch jeder C-Compiler nicht anders. Im Rahmen der 
Fähigkeiten der Verfasser des Codegenerators für das jeweilige 
Zielsystem. Und was konkret den avr-gcc angeht, besteht da immer noch 
viel Potential für Verbesserungen.
Diese sind allerdings de facto oft wegen der Sprache selber nicht 
möglich. Die hat Axiome, um die der Codegenerator herumlavieren muss. C 
weiss nix von Interrupts, C weiß nix von mehreren Adressbereichen, C 
weiß eigentlich praktisch garnix von der Realität.

Aber das ist ja kaum noch relevant, die Unterstützung für AVR8 ist ja 
eh' quasi abgekündigt.

Man könnte sich also zurücklehnen. Aber nö: Bei ARM z.B. könnte man die 
Sachlage genau wie oben für den AVR8 zusammenfassen und mit "neuen" 
Hardware-Schmankerln anreichern, von denen C auch wieder rein garnix 
weiß. Angefangen von DMA, weiter über per ExtMem eingebundenen Speicher 
usw. usf.
Ja, irgendwie alles notdürftig über C benutzbar gemacht, aber weit weg 
davon, optimal zu sein.

Richtig beherrschen kann all den Scheiß nur ein Assemblerprogrammierer. 
Und der hat ordentlich zu tun damit.

von Joachim B. (jar)


Lesenswert?

c-hater schrieb:
> Jepp. Genau deswegen ergab in meiner Rechnung ja auch 20.000.000/100.000
> nicht 200, sondern nur 198 Takte...

sicher?

auch bei 328p 1284p und 2560?
immer 198 Takte?

glaube ich nun nicht!

von c-hater (Gast)


Lesenswert?

Joachim B. schrieb:

> und damit war mein Timing bei m1284p 10% langsamer als beim 328p
> und nicht durch ein vermutetes und nicht vorhandenes drittes Adressbyte!

1) Ich würde niemals vermuten, dass der 1284P einen 22Bit-PC hat. Ich 
habe schließlich das Datenblatt gelesen...

2) Dein Timing war nicht Assemblercode sondern C, richtig? Dann weißt 
du, dass du nix weißt, sondern dich auf den Compiler verläßt. Dabei 
sollte jeder wissen, dass C KEINERLEI Timing garantiert...

Der Minumum-Interruptframe beträgt beim 1284P 8 Takte. Wie bei den 
meisten AVR8. Wenn dein C-Compiler mehr braucht, ist dein C-Compiler 
Scheiße oder du. So einfach ist das.

Vermutlich hättest du nicht aus der ISR auf konstante Daten im Flash 
(oberhalb 64k) zugreifen sollen, dann hätte es der Compiler sich 
geklemmt, RAMPZ zusätzlich auf den Stack zu legen. So gut isser ja nun 
inzwischen schon (wenn auch noch nicht seit so furchtbar langer Zeit, 
eigentlich erst, seitdem er überhaupt mit Flash >128k umgehen kann)...

von c-hater (Gast)


Lesenswert?

Joachim B. schrieb:

> auch bei 328p 1284p und 2560?
> immer 198 Takte?
>
> glaube ich nun nicht!

Ich auch nicht. Denn der 2560 hat natürlich notwendigerweise einen 
22Bit-PC.

von Maxe (Gast)


Lesenswert?

1. Was, glaub ich, noch nicht explizit gesagt wurde: Das Interruptflag 
der jeweiligen Interruptquelle wird beim Aufruf der ISR gelöscht. D.h. 
der gleiche Interrupt kann während der Abarbeitung schon "anstehen".

2. Man könnte sich selbst eine Priorisierung basteln, indem man in der 
ISR die Interruptflags ausliest und ggf. die zugehörigen ISRs auslöst 
und das Flag dann per Software löscht.

von Joachim B. (jar)


Lesenswert?

Joachim B. schrieb:
> immer 198 Takte?
> glaube ich nun nicht!
c-hater schrieb:
> Ich auch nicht. Denn der 2560 hat natürlich notwendigerweise einen
> 22Bit-PC.

und der 1284p nicht mal diesen, also war dein

c-hater schrieb:
> Jepp. Genau deswegen ergab in meiner Rechnung ja auch 20.000.000/100.000
> nicht 200, sondern nur 198 Takte...

falsch weil unpräzise?
Deine Rechnung mag richtig sein, ohne Nennung von CPU/MCU wertlos!
Es gibt ja mehr als AVR und dort mehr als den 328p.

: Bearbeitet durch User
von LostInMusic (Gast)


Lesenswert?

>2. Man könnte sich selbst eine Priorisierung basteln, indem man in der
>ISR die Interruptflags ausliest und ggf. die zugehörigen ISRs auslöst
>und das Flag dann per Software löscht.

Ja, kann man machen.

Vielleicht sollte man aber etwas anderes machen, wenn der Quotient aus 
der CPU-Leistung und den Anforderungen der Applikation dermaßen nahe an 
1 liegt, dass man sich um das Einsparen einer Handvoll Takte Gedanken 
machen muss, nämlich sich überlegen, ob dann nicht die Wahl eines 
Prozessors mit mehr Rumms vielleicht die bessere Lösung wäre.

Just my two cents.

von Maxe (Gast)


Lesenswert?

Ich würds auch nicht machen, aber ist eben nicht so, dass keine 
rudimentäre Priorisierung möglich wäre.

Oft ist es ja so, man denkt, man müsste es auf eine bestimmte Art machen 
(die der µC vielleicht gar nicht bietet) und merkt erst im Lauf der 
Implementierung, dass das garnicht so kritisch ist.

von Rainer V. (a_zip)


Lesenswert?

So, nachdem wir nun gesehen haben, dass man von 200 CPU-Zyklen 2! 
einsparen kann (natürlich nur, wenn man schlau ist...), kommen nun die 
Vorschläge, eine "dickere" Maschine zu benutzen. Allerdings ohne auf 
mein Problem einzugehen.

Ich antworte jetzt ohne Zitate auf die für mich relevanten Beiträge!

1. Ja, es ist mir klar, dass die INterrupts eine Priorität haben. Und 
nach neuerlichem Studium der Docs stellt sich mir wieder die Frage, ob 
z.B. das Interrupt-Bit - etwa von Timer - auch gesetzt wird, wenn der 
globale Interrupt nicht gesetzt ist. Wenn der globale Interrupt gesetzt 
ist, dann wird doch wohl die entsprechende Routine angesprungen...wenn 
nicht, dann wird die Routine eben nicht aufgerufen, ich wüßte aber 
zumindest, das da ein Interrupt war oder??!!

2. Wenn also mehrere Interrupts auflaufen, werden diese dann gemäß ihrer 
Priorität ausgeführt. Jeweils direkt nach dem RETI des vorhergehenden?

3. Natürlich sind 20ms nicht viel. Ich habe hier aber ein System von 10 
Prozessen auf 6 Controllern, die völlig asynchron ablaufen. Und ich will 
da eine Datenkonsistens von min. 2s realisieren. Und dieses Problem 
besteht doch völlig unabhängig von den eingesetzten Komponenten. Selbst 
wenn ich da 6 PC's zusammenklöppeln würde, wäre ich keinen Schritt 
weiter.

Gruß Rainer,
und bei diesem herrlichen Spätsommerwetter verabschiede ich mich nun in 
Garten und an Grill :-)

von Einer K. (Gast)


Lesenswert?

Rainer V. schrieb:
> stellt sich mir wieder die Frage, ob
> z.B. das Interrupt-Bit - etwa von Timer - auch gesetzt wird, wenn der
> globale Interrupt nicht gesetzt ist

AVR?
Dann auf jeden Fall: Ja!


Rainer V. schrieb:
> 2. Wenn also mehrere Interrupts auflaufen, werden diese dann gemäß ihrer
> Priorität ausgeführt. Jeweils direkt nach dem RETI des vorhergehenden?

AVR?
Es wird immer der Interrupt mit der höchsten Priorität ausgeführt.



Rainer V. schrieb:
> 3.

Das ist völlig unverständlich für mich.

von Oliver S. (oliverso)


Lesenswert?

Rainer V. schrieb:
> 1. Ja, es ist mir klar, dass die INterrupts eine Priorität haben. Und
> nach neuerlichem Studium der Docs stellt sich mir wieder die Frage, ob
> z.B. das Interrupt-Bit - etwa von Timer - auch gesetzt wird, wenn der
> globale Interrupt nicht gesetzt ist.

Eigentlich steht das eindeuting da drin, aber halt in angelsächsisch. 
Ja, die einzelnen Interruptflags werden unabhängig vom globalen i-Flag 
gesetzt.

Rainer V. schrieb:
> 2. Wenn also mehrere Interrupts auflaufen, werden diese dann gemäß ihrer
> Priorität ausgeführt. Jeweils direkt nach dem RETI des vorhergehenden?

Wie weiter oben schon mehrfach geschrieben wurde, wird nach einem Reti 
ein Befehl des unterbrochenen Programms ausgeführt, ehe der nächste 
Sprung in eine ISR stattfindet.

Oliver

von Rainer V. (a_zip)


Lesenswert?

Oliver S. schrieb:
> Wie weiter oben schon mehrfach geschrieben wurde, wird nach einem Reti
> ein Befehl des unterbrochenen Programms ausgeführt, ehe der nächste
> Sprung in eine ISR stattfindet.

Ok, habe ich so nicht registriert, ist aber wichtig! Auch wenn das 
unterbrochene Programm eine Interruptroutine war???

Arduino Fanboy D. schrieb:
> Das ist völlig unverständlich für mich.

Ist mir klar, weil du offensichtlich nur das liest, was du lesen 
möchtest. Trotzdem lese ich auch deine Beiträge wie jeden anderen...:-)
 Für mich bleibt es spannend!
Gruß Rainer

von Oliver S. (oliverso)


Lesenswert?

Rainer V. schrieb:
> Ok, habe ich so nicht registriert, ist aber wichtig! Auch wenn das
> unterbrochene Programm eine Interruptroutine war???

Eine Interrupt-Routine ist für den AVR kein besonderer Zustand. Der weiß 
gar nicht, ob er sich in einer ISR befindet, oder nicht.

Oliver

von LostInMusic (Gast)


Lesenswert?

>[...] und merkt erst im Lauf der Implementierung, dass das garnicht so
>kritisch ist.

Wie wahr!

>[...] kommen nun die Vorschläge, eine "dickere" Maschine zu benutzen.
>Allerdings ohne auf mein Problem einzugehen.

OK, dann hier noch ein Vorschlag, ohne auf Dein Problem einzugehen: Mach 
es doch mit Polling!

Wie Du schon geschrieben hast, gibt es in Deinem System fünf Slaves und 
ein Datenpaket dauert 20 ms, wenn ich das richtig verstanden habe. 
Bleibt noch die Datenübertragungsrate (eine ganz unwesentliche 
Information). Ich nehme daher einfach mal an, dass in den 20 ms fünf 
Bytes = 40 Bits übertragen werden.

Dann sieht meine kleine Beispiel-Machbarkeitsstudie dazu so aus:

Bei genannten Übertragungsrate dauert ein Bit 0.5 ms. Eine vernünftige 
Abtastrate wäre dann z. B. 0.1 ms, d. h. die Signalleitungen müssen mit 
einer Frequenz von 10 kHz gepollt werden. Eine CPU mit 20 MHz ist 2000 
mal höher getaktet, also hat man maximal 2000 Takte Zeit für die 
Auswerte-Statemachine. Da manche Instruktionen mehr als einen Takt 
benötigen, wollen wir mit 1500 Instruktionen rechnen. Geteilt durch die 
Slave-Anzahl 5 macht das immerhin 300 Instruktionen pro Slave. Abzüglich 
eines gewissen Anteils aufgrund von Overheads und weil der Prozessor 
wahrscheinlich auch noch was anderes tun soll, dürfen wir final von 
einem Kontingent von 200 Instruktionen zur Verarbeitung eines 
Übertragungsbits eines Slaves ausgehen. Nun sollte niemand 
unterschätzen, wieviel Power man in 200 Instruktionen packen kann, und 
andererseits muss man für ein Bit nur wenig machen: Pegel feststellen, 
Flankenwechsel erkennen, Timerstand auswerten, Timer runterzählen und 
gegebenfalls resetten, Ergebnisbit ins entsprechende Register shiften. 
Das ist alles mit einer kleinen Anzahl einfacher Instruktionen, die auf 
einer Handvoll Registern operieren, zu erledigen. Daher schätze ich die 
Chance, das bei einer Übertragungsrate in diesem Bereich tatsächlich so 
machen zu können, als durchaus realistisch ein - eine gute 
Implementierung der Statemaschine vorausgesetzt. Da benötigt man dann 
nur noch den Timer-Interrupt, der die 10 kHz Abtastfrequenz generiert.

>Natürlich sind 20ms nicht viel. Ich habe hier aber ein System von 10
>Prozessen auf 6 Controllern, die völlig asynchron ablaufen. Und ich will
>da eine Datenkonsistens von min. 2s realisieren. Und dieses Problem
>besteht doch völlig unabhängig von den eingesetzten Komponenten.

Bueno. Und wenn Du genau das jetzt mal im Detail so beschreiben würdest, 
dass man es auch versteht, dann würde wahrscheinlich auch endlich klar 
werden, wo Dein Problem wirklich liegt.

von Joachim B. (jar)


Lesenswert?

Oliver S. schrieb:
> Eine Interrupt-Routine ist für den AVR kein besonderer Zustand. Der weiß
> gar nicht, ob er sich in einer ISR befindet, oder nicht.

das kann man ja ändern, in jeder AVR ISR könnte man ein Flag setzen mit 
einer zugehörigen Bitnummer, dann weiss man wo der AVR steckt, bzw. 
gerade war und danach auslesen.

von Theor (Gast)


Lesenswert?

Rainer V. schrieb:
> So, nachdem wir nun gesehen haben, dass man von 200 CPU-Zyklen 2!
> einsparen kann (natürlich nur, wenn man schlau ist...), kommen nun die
> Vorschläge, eine "dickere" Maschine zu benutzen. Allerdings ohne auf
> mein Problem einzugehen.
>
> Ich antworte jetzt ohne Zitate auf die für mich relevanten Beiträge!
>
> 1. Ja, es ist mir klar, dass die INterrupts eine Priorität haben. Und
> nach neuerlichem Studium der Docs stellt sich mir wieder die Frage, ob
> z.B. das Interrupt-Bit - etwa von Timer - auch gesetzt wird, wenn der
> globale Interrupt nicht gesetzt ist. Wenn der globale Interrupt gesetzt
> ist, dann wird doch wohl die entsprechende Routine angesprungen...wenn
> nicht, dann wird die Routine eben nicht aufgerufen, ich wüßte aber
> zumindest, das da ein Interrupt war oder??!!

Im Wesentlichen ist das so. Ja.
Das Interrupt-Flag (oder -Bit, wenn Du so willst) wird unabhängig davon 
gesetzt, ob der entsprechende Interrupt freigegeben ist, oder ob global 
alle oder kein Interrupt freigegeben ist.

In der Dokumentation wird das nicht ausdrücklich so gesagt. Aber: In der 
gesamten Dokumentation wird auch das Gegenteil nicht gesagt.

In der Dokumentation wird im wesentlichen gesagt, dass die 
Interrupt-Flags zu dem Zeitpunkt gesetzt werden, zu dem ihre Bedingung 
zutrifft oder das Ereignis eingetreten ist. Sie bleiben gesetzt, bis 
entweder die Interrupt-Routine ausgeführt wird, oder das Bit durch einen 
Befehl gelöscht wird. An das globale oder indiduelle 
Interrupt-Enable-Bit wird dabei keine Bedingung geknüpft.

Das selbe Schema trifft im Allgemeinen (aber nicht grundsätzlich) zu: 
Was nicht ausdrücklich gesagt wird, trifft auch nicht zu.

Oft sind die Aussagen aber über ein Datenblatt verteilt.
Deswegen ist es manchmal nützlich zu einem Thema das gesamte Datenblatt 
durchzulesen. Z.B. in dem man in dem Datenblatt nach "Interrupt" sucht 
und alle Texte liest, in denen das Wort vorkommt.

> 2. Wenn also mehrere Interrupts auflaufen, werden diese dann gemäß ihrer
> Priorität ausgeführt. Jeweils direkt nach dem RETI des vorhergehenden?

Nein. Es wird noch mindestens ein weiterer Befehl ausgeführt. Nämlich 
der Befehl, der dem folgt, während dessen Ausführung der Interrupt 
auftrat; der Befehl, dessen Adresse auf den Stack gespeichert wurde.
Das ist hier aber schon mehrfach gesagt worden und steht auch in der 
Dokumentation.

> 3. Natürlich sind 20ms nicht viel. Ich habe hier aber ein System von 10
> Prozessen auf 6 Controllern, die völlig asynchron ablaufen. Und ich will
> da eine Datenkonsistens von min. 2s realisieren. Und dieses Problem
> besteht doch völlig unabhängig von den eingesetzten Komponenten.

Die beiden Dinge sind nicht völlig unabhängig voneinander. Sie hängen 
sogar eng zusammen.
Das eine ist Deine Forderung. Eine Eigenschaft, die das Gesamtsystem 
erfüllen soll.
Die Komponenten müssen aber auch in der Lage sein, diese Forderung zu 
erfüllen. Das ist das Andere.

> [...]

von Rainer V. (a_zip)


Lesenswert?

LostInMusic schrieb:
> Wie Du schon geschrieben hast, gibt es in Deinem System fünf Slaves und
> ein Datenpaket dauert 20 ms, wenn ich das richtig verstanden habe.

Danke für deine Mühe! Nein, du hast es eben nicht richtig verstanden. 
Die Slaves befinden sich jeweils für 20ms - und zwar auch völlig 
asynchron - in einem Prozess, der nicht unterbrochen werden darf...eben 
jeder Slave für sich (nebenbei hat auch jeder Slave zwei AD-Wandlungen 
zu managen. Das ist aber deutlich überschaubarer, glaube ich momentan 
noch :-)! Wenn der Master nun anklopft und Daten haben möchte, merkt der 
Slave das nicht und antwortet auch nicht. Wenn ich aber das 
Interrupt-Flag im Slave nach der Routine noch auswerten könnte, könnte 
ich dem Master dann trotzdem noch eine Nachricht schicken. Allerdings 
wäre die Unterbrechung der Slave-Routine schon "extrem" zeitkritisch. 
Immerhin müßte ich in deutlich unter 1ms ein Uart-Byte auswerten, damit 
der Slave sich überhaupt angesprochen fühlt. Bis dahin wäre der 
eigentliche Task aber komplett im Stillstand! Und als Slaves habe ich 
Arduino-Minis, die "nur" 4MHz Quarz haben. Insofern ist auch der Beitrag 
mit den 198 CPU-Takten nicht ganz am Thema vorbei. Ich bitte also die 
Helfe-Willigen, sich das Gesamtsystem noch mal vor die Augen zu führen. 
Ich will in min. 2s Daten von 5 Slaves bekommen. Dabei ist weder die 
Übertragungsrate der Ringleitung der Knackpunkt, sondern die Tatsache, 
dass ein Slave eben auf eine Anfrage nicht antwortet! Sicher wissen die 
Spezialisten ohne nachzudenken, wie man sowas löst...ich momentan noch 
nicht.
So Leute, der Grill glüht...aber dank modernster Technik bleibe ich mit 
meinem Pad am Ball :-)
Spätsommerlicher Gruß, Rainer

von 900ss (900ss)


Lesenswert?

Rainer V. schrieb:
> und ich hoffe doch stark, dass im Weltraum keine AVR's werkeln :-)

Doch taten sie bis vor einem Jahr für ein Experiment auf der ISS. :)
Inzwischen sind sie wieder auf der Erde.

von c-hater (Gast)


Lesenswert?

Rainer V. schrieb:

> Danke für deine Mühe! Nein, du hast es eben nicht richtig verstanden.
> Die Slaves befinden sich jeweils für 20ms - und zwar auch völlig
> asynchron - in einem Prozess, der nicht unterbrochen werden darf...

Das genau ist das Problem. Dieser "Prozess" muss einfach unterbrechbar 
gemacht werden. Wenn er das nicht von Hause aus ist, war er von 
vornherein sowieso vollkommen beschissen programmiert.

> jeder Slave für sich (nebenbei hat auch jeder Slave zwei AD-Wandlungen
> zu managen.

Was gibt es da groß zu "managen"? Normalerweise startet man die Wandlung 
und das war's. Irgendwann kommt dann ein Interrupt, der anzeigt, dass 
die Wandlung komplett ist, dann holt man das Ergebnis der Wandlung ab 
und gut isses.
In der ganzen Zwischenzeit gibt es keinen Grund, die MCU 
schwachsinnigerweise damit zu beschäftigen, auf das Ende der Wandlung zu 
warten. Die kann da was anderes tun, nämlich z.B.: eine Anfrage des 
Masters zu verarbeiten...

von Einer K. (Gast)


Lesenswert?

Rainer V. schrieb:
> Ist mir klar, weil du offensichtlich nur das liest, was du lesen
> möchtest.

Warum greifst du mich hier persönlich an?
Habe ich dir was getan?

OK, das kann ich auch...

Wenn du genauso schlampig denkst, wie du deinen Aufbau beschreibst und 
so sieht es für mich aus, dann wundert mich nicht, dass du nicht mal im 
Ansatz weiter kommst, und allmählich  sauer wirst.
Da es schließlich an dir nicht liegen kann, wird jetzt auf denen rum 
getrampelt, die den wahren Wert deiner ach so genialen und vollständigen 
Erklärungen nicht erkennen können.

Und Tschüss, viel Spaß und Erfolg ich dir wünsche, auf all deinen 
Irrwegen.

von Rainer V. (a_zip)


Lesenswert?

Arduino Fanboy D. schrieb:
> Warum greifst du mich hier persönlich an?
> Habe ich dir was getan?

Hallo, ganz im Gegenteil. Ich lese deine Beiträge, auch wenn sie mir 
manchmal abstrus vorkommen! Und entspann dich mal...ich sitze in einer 
fröhlichen Runde im Garten...bald werde ich wahrscheinlich nicht mehr 
antworten können...

c-hater schrieb:
> Das genau ist das Problem. Dieser "Prozess" muss einfach unterbrechbar
> gemacht werden. Wenn er das nicht von Hause aus ist, war er von
> vornherein sowieso vollkommen beschissen programmiert.

Ja Mann, diese Module sind uralt und sind sicher "beschissen" 
programmiert. Ich will sie aber benutzen! Und sie haben eben keine 
"Intelligenz". Sie schmeissen ihre Daten jede Sekunde raus, ob du sie 
nimmst oder nicht! Es kann ja auch sein, dass niemand mein Problem 
interessant findet...aber dann sagt das doch einfach.
 Gartengruß Rainer

von LostInMusic (Gast)


Lesenswert?

>Wenn der Master nun anklopft und Daten haben möchte, merkt der
>Slave das nicht und antwortet auch nicht. Wenn ich aber das
>Interrupt-Flag im Slave nach der Routine noch auswerten könnte, könnte
>ich dem Master dann trotzdem noch eine Nachricht schicken.

Das ist schlicht dadurch zu lösen, indem Du den externen Interrupt 
enablest. Die Request-Leitung des Masters kommt an den entsprechenden 
Pin.

Vor dem Eintritt in deine ununterbrechbare, 20 ms dauernde Routine 
deaktivierst Du alle Interrupts global mit "cli". Danach löschst Du das 
ExtInt-Pending-Bit manuell. Nach dem Ende der Routine schaust Du nach, 
ob es gesetzt ist. Wenn ja, hat der Master zwischendurch ein Anfrage 
geschickt und Du kannst sie beantworten. Dann löschst Du das 
ExtInt-Pending-Bit wieder manuell und zu guter Letzt aktivierst Du 
wieder alle Interrupts global mit "sei".

Das ist alles. Das Pending-Bit wird vollautomatisch von der Hardware 
gesetzt, weil der externe Interrupt enabled ist. Eine ISR für den ExtInt 
ist überflüssig; sie würde niemals angesprungen werden.

Oder ganz schick und wenn Du noch einen Timer mit Capture-Interrupt frei 
hast: Dasselbe damit machen; dann kannst Du sogar den Zeitpunkt 
auslesen, wann der Master den Request geschickt hat.

von c-hater (Gast)


Lesenswert?

Rainer V. schrieb:

> Ja Mann, diese Module sind uralt und sind sicher "beschissen"
> programmiert.

Dann ändere das einfach. Wo ist das Problem?

> Ich will sie aber benutzen!

Das ergibt absolut keinen Sinn!

von LostInMusic (Gast)


Lesenswert?

Nachtrag - es gibt natürlich eine noch billigere Lösung: Der Master hält 
den Pegel auf der Request-Leistung einfach länger als 20 ms. Dann 
bekommt es der Slave garantiert immer mit. Sobald er geantwortet hat, 
setzt der Master die Leitung wieder auf "Idle".

von Rainer V. (a_zip)


Lesenswert?

LostInMusic schrieb:
> Der Master hält
> den Pegel auf der Request-Leistung einfach länger als 20 ms.

Ja, danke, das hätte was, wenn es nur einen Slave gäbe...if you 
see...und ich schrieb auch schon, dass ich eine RS422-Halb-Duplex 
verwenden will.
Das Problem sind doch die völlig asynchronen Vorgänge! Und ich habe eben 
vorgegeben, dass ich nicht unendlich warten will, bis ich einmal alle 
Datensätze aufgesammelt habe.

c-hater schrieb:
> Das ergibt absolut keinen Sinn!

Lieber Freund...es ergibt einfach deshalb Sinn, weil ich es will! Du 
sitzt hier nicht in einem Meeting, wo du einfach sagst, ich bin 
raus...Dann antworte doch einfach nicht mehr. Das ist genauso wie "raus" 
und ich bin dir nicht böse...
Gruß Rainer

von c-hater (Gast)


Lesenswert?

Rainer V. schrieb:

> Lieber Freund...es ergibt einfach deshalb Sinn, weil ich es will!

Aha. Das trotzige Aufstampfen eines unverständigen Kindes.

Bei einem Kind ist das zumindest verständlich, das weiß es einfach noch 
nicht besser.

Du aber bist erwachsen. D.h.: man kann das nur so deuten: Stockedoof und 
stolz darauf. Jegliches Hinzulernen ausgeschlossen, weil garnicht 
gewollt...

> Dann antworte doch einfach nicht mehr.

Werde ich tun.

von LostInMusic (Gast)


Lesenswert?

>dass ich eine RS422-Halb-Duplex verwenden will.
>Das Problem sind doch die völlig asynchronen Vorgänge!

Auch mit diesen Infos bleibt für mich im Dunkeln, wo der Kern Deines 
Problems liegt. Ist es so schwer, das einfach mal mit ein paar 
lupenreinen, verständlichen Sätzen auf den Punkt zu bringen? Es wäre 
wirklich hilfreich (für Dich!). Was muss der Master können? Was können 
die Slaves schon und was sollen sie noch können müssen? Was ist 
festgelegt und was kannst Du ändern? Welchen Randbedingungen unterliegt 
das ganze System? Du solltest vielleicht auch nicht davon ausgehen, dass 
jeder mit RS422-Halb-Duplex vertraut ist.

Bevor das alles nicht geklärt ist, ist jede weitere Diskussion nur 
Stochern im Nebel.

von Einer K. (Gast)


Lesenswert?

LostInMusic schrieb:
> Ist es so schwer, das einfach mal mit ein paar
> lupenreinen, verständlichen Sätzen auf den Punkt zu bringen?
Offensichtlich ja.
Aber vermutlich sind die geheimen Module so geheim, dass die Welt ins 
wanken gerät, wenn wir was darüber erfahren würden.

> RS422-Halb-Duplex
Alleine das ist schon unüberlegt, würde ich mal vermuten....
Denn die RS422 Spezifikation gibt das nicht her.

LostInMusic schrieb:
> Du solltest vielleicht auch nicht davon ausgehen, dass
> jeder mit RS422-Halb-Duplex vertraut ist.
OK, vielleicht bin ich auch nur nicht damit vertraut.
Denn bisher dachte ich, dass genau das der Kern Unterschied zu RS485 
ist, da dieses eine Kollision locker weg steckt.

> Arduino-Minis, die "nur" 4MHz Quarz haben.
Als eingewiesene Arduino Fachkraft, mit fundiertem Halbwissen, kenne ich 
nur 16MHz und 8MHz Arduino Minis.
Aber Wunder gibts ja immer wieder....

von Theor (Gast)


Lesenswert?

Interessant wäre ja auch mal, zu erfahren, was das für ein 
geheimnisvoller Sensor ist, der es nötig macht, zur Kommunikation 20ms 
lang mit ihm, in einem Zeitraster von 1/(4 MHz) = 250 ns zu reagieren.

Ich hänge mich jetzt mal aus dem Fenster:

Ich halte es eher für unwahrscheinlich , dass das nötig ist.

Wahrscheinlicher wird man auf Flanken oder die Zeitdauer zwischen 
Flanken reagieren müssen. Das ist etwas ganz Anderes. Dazwischen tippt 
der AVR noch bei den Affen am monumentalen Weltbestseller mit und 
langweilt sich dabei.

Bei mal so geratenen 8 Bit Sensordaten sind das immer noch so 5.000 (in 
Worten Fünftausend) Befehle zwischen jedem Bit). Seien es 32 Bit, so 
ergeben sich immer noch 1250 Befehle. Das ist reichlich .

Ob meine Vermutungen so richtig sind, mag der TO vielleicht bestätigen 
oder bestreiten. Aber bitte mit Fakten, d.h. mit Angabe von Typ und Link 
zum Datenblatt des Sensors.


Falls da nichts kommt, warten wir dann mal auf den "Spezialisten" mit 
dem Zauberstab. Der wird das alles ohne Informationen klären. Einfach 
weil er Spezialist ist. Chuck Norris, z.B. erledigt solche Sachen 
einfach durch Muskelkraft und ein böses Gesicht. :-)

Beitrag #6410218 wurde vom Autor gelöscht.
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Theor schrieb:
> warten wir dann mal auf den "Spezialisten" mit dem Zauberstab.

https://www.youtube.com/watch?v=BKorP55Aqvg

X: "What keeps you from doing it?"
E: "Geometry."
X: "Then just ignore it!"

Einfach unübertroffen.

: Bearbeitet durch User
von Maxe (Gast)


Lesenswert?

Rainer V. schrieb:
> Wenn während einer laufenden Interrupt-Routine
> weitere Interrupts auftreten, dann werden die aber nicht verworfen,
> sondern offensichtlich gespeichert.
Es muss dir aber klar sein, dass nur der Interrupt selbst "gespeichert" 
wird, und nicht die Zustände, die dazu führen.
D.h. wenn zwei Slaves gleichzeitig serielle Daten auf die gleiche 
Schnittstelle schicken und das zu zwei Interrupts führt (muss nicht), 
sind die Daten trotzdem kaputt, ohne dass du es notwendigerweise 
bemerkst.

von Veit D. (devil-elec)


Lesenswert?

Hallo Rainer,

mal ehrlich, die letzten Infos hättest du schon früher bringen können. 
Das musst du einsehen.

Deine Info ist. Du hast 5 Slaves, wo jeder Slave zu x beliebigen 
Zeitpunkt für 20ms auf keine serielle Anfrage reagiert. Das wiederholt 
sich pro Slave aller einer Sekunden. Du möchtest innerhalb von 2s alle 
Slave abgefragt haben.

Jetzt überlegen wir einmal. Der Worst-Case ist wenn jeder Slave genau 
dann mit seiner 20ms Blockierung beginnt wenn du diesen abfragen 
möchtest. Das heißt du verlierst insgesamt mindestens 100ms. Wenn sich 
das aller 1s wiederholt, hast max. 900ms Zeit für die gesamte 
Kommunikation mit allen. An der Stelle wäre es wichtig zu wissen mit 
welcher Baudrate du kommunizierst und wieviele Bytes übertragen werden 
müssen. Dafür ist ein definiertes Übertragungsprotokoll wichtig zu 
kennen bzw. aufzustellen. Es könnte ja sein du überträgst massig Daten 
wofür 900ms nicht ausreichen. Soviel zum Thema fehlende Informationen. 
Das solltest du dir nochmal genau überlegen. Oder du musst dann allein 
weitermachen.

Ich mach mal weiter. Wenn der Master mit einem angenommenen Timeout von 
5ms seine Anfrage wiederholt, verlierst du im Worst Case maximal 5ms, 
wenn die letzte Anfrage auf das Ende der 20ms ISR Blockade trifft. Das 
heißt 5 Slaves mal 25ms Totzeit = 125ms. Restzeit 875ms.

Das heißt weiter du hast 875ms / 5 = 175ms Zeit für die zur 
Kommunikation pro Slave.

Jetzt bist du dran. Wieviele Bytes überträgst du und welche Baudrate ist 
dafür notwendig damit du noch Luft hast und nicht auf Kante nähst. Wenn 
es eng wird kannste noch mit dem Timeout von 5ms runtergehen. Mit den 
Zahlen bzw. Überlegung musste jetzt rumspielen.

Wenn das klar ist, fängste an mit definierten Protokoll eine 
Kommunikation zu programmieren. Anfrage senden und auf Antwort warten 
ggf. Anfrage wiederholen. Da haste schon einmal zu tun.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

c-hater schrieb:
> Man muss einfach nur wissen, was man tut. Du weißt das definitiv immer
> noch nicht (nach so vielen Jahren: schändlich, weil nix dazu gelernt)!

c-hater schrieb:
> Takte. Ein gelernter Assemblerprogrammierer kann in 190 Takten eine
> Menge Zeug tun...
>
> Du nicht!

 Du auch nicht.

 Wenn so eine Aussage von jemandem kommt, der nicht mal weiss welche
 Register beim AVR als Paare bezeichnet werden...
 Wenn ich mich richtig erinnere waren für dich r25/r26 ein Register-
 paar...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Rainer V. schrieb:
> Selbst wenn ich die Zeit, in der alle Slaves ihre Daten übermittelt
> haben müssen, auf 2s lege, muß ich doch quasi 6 asynchrone Ereignisse,
> die sich alle irgendwie blockieren können, in dieser Zeit "geschafft"
> haben. Muß mangels Hardware jetzt noch mal genauer in das Timing des

 Dann mach doch mal einen Round-robin System.
 Master sendet alle 2 Sekunden eine Nachricht mit Adresse 0xFF - (an
 alle Slaven) mit Masterzeit (Sekunden und milisekunden) und dazu 1
 zusätzlicher Byte, wo jedes gesetztes bit bedeutet, daß in den letzten
 2 Sekunden eine Nachricht von diesem Slave empfangen wurde.
 Jeder Slave hat seine Timeslice, in welcher er eine neue Nachricht
 rausschickt oder die letzte wiederholt, falls seine vorherige Nachricht
 nicht empfangen, d.h. sein bit nicht gesetzt wurde.

 Slave 1 hat nun 200ms Zeit, von 1-200, Slave 2 hat Zeit von 201-400,
 Slave 3 von 401-599ms etc.
 Und wenn es 2 Sekunden sind, hat Slave 1 noch einmal die Möglichkeit
 von 1001-1200 die Nachricht zu wiederholen, wenn es aus irgendeinem
 Grund vorher nicht geklappt hat, Slave 2 hat diese Möglichkeit von
 1201-1400, Slave 3 von 1401-1600 etc.

 Punkt ist:
 Selbst wenn ein Slave nicht sofort antworten kann, hat er doch die
 Synchron Nachricht erhalten (hoffentlich geschieht der Empfang per ISR)
 und kann seine TimeSlice ausrechnen und entsprechend antworten.
 Die blockierende Routine dauert max. 20ms, dementsprechend ist es
 überhaupt kein Problem seine Antwort in diesen 200ms zu senden.

von c-hater (Gast)


Lesenswert?

Marc V. schrieb:

>  Du auch nicht.

Ich denke schon. Vermutlich denkt das auch jeder andere kompetente 
Mitleser, was deinen Kompetenzstatus zumindest etwas "anrüchig" macht...

Dazu kommt, dass ich mindestens zwei nichttriviale Asm-Projekte 
veröffentlicht habe, du hingegen exakt 0...

>  Wenn so eine Aussage von jemandem kommt, der nicht mal weiss welche
>  Register beim AVR als Paare bezeichnet werden...

Im Prinzip kann ich jede Sammlung von zwei Registern als Paar 
bezeichnen, denn das primäre Kennzeichen eines Paars ist EINZIG, dass 
es aus zwei Elementen besteht.

Aber natürlich macht es es beim AVR8 Sinn, bevorzugt Register zu Paaren 
zusammen zu fassen, die erstens im Registerfile aufeinander folgen und 
von denen zweitens das Register mit dem geringeren Index einen 
"even"-Index hat. Das sind dann spezielle Registerpaare, die besondere 
Eigenschaften besitzen.
Insbesondere natürlich die, dass sie sich anderen dieser besonderen 
Paare mittels movw innert eines Taktes zuweisen lassen. Wie du dich 
leicht überzeugen kannst, nutze ich dieses Feature in meinem Programmen 
ziemlich intensiv...
Einige dieser Paare haben darüber hinaus noch weitere besondere 
Eigenschaften. Auch das nutze ich natürlich, denn das geht ja kaum 
anders, wenn man mit indizierte Adressierung operiert...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

c-hater schrieb:
> Dazu kommt, dass ich mindestens zwei nichttriviale Asm-Projekte
> veröffentlicht habe, du hingegen exakt 0...

 Bitte ein link auf entsprechende Beiträge...

> Im Prinzip kann ich jede Sammlung von zwei Registern als Paar
> bezeichnen, denn das primäre Kennzeichen eines Paars ist EINZIG, dass
> es aus zwei Elementen besteht.

 Sicher.
 Dann benutzt du auch SREG und r3 als ein Paar?

> Insbesondere natürlich die, dass sie sich anderen dieser besonderen
> Paare mittels movw innert eines Taktes zuweisen lassen.

 Sicher.
 Wie z.B. r25/r26?

> Wie du dich
> leicht überzeugen kannst, nutze ich dieses Feature in meinem Programmen
> ziemlich intensiv...

 Naja.
 Deine Programme habe ich zwar noch nie gesehen, aber wenn du es
 behauptest...
 BTW bei Copy&Paste kann man auch schwer derartige Fehler machen...

von c-hater (Gast)


Lesenswert?

Marc V. schrieb:

>  Dann benutzt du auch SREG und r3 als ein Paar?

SREG ist kein MCU-Register, sondern SFIO. Es macht wohl eher selten 
Sinn, ein spezialisiertes SFIO zusammen mit einem MCU-Register als Paar 
zu verwenden. Aber sogar sowas könnte vorkommen. Z.B. 
TCNTirgendwas+Zählererweiterung in einem MCU-Register.

> Bitte ein link auf entsprechende Beiträge...

Suche in "Projekt & Code" nach "ATtiny85". Die Suche liefert recht 
wenige Ergbnisse. Zwei davon sind von mir.

Und, bevor du fragst: ja, ich verwende durchaus auch andere AVR8... 
Veröffentlicht habe ich nur die Buddelschiffe. Sachen, die erstens reine 
Spielereien sind (also insbesondere nicht die Interessen meines 
Brötchengebers tangieren), und die zweitens zeigen, was selbst auf kaum 
wahrnehmbaren µC geht, wenn ihnen direkt in der Sprache was beibringt, 
die sie wirklich verstehen...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

c-hater schrieb:
>> Bitte ein link auf entsprechende Beiträge...
>
> Suche in "Projekt & Code" nach "ATtiny85". Die Suche liefert recht
> wenige Ergbnisse. Zwei davon sind von mir.

 Nööö, selber suchen, link senden.
 Ein Beitrag von dir, (Audio Spektrum Analyzer mit ATtiny85) habe
 ich zwar gefunden, aber nachdem ich disassembliertes .HEX File gesehen
 habe, behaupte ich, daß es ein abgeschriebenes Programm (wahrscheinlich
 in BASIC) ist, mehr als BASIC hast du bestimmt nicht gelernt...

 Beispiel:
1
         sub  r0, r0
2
         sub  r1, r1

 Lol.
 So macht das nur der compiler, jemand der selber in Assembler
 schreibt und Ahnung hat, benutzt hier wahrscheinlich:
1
         clr   r0
2
         clr   r1

 P.S.
 An deiner Stelle wurde ich schnellstens aufhören andere Leute
 anzuspucken und ständig etwas von Copy&Paste zu plappern...

: Bearbeitet durch User
von leo (Gast)


Lesenswert?

Marc V. schrieb:
> und Ahnung hat, benutzt hier wahrscheinlich:
> clr   r0

... was EOR r0,r0 entspricht. Also nur langsam schreiben.

leo

von Joachim B. (jar)


Lesenswert?

Marc V. schrieb:
> sub  r0, r0

ist aber nicht

Marc V. schrieb:
> clr   r0

da darf es doch Unterschiede geben und wer sich auskennt nutzt auch mal 
miese Tricks wenn die Takte bekannt sind und auch erst Recht gewünscht 
sind.
Man könnte ja auch ein NOP einfügen, ist aber ein Befehl mehr, nur das 
muss man halt wissen ob der eine Befehl noch reinpasst oder das 
gewünschte Ergebnis in clocks bringt!

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

leo schrieb:
> ... was EOR r0,r0 entspricht.

 Was ja auch in DaBla steht:
1
Operation:
2
(i) Rd ← Rd ⊕ Rd

> Also nur langsam schreiben.

 Du und andere "Experten" auch...

von Einer K. (Gast)


Lesenswert?

Marc V. schrieb:
> So macht das nur der compiler, jemand der selber in Assembler
>  schreibt und Ahnung hat, benutzt hier wahrscheinlich:
>  clr   r0
>  clr   r1

clr ist kein AVR ASM Statement, sondern ein Pseudobefehl des Assemblers
Codeidentisch mit
eor  r0, r0
eor  r1, r1

Zudem werden andere Flags gesetzt, als bei sub  r0, r0.
Es macht also schon einen Unterschied.
Du vergleichst Äpfel mit Birnen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Joachim B. schrieb:
> da darf es doch Unterschiede geben und wer sich auskennt nutzt auch mal

 Ja.
 Nur gibt es hier keine Unterschiede, ausser in bestimmten Flags aber da
 es sich nur um einen Register handelt, kann es diese Unterschiede
 nicht geben.

> Man könnte ja auch ein NOP einfügen, ist aber ein Befehl mehr, nur das

 Man könnte ja auch zehn NOPs einfügen, nur wozu?

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Arduino Fanboy D. schrieb:
> Zudem werden andere Flags gesetzt, als bei sub  r0, r0.
> Es macht also schon einen Unterschied.
> Du vergleichst Äpfel mit Birnen.

 Ausser Zero-Flag wird kein anderer Flag gesetzt.
 Und nochmal für dich, da du ja auch ein "Experte" zu sein scheinst:
 Bei sub r0, r0 macht es keinen Unterschied, da ausser Zero-Flag kein
 anderer Flag gesetzt wird, es werden aber ein paar zurückgesetzt, die
 aber im weiterem Verlauf des kopierten Programms gar nicht gebraucht
 werden.
 Um das zu verstehen, muss man aber Assembler können, was bei dir
 offensichtlich nicht der Fall ist...

 P.S.
 Disassembler übersetzen CLR immer mit EOR r,r aber sub rx, rx
 zweimal hintereinander benutzen nur compiler.

: Bearbeitet durch User
von Sklavenhalter (Gast)


Lesenswert?

Beim RS485/422 Konzept geht es am Einfachsten ohne irgendwelche 
Umständen bei der Slave Programmierung mit einem adressierbaren 
Master/Slave Konzept. Jeder Sklave muß absolut die Schnauze halten bis 
er ein auf ihn bezogene Adressierung erhält. Dann braucht der Master nur 
der Reihe nach die Sklaven ansprechen. Dann gibt es keine Kollisionen. 
Alle anderen Sklaven halten sich stillschweigend zurück.

So machten wir es in der Vergangenheit in einem älteren industriellen 
System. Das hat über Dekaden sehr zuverlässig funktioniert. Alle 
Datenaustausche sind mit CRC16 abgesichert. Wenn aus irgendeinen Grund 
der adressierte Sklave nicht antwortet, dann weiß sich der Master mit 
Retry oder anderen hier vorgesehenen Ausweichstrategien zu helfen.

Was bei RS485 ganz wichtig ist die Sklaven mit einem zuverläßigen 
Watchdog/HW Schutz auszustatten damit der Bus durch einen abgestürzten 
Sklaven nicht möglicherweise blockiert werden kann. Z.B kann man mit 
einem HW One-Shot Timer bei der Sklavensendesteuerung verhindern, daß 
der Bus durch ein Versagen des uC blockiert wird. Für den 
Nicht-industriellen Einsatz ist dies in vielen Fällen vollkommen 
ausreichend.

Jedenfalls sind bei den Sklaven bei der Programmierung sonst keine 
besonderen Timing Rücksichten oder komplizierte Protokolle notwendig. 
Bei Hobbyanwendungen ist dieses Konzept auf alle Fälle zuverlässig 
genug. Die bisherigen Erfahrungen bewiesen das.

Wer besonders hohe Zuverlässigkeit braucht oder Service Requests von den 
Sklaven muß eben auf andere Möglichkeiten wie z.B. CAN, ARINC oder 
andere komplizierte industrielle Protokolle und Busse zurückgreifen. Für 
den Hausgebrauch kann man oft mit den hier vorgeschlagenem bescheidernen 
Konzepten auskommen.

von Einer K. (Gast)


Lesenswert?

Marc V. schrieb:
> Um das zu verstehen, muss man aber Assembler können, was bei dir
>  offensichtlich nicht der Fall ist...
Mangelhafte Auffassungsgabe mit Angriffen kompensieren zu wollen...
Armselig.

Vielleicht bin ich ja wirklich nicht der Oberheld in Sachen ASM.
Aber deinen Ausführungen kann ich entnehmen, dass es dicke reicht dich 
mehrfach zu übertrumpfen.

Du hast mein volles Mitleid.

von Joachim B. (jar)


Lesenswert?

Marc V. schrieb:
> Man könnte ja auch zehn NOPs einfügen, nur wozu?

hat man früher mal für ein exaktes Timing gemacht, als RAM und ROM noch 
Mangelware war!

Arduino Fanboy D. schrieb:
> clr ist kein AVR ASM Statement

guter Hinweis, ich bin darauf reingefallen, aber meine ASM Kenntnisse 
sind alt und nicht beim AVR speziell vorhanden!

Marc V. schrieb:
> Disassembler übersetzen CLR immer mit EOR r,r aber sub rx, rx
>  zweimal hintereinander benutzen nur compiler.

so langsam scheint mir hier reden einige von popobacken und andere von 
kuchenbacken.

Keine Ahnung wer sich hier nun selber outet, ausser ich :)

wie gesagt ich habe von AVR ASM keine große Ahnung, nur rudimentär das 
es ld lda oder sowas gibt!

interessant bleibt das einer schreibt es gibt keinen ASM clr, ich denke 
ja auch register werden gelöscht in dem 0 reingeschrieben wird, aber mit 
sich selber subtrahiert ist schon "komisch"

andererseits

Marc V. schrieb:
> sub rx, rx
>  zweimal hintereinander

ist mindestens genauso komisch

Beitrag #6411392 wurde vom Autor gelöscht.
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Marc V. schrieb:
>          sub  r0, r0
>  So macht das nur der compiler,

Also avr-gcc generiert solchen Code schon mal nicht, und in der libgcc 
(asm) gibt's sowas auch nicht.

>  schreibt und Ahnung hat, benutzt hier wahrscheinlich:
>          clr   r0

Das setzt andere Flags (Z), SUB hingegen setzt alles an Arithmetik-Flags 
(alle außer I und T).

von c-hater (Gast)


Lesenswert?

Marc V. schrieb:

>  habe, behaupte ich, daß es ein abgeschriebenes Programm (wahrscheinlich
>  in BASIC) ist, mehr als BASIC hast du bestimmt nicht gelernt...

Das sind gleich zwei ziemlich verwegene Behauptungen. Du kannst sie 
hoffentlich mit irgendwelchen Beweisen untermauern.

>  Beispiel:
>
1
>          sub  r0, r0
2
>          sub  r1, r1
3
>

Ja, das kommt sogar mehrfach vor. Immer da, wo ich mein size-optimiertes 
MUL8x8-Macro benutzt habe (was ich auch schonmal irgendwo hier 
veröffentlicht habe). OK, das erste sub müßte an dieser Stelle nicht 
sein, sondern könnte genausogut z.B. ein xor r0,r0 (AKA: clr R0) sein, 
das zweite hingegen ist für den Rest der Routine essentiell wichtig. Sie 
würde nicht korrekt funktionieren können, wenn das nicht mit sub gelöst 
worden wäre.

Du unsäglicher nixwissender aber nichtsdestotrotz überaus arroganter 
Blindflansch bist einfach nur viel zu doof, den Kontext zu kapieren...

von Marc V. (Firma: Vescomp) (logarithmus)


Angehängte Dateien:

Lesenswert?

Arduino Fanboy D. schrieb:
> Aber deinen Ausführungen kann ich entnehmen, dass es dicke reicht dich
> mehrfach zu übertrumpfen.
>
> Du hast mein volles Mitleid.

 Lol.
 Weil du keine Ahnung hast.

 Für solche, die doch Ahnung haben ist ein File angehängt in welchem
 nebeneinander zwei völlig identische Teie des Codes auf zwei
 verschiedenen Adressen stehen.

c-hater schrieb:
> Du unsäglicher nixwissender aber nichtsdestotrotz überaus arroganter
> Blindflansch bist einfach nur viel zu doof, den Kontext zu kapieren...

 Wenn das excellente programmierkenntnisse sind, dann habe ich wirklich
 keine Ahnung...

 Link:
Beitrag "Re: Audio Spektrum Analyzer mit ATtiny85"

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Johann L. schrieb:
> Marc V. schrieb:
>>          sub  r0, r0
>>  So macht das nur der compiler,
>
> Also avr-gcc generiert solchen Code schon mal nicht, und in der libgcc
> (asm) gibt's sowas auch nicht.

Anmerkung: In der avr-libgcc gibt es vergleichbaren Code, aber nicht den 
gleichen :-)  Zum Beispiel in __udivmodhi4 und __udivmodsi4

     SUB r26, r26
     SUB r27, r27

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Marc V. schrieb:
> ist ein File angehängt in welchem nebeneinander zwei völlig
> identische Teie des Codes auf zwei verschiedenen Adressen stehen.

Sowas machen auch doofe Compiler wenn sie optimieren, z.B. bei Inlining 
oder Loop Unrolling.  Insbesondere bei Optimierung auf Geschwindigkeit.

von c-hater (Gast)


Lesenswert?

Marc V. schrieb:

>  Für solche, die doch Ahnung haben ist ein File angehängt in welchem
>  nebeneinander zwei völlig identische Teie des Codes auf zwei
>  verschiedenen Adressen stehen.

Das passiert bei der Verwendung von Macros schon mal und ist überaus 
sinnvoll, wenn auf Peformance optimiert wird. Denn es spart den 
vergleichweise teuren Callframe...

Macht ein richtig guter C-Compiler übrigens ganz genauso...

von Einer K. (Gast)


Lesenswert?

c-hater schrieb:
> Macht ein richtig guter C-Compiler übrigens ganz genauso...
Ach, mach dir keinen Kopp darum....
Mich ist der  Marc V. vor einiger Zeit genauso verbohrt angegangen.
Da war es ihm wichtig, zu behaupten, dass I2C Adressen 8 Bit haben.
Ihm wollte das R/W Bit der Adresse zurechnen.
Hinweise auf irgendwelche Datenblätter und die I2C Spezifikation waren 
ihm komplett egal.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Johann L. schrieb:
> Marc V. schrieb:
>> ist ein File angehängt in welchem nebeneinander zwei völlig
>> identische Teie des Codes auf zwei verschiedenen Adressen stehen.
>
> Sowas machen auch doofe Compiler wenn sie optimieren, z.B. bei Inlining
> oder Loop Unrolling.  Insbesondere bei Optimierung auf Geschwindigkeit.

 Stimmt.
 Nur bei soviel code wie oben fällt ein rcall+ret (7 Takte) kaum ins
 Gewicht.
 Aber 166 zusätzliche Bytes schon...

c-hater schrieb:
> Das passiert bei der Verwendung von Macros schon mal und ist überaus
> sinnvoll, wenn auf Peformance optimiert wird. Denn es spart den
> vergleichweise teuren Callframe...

 Ja, 7 Takte und 0,875us (bei 8MHz Tiny) einsparen aber 166 Bytes
 verschwenden - einfach genial...

> Macht ein richtig guter C-Compiler übrigens ganz genauso...

 Dachte, du hast das selber in ASM geschrieben?
 Wenn es C-Compiler genauso machen, wo hast du dann deine genialen
 Kenntnise in Assembler benutzt und wozu?

von c-hater (Gast)


Lesenswert?

Marc V. schrieb:

>  Nur gibt es hier keine Unterschiede, ausser in bestimmten Flags

Ja genau...

Mehr oder weniger zufällig ist nun gerade bei dieser Routine der Zustand 
des carryflags für den weiteren Fortgang der Sache relevant. Und der 
Sinn der Anwendung der sub-Instruktion ist hier halt, in einem Takt 
sowohl das Register zu clearen als auch das Carry-Flag zu löschen.

An solchen "Tricks" erkennt man gelernte Assembler-Programmierer. (Naja: 
auch gute Codegeneratoren von Compilern, denn auch die werden letztlich 
natürlich auch von guten Assemblerprogrammierern verfasst...)

Du bist auf jeden Fall absoluter Nullwisser-Arsch. Und du scheinst auch 
nicht dazulernen zu wollen.

Übrigens: hattest du mal ein Alias "Ossifant"? Würde ziemlich gut 
passen...

Naja, du wirst es natürlich abstreiten, die Moderatoren könnten es wohl 
rausfinden, werden ihre Erkenntnisse aber keinesfalls veröffentlichen.

Egal, soll sich jeder Leser sein eigenes Bild machen...

von c-hater (Gast)


Lesenswert?

Marc V. schrieb:

>  Stimmt.
>  Nur bei soviel code wie oben fällt ein rcall+ret (7 Takte) kaum ins
>  Gewicht.

Der Nutzcode des MUL8X8-Macros hat 40 Takte. 7 Takte mehr für einen 
Callframe bedeutet einen Overhead von 7*100/40=17,6%.

Du dummer Blindflansch kannst nichtmal trivialste Mathematik. Du bist so 
prasseldumm, dass es einen Hund jammert...

>  Ja, 7 Takte und 0,875us (bei 8MHz Tiny) einsparen aber 166 Bytes
>  verschwenden - einfach genial...

Die Lösung funktioniert insgesamt auch deshalb, weil ich Size- und 
Performance-Optimierung weise gemischt habe. Das ist, wozu ein 
C-Compiler heute leider noch nicht selbstständig fähig ist. Bestenfalls 
kann man ein wenig nachhelfen. Bezüglich der (sehr trivialen) Mathematik 
in dem Programm könnte ich dem GCC das schon relativ problemlos 
beibiegen. Aber der Rest ist Sackstand. Letztlich liefe es darauf 
hinaus, das halbe Programm doch wieder in Asm zu schreiben (mit der 
unsäglich grottigen gcc-Inkarnation dieser eigentlich einfachen, 
übersichtlichen und schönen Sprache). Und dann am Ende immer noch nicht 
so effizient zu sein, wie mein natives Asm-Programm...

>  Dachte, du hast das selber in ASM geschrieben?

Habe ich.

>  Wenn es C-Compiler genauso machen

Sie versuchen es. Mit eher mäßigem Erfolg...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

c-hater schrieb:
> des carryflags für den weiteren Fortgang der Sache relevant. Und der
> Sinn der Anwendung der sub-Instruktion ist hier halt, in einem Takt
> sowohl das Register zu clearen als auch das Carry-Flag zu löschen.

 Aha.
 Gleich zweimal hintereinander, wie es auch zufälligerweise Compiler
 tun?

> Du bist auf jeden Fall absoluter Nullwisser-Arsch. Und du scheinst auch
> nicht dazulernen zu wollen.

 Wenn Argumente nicht vorhanden sind, kommen Beleidigungen...
 Und wenn du behauptest, diesen armseligen Stück (abgeschriebenen Code)
 selbst in Assembler geschrieben zu haben, dann hast du entweder keine
 Ahnung von programmieren oder du hältst alle anderen für Idioten.

> An solchen "Tricks" erkennt man gelernte Assembler-Programmierer.

 An welchen Tricks?
 166 Bytes bei 8KB verschwenden?
 Hör auf, unnötig einen noch grösseren Idioten als du schon bist aus dir
 zu machen.

> Übrigens: hattest du mal ein Alias "Ossifant"? Würde ziemlich gut
> passen...

 Nein, natürlich nicht.
 Auch melde ich mich nicht als Gast an, wie es einige hier tun...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

c-hater schrieb:
> Der Nutzcode des MUL8X8-Macros hat 40 Takte. 7 Takte mehr für einen
> Callframe bedeutet einen Overhead von 7*100/40=17,6%.
>
> Du dummer Blindflansch kannst nichtmal trivialste Mathematik. Du bist so
> prasseldumm, dass es einen Hund jammert...

 Wie ich schon sagte, hör auf, unnötig einen noch grösseren Idioten als
 du schon bist aus dir zu machen.
 Wie willst du 83 Befehle in 40 Takte packen?
 Du bist ganz einfach ein Idiot der nicht mal rechnen kann.

von Verwirrter Gast (Gast)


Lesenswert?

>Auch melde ich mich nicht als Gast an

Was? Das geht?

von c-hater (Gast)


Lesenswert?

Marc V. schrieb:

>  Wie willst du 83 Befehle in 40 Takte packen?

Woher nimmst du die 83 Befehle?

Das MUL8X8-Macro umfaßt jedenfalls nur 40 Takte.

von c-hater (Gast)


Lesenswert?

Marc V. schrieb:

>  Gleich zweimal hintereinander, wie es auch zufälligerweise Compiler
>  tun?

Die tun es vermutlich aus demselben Grund aus dem ich es getan habe: 
Sieht hübscher aus. Sprich: der Verfasser des Codegenerators (zumindest 
des hier relevanten Teils davon) hat wohl ähnliche Schönheitsideale wie 
ich.

Und nein, Ossifant, du kriegst den Quelltext nicht. Weil du dermaßen 
prasseldoof und gleichzeitig unerträglich arogant bist. Wenn du nämlich 
wenigstens einigermaßen clever wärst (also wenigstens einen gewissen 
substantiellen Grund für die Arroganz hättest), hättest du das längst 
aus dem VB.net-Code extrahieren können. Da ist nämlich eine 
Quasi-1:1-Umsetzung des Asm-Codes für den Tiny in VB.net enthalten. Der 
im Thread erwähnte "Simulator", mit dessen Hilfe die hübschen bunten 
Grafiken aus dem Thread in akzeptabler Zeit produziert werden konnten...

Wenn VB.net nicht dein Ding ist: das .net-Zeug ist naturgemäß CLI-Code, 
du kannst dir das also auch problemlos in der C#-Entsprechung ausgeben 
lassen. Oder kannst du auch das nicht? Kannst du überhaupt 
irgendetwas?

Außer inkompetent rumzulabern? Das kannst du immerhin ganz gut...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

c-hater schrieb:
> Woher nimmst du die 83 Befehle?

 Glaube zwar nicht, daß du da etwas verstehen wirst, aber hier:
Beitrag "Re: Verständnis AVR Interrupts"

c-hater schrieb:
> Und nein, Ossifant, du kriegst den Quelltext nicht.

 Man, sowas nennt sich Paranoia - schon mal nach Hilfe gesucht?

> Wenn VB.net nicht dein Ding ist:

 Nein, ist es nicht, aber wir sind uns wenigstens in einem einig:
 Weiter als Basic bist du nicht gekommen.

> Außer inkompetent rumzulabern? Das kannst du immerhin ganz gut...

 Und kannst du etwas anderes außer beleidigen und Fragen ausweichen?

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Arduino Fanboy D. schrieb:
> Ach, mach dir keinen Kopp darum....
> Mich ist der  Marc V. vor einiger Zeit genauso verbohrt angegangen.
> Da war es ihm wichtig, zu behaupten, dass I2C Adressen 8 Bit haben.

 Lügen auch noch?
 Ich habe nie behauptet, daß die Adresse 8 bit hat - nur daß es die
 oberen 7 bits sind.
 Ich habe aber behauptet, daß es deswegen Blödsinn ist, jedesmal die
 Adresse rumzuschieben und dann noch mit R/W bit zu OR-en, anstatt am
 Anfang eine Adresse für schreiben und eine fürs lesen zu definieren
 - und das wars dann.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Marc V. schrieb:
> c-hater schrieb:
>> Sinn der Anwendung der sub-Instruktion ist hier halt, in einem Takt
>> sowohl das Register zu clearen als auch das Carry-Flag zu löschen.
>
>  Gleich zweimal hintereinander, wie es auch zufälligerweise Compiler
>  tun?

Der obige asm-Code mit den beiden SUBs aus der avr-libgcc ist nicht vom 
Compiler sondern von Chertykov soweit ich weiß.  avr-gcc selbst 
generiert sowas nicht.

c-hater schrieb:
> An solchen "Tricks" erkennt man gelernte Assembler-Programmierer.

Sowas überlegt man sich in 5 Sekunden selber wenn man's braucht. 
Peinlich, das überhaupt zu erwähnen...

von Einer K. (Gast)


Lesenswert?

Marc V. schrieb:
> Ich habe nie behauptet, daß die Adresse 8 bit hat
Ist klar...

Marc V. schrieb:
> Lügen auch noch?
Das überlasse ich lieber dir.


Klar, ist dir die Blamage von damals Höllen peinlich.
Habe ich volles Verständnis für.
Aber raus kommst du da nicht mehr.
Den Pranger hast du dir selber gesucht und dich selber dran gestellt.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Arduino Fanboy D. schrieb:
> Klar, ist dir die Blamage von damals Höllen peinlich.

 Welche Blamage, pathologischer Lügner?

> Habe ich volles Verständnis für.
> Aber raus kommst du da nicht mehr.
> Den Pranger hast du dir selber gesucht und dich selber dran gestellt.

 Geh zum c-hater und dann beide ganz schnell zum Psychiater.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Sehr geehrte Damen und Herren, freuen Sie sich auf die nächste Folge von 
"How to destroy a thread", die wir in Kürze ausstrahlen.

von 900ss (900ss)


Lesenswert?

Johann L. schrieb:
> die nächste Folge

Obwohl es sehr schwer wird, das zu toppen was hier abgeliefert wurde :)

von Hugo H. (hugohurtig1)


Lesenswert?

c-hater schrieb:
> Dazu kommt, dass ich mindestens zwei nichttriviale Asm-Projekte
> veröffentlicht habe

Genau genommen - eines. Das Andere kann man sich aus den Hex-Files / den 
.NET-Files decompilieren oder das veröffentlichte Decompilat (eines 
AVR-Hex-Files) als "Veröffentlichung" studieren :-).

Habe ich etwas übersehen?

: Bearbeitet durch User
von Rainer V. (a_zip)


Lesenswert?

Hallo und danke...besonders auch für die lustigen Beiträge...die 
Schnittstellenbausteine sind eingetroffen. Leider hakt das Programm für 
die Slaves noch etwas. Ich denke aber, dass ich morgen einen ersten Test 
mit Master und Slave laufen lassen kann. Werde dann weiter berichten.
Gruß Rainer

von allesKäse (Gast)


Lesenswert?

900ss D. schrieb:
> Johann L. schrieb:
>> die nächste Folge
>
> Obwohl es sehr schwer wird, das zu toppen was hier abgeliefert wurde :)

W.S. fehlt noch, dann ist das zu toppen!

von c-hater (Gast)


Lesenswert?

Johann L. schrieb:

> c-hater schrieb:
>> An solchen "Tricks" erkennt man gelernte Assembler-Programmierer.
>
> Sowas überlegt man sich in 5 Sekunden selber wenn man's braucht.
> Peinlich, das überhaupt zu erwähnen...

Tja, wenn man den Compilern das auch immer an passender Stelle 
einfallen würde. Tut es aber nicht!!!

Und diesen Sachverhalt zu erwähnen, ist mir kein bissel peinlich...

Du schuldest übrigens immer noch ein funktionierende und portable 
C-Umsetzung...

Nur diese könnte beweisen, das eine C-only-Implementierung mindestens so 
gut ist wie eine Implementierung durch einen fähigen Asm-Programmierer.

Kannst du nicht liefern. Weil ich natürlich die Projekte so angelegt 
habe, dass sie wirklich alles aus der verfügbaren Hardware rausholen 
(rausholen müssen).

Gib doch einfach zu, dass ein gelernter Asm-Programmierer bei jedem 
nichttrivialen Programm immer noch mindestens ein wenig besser sein kann 
als ein Compiler. Das tut doch nicht weh'. Schließlich ist es die 
objektive Wahrheit. Und ich bin absolut sicher, dass sie auch dir nur zu 
bewusst ist...

Paßt nur nicht zu deiner Bibel und deinen Bemühungen als Shepard...

Wobei mich eigentlich genau diese quasi-religiöse Grundeinstellung der 
C-Only-Apologeten überhaupt nur dazu bewogen hat, zu zeigen, dass sie 
mit vielen Aussagen schlicht und einfach LÜGEN.

Eien davon ist halt die: der Compiler wird's schon richten. Nein, tut er 
ganz offensichtlich nicht.

von c-hater (Gast)


Lesenswert?

Hugo H. schrieb:

> Genau genommen - eines. Das Andere kann man sich aus den Hex-Files / den
> .NET-Files decompilieren oder das veröffentlichte Decompilat (eines
> AVR-Hex-Files) als "Veröffentlichung" studieren :-).
>
> Habe ich etwas übersehen?

Ja. Das hätte anders laufen können, wenn da nicht der Ossifant und seine 
Mit-C-Hater-Hater ihre dumme nixwissende Fresse aufgerissen hätten...

Übrigens tut der Absenz des Quelltextes nicht wirklich was zur Sache, 
wenn ein Projekt als SingleUse-Projekt angelegt ist und schlicht in 
dieser Anwendung funktioniert...

Der Code kann genau nur das, was er können muss, er ist in keiner Form 
darauf vorbereitet mehr oder irgendwas anderes zu können. Genau genommen 
ist das Projekt sogar nur deswegen funktionsfähig, weil der Code so sehr 
auf das einzige Ziel des Projektes hin optimiert wurde.

Das steht aber eingentlich alles schon in dem Projekt-Thread. Manche 
Leute begreifen es aber scheinbar erst bei der dritten Wiederholung...

von Hugo H. (hugohurtig1)


Lesenswert?

c-hater schrieb:
> Das steht aber eingentlich alles schon in dem Projekt-Thread. Manche
> Leute begreifen es aber scheinbar erst bei der dritten Wiederholung...

Manche Leute labern von "Veröffentlichung" - belassen es aber beim 
Labern. Dann prahle doch einfach nicht mit etwas, was nicht real ist. 
Deine "Angriffe" kannst Du Dir sparen :-) - die kennt hier jeder.

Das Zitat ist ja irgendwie passend :-) :

c-hater schrieb:
> zu zeigen, dass sie
> mit vielen Aussagen schlicht und einfach LÜGEN.

: Bearbeitet durch User
von Rainer V. (a_zip)


Lesenswert?

So, jetzt ist's gut...wenn ich konkrete Fragen habe, mache ich einen 
neuen Faden auf...
Gruß Rainer

von c-hater (Gast)


Lesenswert?

Hugo H. schrieb:

> Manche Leute labern von "Veröffentlichung"

Tja. Es ist eine offensichtlich funktionierende Lösung veröffentlich 
worden. Sogar mit reichlich Zubehör, um sie mit geringem Aufwand an 
persönliche Wünsche anpassen zu können, solange die Fähigkeiten der 
Lösung dadurch nicht überschritten werden.

Wo genau kann man übrigens eigentlich deine Veröffentlichungen finden?

von Hugo H. (hugohurtig1)


Lesenswert?

c-hater schrieb:
> Wo genau kann man übrigens eigentlich deine Veröffentlichungen finden?

Nirgendwo - ich brüste mich aber auch nicht mit 
Pseudo-"Veröffentlichungen" von Lösungen :-)

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

c-hater schrieb:
> Du schuldest übrigens immer noch ein funktionierende und portable
> C-Umsetzung...

Ich schulde dir rein garnix.  Warum sollte ich irgendeines deiner 
Projekte neu schreiben?

> Nur diese könnte beweisen, das eine C-only-Implementierung mindestens so
> gut ist wie eine Implementierung durch einen fähigen Asm-Programmierer.

Du hast immer noch nicht verstanden, was ich schreibe.

von c-hater (Gast)


Lesenswert?

Johann L. schrieb:

> Du hast immer noch nicht verstanden, was ich schreibe.

Was schreibst du denn deiner Meinung nach? Gibt es ein Konzept dahinter, 
was ich nicht verstanden habe und auf das ich antworten sollte?

Was die (Nicht-)Fakten betrifft, die aus deinen Äußerungen zu entnehmen 
waren, habe ich wohl passend geantwortet.

So ist das halt mit den bösen Fakten, die können einem gefallen oder 
auch nicht... Wenn sie aber offensichtlich mit der eigenen Meinung 
kollidieren, sollte man vielleicht am Ende doch mal die eigene Meinung 
überdenken...

Jeder wissenschaftlich denkende Mensch würde das zumindest in Erwägung 
ziehen...

Du nicht. Du bist ganz offensichtlich unverbrüchlicher Axiomat. C ist 
gottgegeben und der Endpunkt und der Urgrund allen Seins.

So kenne ich sie, diese C-Apologeten. Ohne Trutz und Tadel, unbeirrbar 
und unbelehrbar bis in alle Ewigkeit... Amen...
Dabei wissen sie weit überwiegend einen Scheiß. Du kannst wenigstens 
noch die Sprache richtig, die meisten dieser Blinden Wichser können 
nichtmal die wirklich...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wie gesagt, du hast nicht verstanden, was ich schreibe.  Vielleicht hat 
du es auch einfach nicht gelesen.  Jedenfalls hab ich nichts 
geschrieben, von dem du da rumphantasierst.

: Bearbeitet durch User
von Maxe (Gast)


Lesenswert?

1. Gebot, diskutiere niemals mit einem Hater.

von c-hater (Gast)


Lesenswert?

Johann L. schrieb:

> Wie gesagt, du hast nicht verstanden, was ich schreibe.

Doch, was du lesbar geschrieben hast, habe ich sehr wohl verstanden und 
adäquat kommentiert.

Dein Problem ist scheinbar, dass du irgendwie glaubst, mehr 
geschrieben zu haben, als du tatsächlich geschrieben hast.

Und wohl irgendwie auf die Kommentierung dessen wartest, was nicht da 
steht...

Tja, Kommunikation ist irgendwie deutlich einfacher, wenn man alles 
schreibt, was man zu sagen hat...

von c-hater (Gast)


Lesenswert?

c-hater schrieb:

> Tja, Kommunikation ist irgendwie deutlich einfacher, wenn man alles
> schreibt, was man zu sagen hat...

Ergänzend:

Wenn deine Behinderung so weit reicht, dass du kein deutsch mehr kannst, 
darfst du es auch ein C schreiben. Ich werde es trotzdem verstehen...

Nur wenn garnix substantielles da steht, dann muß auch ich passen...

von Nanny (Gast)


Lesenswert?

Der Kindergarten hier grenzt ja schon an Realsatire....

von Rainer V. (a_zip)


Lesenswert?

Ganz klar Loriot...

von Toxic (Gast)


Angehängte Dateien:

Lesenswert?

Rainer V. schrieb:
> Und nun verstehe ich die Doc's (auch
> hier im ".net") nicht.

Bin jetzt nur zufaellig auf diesen Thread gestossen.Ich nehme an,dass du 
mittlerweile bei all den Postings hier schon zum Profi mutiert bist,aber 
vielleicht interessiert es den einen oder anderen  Newbie wie Interrupts 
verarbeitet werden.
Es ist zwar eine Arduinoabhandlung aber die basieren ja auf Atmel uCs...
Angehaengte Pdf anschauen und fuer gut befinden oder bei Nichtgefallen 
einfach loeschen...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

c-hater schrieb:
> Du schuldest übrigens immer noch ein funktionierende und portable
> C-Umsetzung...
>
> Nur diese könnte beweisen, das eine C-only-Implementierung mindestens so
> gut ist wie eine Implementierung durch einen fähigen Asm-Programmierer.

Das hatten wir schon vor Jahren. Damals behauptete Moby, seine 
Assembler-Programme wären mittels C bezgl. Größe, Funktionalität und 
Geschwindigkeit nicht zu schlagen.

Die ganze Diskussion mündete dann in eine Challenge, wo Yalu 
schlussendlich Mobys Assembler-Programm in C neu implementierte. Dieses 
hatte lediglich 158 Bytes Binärcode und schlug Mobys Assemblerprogramm 
von 206 Bytes um Längen. RAM-Verbrauch war derselbe, nämlich 2 Bytes.

Nachzulesen hier: 
Beitrag "Re: Assembler wieder auf dem Weg nach vorn"

P.S.
Moby hielt sich auch für den Assembler-Weltmeister, musste aber nach 
über 2000 Thread-Beiträgen eines besseren belehrt werden. Von daher wäre 
ich an Deiner Stelle mit solchen Aussagen ganz ganz vorsichtig.

von Hugo H. (hugohurtig1)


Lesenswert?

Frank M. schrieb:
> Die ganze Diskussion mündete dann in eine Challenge, wo Yalu
> schlussendlich Mobys Assembler-Programm in C neu implementierte. Dieses
> hatte lediglich 158 Bytes Binärcode und schlug Mobys Assemblerprogramm
> von 206 Bytes um Längen. RAM-Verbrauch war derselbe, nämlich 2 Bytes

Na ja, mit allen Tricks - z. B.:

// Hilfsmakros
#define REG(regno)  __asm__(#regno)
#define NAKED_IN_SECTION(sect) __attribute__((naked, section(sect)))

// GLobale Registervariablen
register uint8_t zero   REG( 1);  // GCC erwartet in R1 immer eine 0
register conv16  adcsum REG( 2);  // Summe von jeweils 8 ADC-Werten
register uint8_t chksum REG( 4);  // Pr³fsumme
register conv24  output REG(14);  // 24-Bit-Ausgabe
register uint8_t cycle  REG(17);  // Zõhler der 5ms-Zyklen

Welcher "normale" C-Programmierer kümmert sich darum?

Ich mag C-Hater nicht besonders (Moby kenne ich nicht) aber dann kann 
ich auch in Assembler (mit Makros) programmieren.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

c-hater schrieb:

* Ich bat dich, nicht immer wieder falsche Sachstände bzgl. avr-gcc / 
avr-g++ zu repetieren, die seit bereits 3 Compilerversionen und > 3 
Jahren behoben sind (konkret PR81268).

* Du antwortest darauf mit der Aufforderung, ich solle eines der 
Projekte aus deiner Asm Mottenkiste nachimplementieren, und behauptest 
ich schulde dir was.

Johann L. schrieb:
>
>> Falls du dich auf avr-gcc beziehst, das ist schon seit bereits 3
>> Compiler-Versionen nicht mehr so.  Soviel zu "Lernen".
>
> Ah ja. Deann setze enfach eines der beiden von mir veröffentlichen
> Anwendungen (zu finden in Projekte & Code) in C um, meinetwegen auch im
> topaktuellen avr-gcc. Es wird dir nicht gelingen.
>
> Erst, falls das doch der Fall wäre, gäbe es für mich etwas zu lernen...

Von dem kiloweise Weihrauch, den du dir täglich zur 
Selbstbeweihräucherung reinziehst, sind deine Hirnwindungen dermaßen 
verharzt, dass du garantiert nix mehr lernst.  Schon garnicht 
Textverständnis.  Oder eine Diskussion in der Sache zu führen — die 
übrigens in diesem Thread wie in 99.9% aller anderen Threads komplett 
Offtopic ist.

Von daher: Noch viel Spaß mit deinen Hasstiraden und den Stimmen in 
deinem Kopf, die wer weiß was für Implikationen und lächerliche 
Forderungen erfinden, nur um irgendwie zu deiner Mottenkiste zu führen 
um allen zeigen zu können, was für ein Toller Asm-Hecht du bist und in 
Aspekten besser abschneidest, als ein bestimmtes Computerprogramm.

von c-hater (Gast)


Lesenswert?

Johann L. schrieb:

> * Ich bat dich, nicht immer wieder falsche Sachstände bzgl. avr-gcc /
> avr-g++ zu repetieren, die seit bereits 3 Compilerversionen und > 3
> Jahren behoben sind (konkret PR81268).

Naja, wenn das alles so schick ist, sollte es ja kein Problem sein, den 
Westminster in C umzusetzen. Ich habe es jedenfalls nicht geschafft, 
ohne massive Ausflüchte nach Asm und in nichtportable Compilerfeatures 
unternehmen zu müssen.
D.h.: es ist viel, viel effizienter, das gleich in Assembler umzusetzen. 
Genau das habe ich getan.

Aber du könntest an diesem Beispiel doch echt mal die gnadenlose 
Überlegenheit von C und deinen überragenden Fähigkeiten als 
C-Programmierer gucken lassen. Indem du es hinreichend schnell und 
hinreichend klein für einen Tiny85, dabei aber trotzdem portabel 
umsetzt. Das wäre dann doch mal ein echter Hingucker...

Aber in einem Punkt hast du Recht: ein echte Schuld, das zu tun, besteht 
natürlich nicht. Wäre mehr so als eine Art Ehrenschuld anzusehen...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

c-hater schrieb:
> Aber du könntest an diesem Beispiel doch echt mal die gnadenlose
> Überlegenheit von C und deinen überragenden Fähigkeiten als
> C-Programmierer gucken lassen.

Drehen wir den Spieß doch mal um.

IRMP läuft mit ein- und demselben Quellcode auf vielen ATTinys, 
ATMegas, PICs, STM32, STM8, TI Stellaris, ESP8266, TEENSY MK20DX256VLH7, 
MBED LPC1347, MBED LPC4088 und anderen µCs.

Programmiere den mal in ASM nach. Dafür müsstest Du für jeden µC ein 
eigenes Assembler-Programm schreiben, eine absolut sinnlose Arbeit.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hugo H. schrieb:
> Na ja, mit allen Tricks - z. B.:
>
> // Hilfsmakros
> #define REG(regno)  __asm__(#regno)
> ...
> aber dann kann ich auch in Assembler (mit Makros) programmieren.

Yalu hat lediglich einige Variablen in Register gelegt, um RAM zu 
sparen, damit er nicht mehr als 2 Byte im RAM benötigt. Das war die 
Vorgabe von Moby.

Trotzdem ist es ein C-Programm. Da ist keine einzige Zeile 
Assembler-Code, lediglich einige Bindungen an CPU-Register.

von Einer K. (Gast)


Lesenswert?

Frank M. schrieb:
> Programmiere den mal in ASM nach. Dafür müsstest Du für jeden µC ein
> eigenes Assembler-Programm schreiben, eine absolut sinnlose Arbeit.

Der gemeine Assembler Fetischist hat an solchen Argumenten kein 
Interesse und blendet sie geflissentlich aus. Es wird dir erklärt 
werden, dass auch C/C++ nicht vollständig Plattformneutral sind.

von Cyblord -. (cyblord)


Lesenswert?

Arduino Fanboy D. schrieb:
> Es wird dir erklärt
> werden, dass auch C/C++ nicht vollständig Plattformneutral sind.

Was halt humbug ist, weil ich in ASM nicht eine einzige Zeile 
Plattformneutral programmieren kann. In C kann ich große Teile völlig 
unabhängig von der Hardware programmieren. Wenn man es halt tut. Der 
gemeine ASM Programmierer würde wohl an jeder beliebigen Stelle direkte 
Registerzugriffe auf die HW einbauen.

von Hugo H. (hugohurtig1)


Lesenswert?

Frank M. schrieb:
> Da ist keine einzige Zeile
> Assembler-Code

https://de.wikipedia.org/wiki/Integrierter_Assembler
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

Frank M. schrieb:
> __asm__(#regno)

Vielleicht sehe ich das falsch, aber in C habe ich "normalerweise" 
keinen direkten Zugriff auf Register. Klar, wenn man sich Prolog und 
Epilog einer ISR sparen will, in welcher Werte verändert werden, dann 
muss man sich etwas einfallen lassen ...

Haarspalterei meinetwegen, aber "ganz sauber" ist das nicht.

Beitrag #6415584 wurde von einem Moderator gelöscht.
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hugo H. schrieb:
> https://de.wikipedia.org/wiki/Integrierter_Assembler
> https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

Ich schrieb bewusst "Assembler-Code". Mit Code meine ich Opcode. Und 
da ist kein einziger Opcode im C-Code. Dass man __asm__(#regno) 
schreiben muss, um eine Variable einem Register zuzuordnen, heisst nicht 
unbedingt, dass da nun Assembler-Code folgt.

Hugo H. schrieb:
> Vielleicht sehe ich das falsch, aber in C habe ich "normalerweise"
> keinen direkten Zugriff auf Register.

Normalerweise nicht, bei direkter µC-Programmierung sehe ich das als 
legitim an, schließlich gibt es ja dieses Instrument. Nur so kann man 
auch ein Mini-Progrämmchen in ASM fair mit C vergleichen, weil Moby 
tatsächlich eben auch fast alles in Registern gehalten hat - eben weil 
es nur ein Mini-Progrämmchen war.

Hätte es sich um ein wesentlich umfangreicheres Programm gehandelt, 
hätte Moby seine Variablen auch im RAM auslagern müssen. Dann hätte Yalu 
natürlich auch darauf verzichtet. Denn dann kann der C-Compiler seine 
Stärken auch wesentlich besser ausspielen: er hat ab einer bestimmten 
Programmgröße allemal ein viel besseres "Gedächtnis" über die aktuell 
verwendeten Register als ein Mensch.

: Bearbeitet durch Moderator
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hugo H. schrieb:
> Frank M. schrieb:
>> Da ist keine einzige Zeile Assembler-Code
>
> https://de.wikipedia.org/wiki/Integrierter_Assembler
> https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
>
> Frank M. schrieb:
>> __asm__(#regno)
>
> Vielleicht sehe ich das falsch, aber in C habe ich "normalerweise"
> keinen direkten Zugriff auf Register.

Der Code ist kein C, sondern GNU-C: __asm kennzeichnet nicht nur inline 
Assembly, sondern auch lokale und globale Registervariablen.  Letztere 
verwendet Yalu in seinem Code, wie leicht and Yalus Quellkommentaren und 
dem Code selbst zu erkennen ist.

> Klar, wenn man sich Prolog und Epilog einer ISR sparen will,
> in welcher Werte verändert werden, dann muss man sich etwas
> einfallen lassen...

Die einzige Möglichkeit, Register, die in einer ISR verwendet werden, 
nicht im ISR-Prolog sichern zu müssen, sind globale Register.

Ob dies im Beispiel dem Laufzeit-Overhead der ISR geschuldet war, dem 
RAM-Verbrauch, oder ob es nur eine von Moby aufgestellte Bedingung war, 
welche man propremlos hätte fallen lassen können, weiß ich jetzt nicht.

: Bearbeitet durch User
Beitrag #6415726 wurde von einem Moderator gelöscht.
von Hugo H. (hugohurtig1)


Lesenswert?

Frank M. schrieb:
> Dass man __asm__(#regno)
> schreiben muss, um eine Variable einem Register zuzuordnen, heisst nicht
> unbedingt, dass da nun Assembler-Code folgt.

Entschuldige bitte - aber für mich ist das Unsinn. Wenn ich Register 
unter einem definierten Namen reserviere greife ich direkt in die 
Assembler-Generierung (Compilierung) ein. Ich schränke den C-Compiler in 
der Verwendung der Register ein und beeinflusse das Compilat und damit 
auch das Assembler-Zwischenprodukt.

von 900ss (900ss)


Lesenswert?

Hugo H. schrieb:
> ch schränke den C-Compiler in der Verwendung der Register ein und
> beeinflusse das Compilat und damit auch das Assembler-Zwischenprodukt.

Stimmt sicher. Und obwohl der Compiler damit eingeschränkte 
Möglichkeiten hatte, war das Ergebnis von Yalu kürzer damals.

von Hugo H. (hugohurtig1)


Lesenswert?

900ss D. schrieb:
> Und obwohl der Compiler damit eingeschränkte
> Möglichkeiten hatte, war das Ergebnis von Yalu kürzer damals.

Nicht obwohl - sondern weil.

von Martin V. (oldmax)


Lesenswert?

Hi
Mal wieder ein wahnsinnig langer Thread, der eigentlich schon nach 15 
Beiträgen hätte sein Ende finden können, nur weil mal wieder ein 
Glaubenskrieg über die Programmiersprache ausgebrochen ist. Man Leute, 
es ist doch Sch...egal, wer welche Sprache benutzt oder bevorzugt. 
Beruflich werden die meisten C nehmen, ganz selten Assembler, aber wer 
in seiner kleinen Kammer bastelt, der darf sich auch mit Assembler 
masochieren. Tu ich auch, weil ich C für mich nie benötigt habe. Sollte 
das in den letzten 30 Jahren meines Lebens nochh notwendig sein, nun, 
dann tu ich mir diese Stottersprache an, aber nicht, weil einer von euch 
mich überzeugt, sondern weil es erforderlich ist.
Aber, das heißt nicht automatisch, das die C -Programmierer gefälligst 
Assembler lernen oder anwenden  müssen. Bei denen, die programmieren zum 
Beruf haben, setze ich sowieso voraus, das sie zu 80 % auch Assembler 
können. Was bleibt, sind die kleinen starrköpfigen Glaubenskrieger, 
deren Anpassungsfähigkeit einem Betonpfeiler gleicht.
Ausgang war mal die Frage zu Interrupts eines AVR. Erinnert ihr euch 
noch?
Gruß oldmax

von Hugo H. (hugohurtig1)


Lesenswert?

Martin V. schrieb:
> Ausgang war mal die Frage zu Interrupts eines AVR. Erinnert ihr euch
> noch?
> Gruß oldmax

Kennst Du das berühmte Zitat von Dieter Nuhr (analog einige Zeit davor 
von "Alfred Tetzlaff") ?

Beitrag #6415907 wurde von einem Moderator gelöscht.
Beitrag #6416057 wurde von einem Moderator gelöscht.
Beitrag #6416064 wurde von einem Moderator gelöscht.
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.