Hallo,
hab eben mit nem LA nachgeguckt, ob mein ATmega8 auch sofort den
Interrupt (INT0) auslöst, aber dies geschieht immer erst 7us-12us
später. Ist das normal und wenn nicht, woran könnte das liegen?
Danke schon mal
> Ist das normal und wenn nicht, woran könnte das liegen?
Für bestimme Rahmenbedinungen sind die gemessen Werte vollkommen in
Ordnung. Wenn Dir das nicht langt musst Du mir ∗allen∗ relevanten
Informationen rausrücken.
Schätze mal, dass er mit den jungfräulichen 1MHz taktet und C verwendet
wird. Dann sind 7-12 Befehlstakte zwischen Interrupt und dem die Messung
beendenden Befehl nicht weiter bemerkenswert.
A. K. schrieb:> 1MHz taktet und C verwendet
Nein, 16MHz und ja, C.
neuer PIC Freund schrieb im Beitrag #4014497:
> Push- und Pop-Orgien des gcc bei all den vielen Registern. Schau dir mal> das disassembly an.
Gute Idee!
Jonathan K. schrieb:> Nein, 16MHz
Gewusst oder gehofft? 7*16=112 Takte geht nur mit Warteschleife vor der
entsprechenden Stelle. Die solltest du rausnehmen, denn so viele
Register hat auch ein AVR nicht.
Auszug aus einem mega644P Datenblatt:
--------------------------------------------------------------------
The interrupt execution response for all the enabled AVR interrupts
is five clock cycles minimum. After five clock cycles the program
vector address for the actual interrupt handling routine is
executed. During these five clock cycle period, the Program Counter
is pushed onto the Stack. The vector is normally a jump to the
interrupt routine, and this jump takes three clock cycles.
--------------------------------------------------------------------
Also ist man (wenn ich das richtig interpretiere) bei einem
Interrupt nach 8 Prozessorzyklen in der ISR. Bei einem 20 MHz AVR
wären das 0.4 usec. Bei lahmen Prozessortakt entsprechend länger.
..... als Beispiel für den 644P .....
Okey, beim ATmega8 ist sind das 4+3 Zyklen. Am Anfang meiner ISR
befinden sich 29 push's, 3 in's, 1 clr, 1 sbiw und 2 out's. Wenn ich das
richtig zusammengezählt habe sind das 66 Zyklen + 7 Zyklen (die 4+3 von
oben) = 73 Zyklen. Macht bei 16MHz 4.5625us. Das ist irgendwie noch
lange net 7us-12us.
A. K. schrieb:> Gewusst oder gehofft?
Wie meinst du das?
A. K. schrieb:> 7*16=112 Takte geht nur mit Warteschleife vor der> entsprechenden Stelle
Hab an der Stelle keine Warteschleife. Direkt am Anfang der ISR wird ein
Ausgang auf HIGH geschaltet.
EDIT: Und warum schwankt die Differenz zwischen dem eingehendem Signal
und dem Auslösen des Interrupts? Wenn ich sagen könnte, dass es immer
8us später ist, wäre das ganze nur halb so wild ...
Mitleser schrieb:> wenn ich das richtig interpretiere
Nicht interpretieren, lesen ist da besser.
Ein Minimum von fünf Zyklen und innerhalb dieser Zyklen braucht es
drei Zyklen um in die Routine zu springen.
Woanders habe ich auch mal was von 3-7 Zyklen gelesen. Welcher es nun
war, weiß ich so aus dem Kopf nicht mehr.
Jonathan K. schrieb:> EDIT: Und warum schwankt die Differenz zwischen dem eingehendem Signal> und dem Auslösen des Interrupts?
Weil es neben der konstanten noch eine variable Interruptlatenz gibt.
Die setzt sich aus mehreren Komponenten zusammen, die im worst case
tatsächlich fast alle zusammenkommen können:
1. der Restausführungszeit der unterbrochenen Instruktion
2. der Laufzeit des längsten cli/sei Blocks im Code von main()
3. der Maximallaufzeit der Interrupts geringerer Priorität
4. der Summe der Laufzeiten aller Interrupts höherer Priorität
Dein Glück ist, daß INT0 die höchste Priorität hat, das eleminiert
Problem 4. Wenn INT0 der einzige verwendete Interrupt ist, entfällt auch
noch Problem 3. Wenn du in der Hauptschleife keinerlei cli/sei-Blöcke
verwendest, entfällt auch noch Problem 2.
Problem 1 hast du aber immer.
Hmm, das klingt
c-hater schrieb:> 2. der Laufzeit des längsten cli/sei Blocks im Code von main()
Aha, mal alle Teile mit cli/sei rausgehen und es sind nur noch 5us-8us.
c-hater schrieb:> 3. der Maximallaufzeit der Interrupts geringerer Priorität
Jetzt noch die zwei Timer deaktiviert und ich habe immer 4.7us-4.75us,
was immerhin schon fast mit meinen errechneten 4.5625us übereinstimmt.
Die übrige Zeit wird dann wohl einfach der AVR noch brauchen, bis er
beim ISR landet.
Jonathan K. schrieb:> Am Anfang meiner ISR befinden sich 29 push's
Ziemlich gross, deine ISR, oder? Weil darin der gesamte Registersatz
versenkt wird. Wenn du wirklich schnelle Interrupts haben willst, dann
halte sie klein und rufe darin keine Funktionen auf.
Jonathan K. schrieb:> EDIT: Und warum schwankt die Differenz zwischen dem eingehendem Signal> und dem Auslösen des Interrupts?
Mit welchem Programm? Wieviele andere Interrupts sind da noch aktiv?
Jonathan K. schrieb:> Jetzt noch die zwei Timer deaktiviert und ich habe immer 4.7us-4.75us,> was immerhin schon fast mit meinen errechneten 4.5625us übereinstimmt.> Die übrige Zeit wird dann wohl einfach der AVR noch brauchen, bis er> beim ISR landet.
Richtig, was nach Eleminierung (fast) aller Quellen variabler Latenz
überbleibt, ist natürlich die konstante Latenz. Deswegen heißt die ja
auch so...
Matthias Sch. schrieb:> Wenn du wirklich nur einen Port auf high setzen willst, kannst du gcc> mal anweisen, eine 'nackte' ISR zu bauen:
Bei solch einer ISR werden auch in angezogenem Zustand garantiert keine
4.5 µs rauskommen. Wenn seine ISR 29 PUSH Befehle enthält, dann steckt
da das halbe Programm drin.
Guten Morgen,
ich habe noch eine Frage zu deiner Anmerkung aus:
c-hater schrieb:> 1. der Restausführungszeit der unterbrochenen Instruktion
Wie ich vorletztes Wochenende gelesen hatte, kann keine Instruktion
unterbrochen werden, wie wird ausgeführt.
Eine Programmunterbrechung erfolgt immer "zwischen" zwei AVR
Anweisungen, deshalb gibt es auch verschiedene Latenzen, z.B. bei
bedingten Sprüngen.
Da ich es gerne genauer wissen möchte, wo kann ich deine Aussage für
Atmel AVR 8-Bit µC wiederfinden ?
Jonathan K. schrieb:> hab eben mit nem LA nachgeguckt, ob mein ATmega8 auch sofort den> Interrupt (INT0) auslöst, aber dies geschieht immer erst 7us-12us> später. Ist das normal und wenn nicht, woran könnte das liegen?
Vor allem Dingen ist das was du gesagt hast, falsch. Was du gemessen
hast, ist nicht die Verzögerung bis der Interrupt ausgelöst hat - die
kannst du nämlich gar nicht messen. Gemessen hast du die die Zeit bis
eine nach außen sichtbare Reaktion aufgetreten ist. Himmelweiter
Unterschied.
Mal zum Vergleich eine Situation der normalen Welt: der Postbote
klingelt an der Tür. Durch das Schließen des Kontaktes im Klingelknopf
rast der Strom durch die Leitung zur Klingel, der Klöppel bwegt sich in
Richtung Glocke und bringt diese zum tönen. Der Schall pflanzt sich
durch die Luft fort, gelangt an dein Ohr. Der Hörnerv sendet einen
Impuls an dein Hirn und dort wird der Interrupt ausgelöst. Das alles
dauert seine Zeit. Keine Ewigkeit. Aber auch nicht Null.
Bevor der Postbote aber eine Reaktion bemerkt (du öffnest die Tür),
vergeht noch eine Menge mehr Zeit für andere Dinge. Du mußt zur Tür
laufen. Und du mußt deine aktuelle Tätigkeit unterbrechen. Vielleicht
gießt du dir gerade eine Tasse Kaffee ein. Oder telefonierst mit deiner
Mutter. Oder stehst eingeseift unter der Dusche.
Und so ist die Verzögerungszeit, die der Postboten messen kann, nicht
die Zeit die zum Auslösen des Interrupts benötigt wird. Sondern die Zeit
bis zur Reaktion.
Zurück zum µC. Auch da wird der Interrupt sehr schnell ausgelöst. Aber
der µC muß mindestens den aktuell laufenden Maschinenbefehl fertig
machen, bevor er die ISR ausführen kann. Eventuell ist er aber gerade
auch in einem Codeblock, der per cli()/sei() ununterbrechbar gemacht
wurde. Der muß dann erst abgearbeitet sein.
Wenn dann die ISR schließlich ausgeführt wird, passieren auch erst mal
ein paar Dinge, bevor eine nach außen sichtbare Reaktion erfolgt
(Stichwort: PUSH-Orgie).
Ob deine 7-12µs normal sind, hängt von der Taktfrequenz ab. Wenn der
ATmega8 mit der Default-Taktfrequenz von 1MHz läuft, dann wären das 7-12
Takte. Und damit vollkommen normal.
Guten Morgen,
bei der Berechnung der benötigten Zeiten in einer ISR, darf man, wenn
man von PUSH-Orgie spricht nicht das "Gegenteil" die POP-Orgie
vergessen.
Die benötigt die selbe Zeit.
Das selbe gilt auch für das Sichern des Statusregister SREG mit jeweils
3 Takten beim betreten und verlassen der ISR.
Uwe S. schrieb:> bei der Berechnung der benötigten Zeiten in einer ISR, darf man, wenn> man von PUSH-Orgie spricht nicht das "Gegenteil" die POP-Orgie> vergessen.
Ich habe gelernt dass diese "Orgien" abhängig sind davon wieviel
der AVR GCC optimiert und (wenn er optimiert) wieviele Register
wirklich aktuell gebraucht (gerettet/restauriert) werden (müssen).
Also es kann auch schon mal weniger Orgie sein ....
Jetzt mal unabhängig davon dass das Statusregister wohl immer
betroffen ist.
Falk Brunner schrieb:> Optimierung im Compiler eingeschaltet?> 29 push in einer ISR hab ich nocht nie gesehen . . .
es braucht doch nur eine Prozedur aufgerufen werden, schon müssen alle
Register gesichert werden.
Peter II schrieb:> es braucht doch nur eine Prozedur aufgerufen werden, schon müssen alle> Register gesichert werden.
R2–R17,R28,R29 (18 Stück) müssen nur gesichert werden, wenn die ISR sie
selbst verwendet. Aufgerufene Funktionen sichern diese Register selbst.
https://gcc.gnu.org/wiki/avr-gcc#Register_Layout
A. K. schrieb:> R2–R17,R28,R29 (18 Stück) müssen nur gesichert werden, wenn die ISR sie> selbst verwendet. Aufgerufene Funktionen sichern diese Register selbst.> https://gcc.gnu.org/wiki/avr-gcc#Register_Layout
davon weiß der GCC dann scheinbar nicht. Rufe mal eine Funktion auf und
schon werden viel mehr Register gesichert. (welche es genau sind kann
ich nicht sagen, aber es sind viel mehr also ohne Funktionsaufruf)
Gilt nur wenn die Funktion nicht geinlined wird.
Uwe S. schrieb:> c-hater schrieb:>> 1. der Restausführungszeit der unterbrochenen Instruktion>> Wie ich vorletztes Wochenende gelesen hatte, kann keine Instruktion> unterbrochen werden, wie wird ausgeführt.
Richtig, genau deswegen gibt es ja eine Restausführungszeit dieser
Instruktion, die als Interruptlatenz wirksam wird. Das ist genau die
Zeit, die die Instruktion nach Interruptauslösung noch benötigt, um
fertig zu werden.
Sie wird also nicht wirklich unterbrochen. Aber wie willst du ohne einen
Riesen-Wortverhau diese Instruktion anders beschreiben als die
unterbrochene? Der Kontext ergab doch unmittelbar, daß sie eben nicht
unterbrochen wird, sonst würde sie ja keine Latenz verursachen.
Peter II schrieb:>> R2–R17,R28,R29 (18 Stück) müssen nur gesichert werden, wenn die ISR sie>> selbst verwendet.> davon weiß der GCC dann scheinbar nicht.
Doch.
> Rufe mal eine Funktion auf und> schon werden viel mehr Register gesichert.
Unbestritten. Mehr ja, aber eben nicht alle. Nicht einmal die Hälfte.
Ich hatte oben 18 aufgezählt. Bleiben 14 übrig. Und genau die werden in
einem bis auf den Funktionsaufruf leeren Handler gesichert:
R0-R1,R18-R27,R30-R31.
Jonathan K. schrieb:> Am Anfang meiner ISR> befinden sich 29 push's
Versuche keine (wirklich keine einzige) Funktion aufzurufen im
Interrupt. Dann verschwinden die meisten Pushs bis auf ne kleine Hand
voll. Notfalls die entsprechenden Funktionen als inline definieren und
somit etwas Flash opfern (wenn überhaupt).
Sehe ich das richtig, dass Interrupts "nachgeholt" werden? Bisher dachte
ich, dass Interrupts, die wegen einem anderen Interrupt nicht direkt
ausgeführt werden können, verloren sind.
Wenn ich
"Bei den meisten Intrrupts wird das auftreten eines Interrupts in einem
Flag gespeichert. Der Interrupts wird entsprechend ggf. Nachgeholt und
geht nicht verloren. Nur wenn in der Zeit in der Interrupts gesperrt
sind der eine Interrupt 2 mal auftritt, wird der Interrupt nur 1 mal
nachgeholt. Beim nachholen der Interrupts gilt die Reihenfolge der
Interruptsvektoren, nicht die in der die Events aufgetreten sind."
aus Beitrag "Hohe Frequenz bei AVR-Interrupts" richtig verstehe, werden
alle verpassten Interrupts, die in einem Register ein Flag für den
Interrupt haben, einmal nachgeholt. Richtig?
Jonathan K. schrieb:> Sehe ich das richtig, dass Interrupts "nachgeholt" werden? Bisher dachte> ich, dass Interrupts, die wegen einem anderen Interrupt nicht direkt> ausgeführt werden können, verloren sind.
ja, sonst könnte man ja nie sinnvoll damit arbeiten. Wenn ein neues Byte
per UART ankommt und gleichzeitig der Timer zuschlägt.
Jonathan K. schrieb:> Sehe ich das richtig, dass Interrupts "nachgeholt" werden? Bisher dachte> ich, dass Interrupts, die wegen einem anderen Interrupt nicht direkt> ausgeführt werden können, verloren sind.
Das wär aber schön doof, wenn der Interrupt von der Motorendabschaltung
nicht durchkommt, weil gerade ein UART Interrupt ein eingehendes Zeichen
behandelt.
> alle verpassten Interrupts, die in einem Register ein Flag für den> Interrupt haben
Alle Interrupts haben ein Flag welches beim Auftreten des Ereignisses
zunächst mal gesetzt wird. Und zwar unabhängig davon, ob der
entsprechende Interrupt freigegeben ist oder nicht.
Dieses Flag speichert also nur die Information: Ereignis ist
eingetreten.
Ist der zugehörige Interrupt dann auch noch frei gegeben UND die globale
Interrupt Freigabe auch noch frei gegeben, dann wird der entsprechende
Interrupt Vektor angesprungen ("die ISR angesprungen") und dabei
automatisch das entsprechende Flag auch noch gelöscht.
Das Registrieren des Interrupt auslösenden Ereignisses findet also immer
und unabhängig davon, ob es auch per ISR behandelt wird statt.
Peter II schrieb:> ja, sonst könnte man ja nie sinnvoll damit arbeiten.
Ahh, dachte ich mir auch die ganze Zeit, aber war bis jetzt auch noch
nie sooo wichtig.
@Mod
Ist doch wieder mal ein schönes Beispiel, wie Hochsprache den Verkehr
aufhält und Problemlösungen verkompliziert. Nicht wahr? Stört natürlich
das Weltbild des C-Evangeliums und muß gelöscht werden, Entschuldigung
;-)
Moby schrieb:> @Mod> Ist doch wieder mal ein schönes Beispiel, wie Hochsprache den Verkehr> aufhält und Problemlösungen verkompliziert. Nicht wahr?
Seh ich eigentlich nicht.
Für ein hinreichend komplexes Programm hast du in jeder Sprache das
Problem, dass du nicht einfach Register nach Lust und Laune in einer ISR
benutzen bzw. verändern darfst.
Die einzige Ausnahme ist, wenn man ein oder mehrere Register für nur
eine ganz spezielle Aufgabe exklusiv reservieren kann. Zugegeben mit den
Registern des AVR ist das bis zu einem gewissen Grad möglich, aber auch
hier wieder: mit steigender Komplexität erfolgt der Wandel im Programm,
dass man genau diese Exklusiv-Verwendung abstellen wird und muss, weil
man nicht genügend Register hat. Womit zwangsläufig das Problem
auftaucht, dass diese in einer ISR gesichert und wiederhergestellt
werden müssen.
> Stört natürlich> das Weltbild des C-Evangeliums und muß gelöscht werden, Entschuldigung> ;-)
Ganz und gar nicht.
Die Diskussionen drehen sich ja nicht darum, dass man in einer Sprache
wie C den Komfort nicht bezahlen müsste. Die Diskussionen drehen sich
darum, wie teuer es ist. Und diese 'Kosten' halten sich nun mal in den
meisten Fällen im akzeptablen Rahmen.
Ich habe es schon des öfteren hier im Forum angeboten: Machen wir doch
die Probe aufs Exempel. Nehmen wir ein hinreichend komplexes Projekt
(also schon 'etwas' komplexer als eine blinkende LED; es muss aber auch
nicht gleich ein TCP/IP Stack sein, aber eine gewisse Herausforderung
sollte es dann schon auch sein), du implementierst es in Assembler, ich
in C. Und dann sehen wir mal, was da so rauskommt, wobei nicht nur die
Laufzeit berücksichtigt wird, sondern auch so Begriffe wie
"Entwicklungszeit" bzw. "Fehlerfreiheit" bzw. "Anpassbarkeit auf
geänderte Bedingungen bzw. Erweiterbarkeit" mit reingenommen werden.
Angeboten hab ich das schon öfter, angenommen hat es noch nie wer.
Karl Heinz schrieb:> Angeboten hab ich das schon öfter, angenommen hat es noch nie wer.
Moby der Handschuh liegt dir zu Füßen, du musst ihn nur aufheben.
Karl Heinz schrieb:> Für ein hinreichend komplexes Programm hast du in jeder Sprache das> Problem, dass du nicht einfach Register nach Lust und Laune in einer ISR> benutzen bzw. verändern darfst.
Natürlich. Aber in Assembler hast du die Freiheit, die die
Registerverwendung danach zu verteilen, wo sie am meisten Nutzen
bringen.
> aber auch> hier wieder: mit steigender Komplexität erfolgt der Wandel im Programm,> dass man genau diese Exklusiv-Verwendung abstellen wird und muss
Kaum. Man kann alles andere auch mit weniger Registern machen, nur halt
nicht mehr ganz so effizent, als wenn man die volle Registerzahl zur
Verfügung hätte. Genau deswegen ist es wichtig, das Zeitverhalten seines
Systems zu kennen und die Register so zu verwenden, daß, über alles
gesehen, die bestmögliche Effizienz rauskommt. Und das geht nur in
Assembler wirklich.
Aber, man muß zugegeben, es gibt auch C-Compiler, die das zumindest
eingeschränkt ebenfalls ermöglichen. Aber gerade bei denen kann man dann
auch am deutlichsten sehen, wie ungeheuer wichtig das für die
Systemleistung ist, denn der Rest des Codes bleibt bei dieser
Optimierung ja gleich.
Und so tut es nichtmal den C-Fetischisten weh, denn die wollen ja
garnicht wissen, wie der Compiler den kryptischen Syntax-Bläh auf
allgemeinverständliche Maschinen-Instruktionen eindampft. Wenn denen
keiner sagt, daß ihr Compiler mit ein bis vier Registern weniger
auskommen mußte, dann merken die das i.d.R. ja auch nichtmal...
c-hater schrieb:> Und so tut es nichtmal den C-Fetischisten weh, denn die wollen ja> garnicht wissen, wie der Compiler den kryptischen Syntax-Bläh auf> allgemeinverständliche Maschinen-Instruktionen eindampft.
Der Witz daran ist: das stimmt.
Solange das erzeugte Kompilat schnell genug ist, interessiert mich das
keinen kleinen Hauch wie der Compiler mein Programm umgesetzt hat.
Erst wenn es mal knapp wird und keine Optimierungsstufe mehr hilft, dann
lohnt es sich, den Assembler anzuschauen. Und wenn sich Interrupts
verhaken, meist liegt es dann nicht am C-Code, sondern an der
Denkweise und an der Programmstruktur. Und die sieht bei einem
Programmierer immer gleich gut und gleich schlecht aus, je nach dem wie
gut er "seinen" uC kennt.
c-hater schrieb:> Genau deswegen ist es wichtig, das Zeitverhalten seines Systems zu> kennen und die Register so zu verwenden, daß, über alles gesehen, die> bestmögliche Effizienz rauskommt.
Ein Assembler-Programmierer, der nicht weiß wie man die
Hardwarekomponenten (Timer, Interrupts, ...) "seines" uC zweckmäßig
verwendet, der wird auch mit Assembler einen grausigen Murks abliefern.
Ein C-Programmierer (oder allgemein Hochsprachenprogrammierer), der sich
mit "seiner" Hardware auskennt, wird ganz selten eine Zeile Assembler
zur Beschleunigung brauchen.
c-hater schrieb:> Und das geht nur in Assembler wirklich.
Früher(tm) war das noch der Fall. Aber seit der Jahrtausendwende sind
die Compiler so gut, da stimmt diese pauschalisierende Aussage nicht
mehr. Manchmal legt dir ein Compiler für einen bestimmten
Hochsprachencode einen wirklich eleganten Assemblercode hin, das hätte
ein durchschnittlicher Assemblerprogrammierer niemals geschafft. Ich
habe sowas einige Male ausprobiert und kontrolliert. Und du?
Lothar Miller schrieb:> Manchmal legt dir ein Compiler für einen bestimmten> Hochsprachencode einen wirklich eleganten Assemblercode hin, das hätte> ein durchschnittlicher Assemblerprogrammierer niemals geschafft.
Beispiel, und das gab es schon in Compilern der 80er: switch statements.
Ein Compiler wird, abhängig von der Anzahl und Verteilung der Werte,
ggf. einen Vergleichsbaum erzeugen. Wenn es genug Werte sind, die für
Tabelle zu wenig sequentiell sind.
Also zuerst einen Wert in der Mitte der Liste abfragen,
drunter/drüber/gleich, dann einen Wert in der Mitte der verbleibenden
Hälfte usw. Aufwand logarithmisch.
Grad bei einfachen Architekturen mit billigen Vergleichen wie AVR kann
das sehr effizient sein. Aber kein Assembler-Programmierer wird jemals
so einen Code produzieren, zumal bei jeder Änderung der ganze Baum neu
aufgebaut werden muss.
@A.K.:
Wer Hochsprachen aber so richtig hasst, der wird nie auf die Idee
kommen, das mal genauer anzuschauen. Allein die Frage welcher Wert steht
denn gerade in welchem Register, wird mMn von mir vielleicht in
Einzenlfällen besser optimiert. Nur wieviele solche Optimierungen
bekomme ich je Sekunde hin? Und das ist Leistung: Arbeit pro Zeit.
Geschätzt bei einfachen Programmen 1s zu 1h oder 3600 mal höhere
Leistung für die Software, denn da arbeiten jeweils die Hirne der
Compilerschreiber für mich mit. Und wenn's komplizierter wird, wessen
Konzentration lässt zuerst nach?
Aber wie gesagt, wer richtige hasst ...
Bastler schrieb:> Aber wie gesagt, wer richtige hasst ...
Ach das ist doch kein Hass. Das ist pures Unvermögen. Die haben ihre
kleine Assembler-Welt und da kennen sie sich aus. Eine Hochsprache
erfordert am Ende viel mehr Können, weil die abstrakten Möglichkeiten
vielfältiger sind. Bei Assembler muss der Fokus immer zum großen Teil
auf niedrigem Level liegen, schon damit alles technisch überhaupt
funktioniert. Bei Hochsprachen verschiebt sich das, und es geht um
Konzepte. Und das kann man nicht mehr so einfach auswendig lernen wie
einen Befehlssatz mit ein- bis zweihundert Befehlen.
Und da scheitern die dann halt und geifern dann gegen die Hochsprachen.
Habt Mitleid.
Bernd K. schrieb:> Was ist denn ein C-Fetischist? Gibts in Deinem Weltbild auch normale> C-Anwender?
Für einen Fetischisten sind die anderen selbstredend auch Fetischisten.
Cyblord ---- schrieb:> Und da scheitern die dann halt und geifern dann gegen die Hochsprachen.> Habt Mitleid.
Ach nee.
Es geht hier doch um möglichst schnelle Reaktion auf Interrupts. Wenn es
richtig zeitkritisch ist, kommt man - insbesondere beim AVR - um
Assembler nicht umhin. Die neueren AVR haben noch die Möglichkeit, über
GPIORx-Register SREG und ein, zwei Register über IN/OUT-Befehle zu
sichern, was die Ausführung noch einmal beschleunigt.
Kann man dann noch den Compiler anweisen, ein paar interne Register
unberührt zu lassen und dadurch PUSH und POP zu vermeiden, steigert das
die Geschwindigkeit nochmals. Dafür ist Assembler erste Wahl!
Lothar Miller schrieb:> Ein C-Programmierer (oder allgemein Hochsprachenprogrammierer), der sich> mit "seiner" Hardware auskennt, wird ganz selten eine Zeile Assembler> zur Beschleunigung brauchen.
Wie ich oben schon schrieb, sind sich ja auch die avr-gcc Entwickler
über die ISR Latenz im Klaren und bieten verschiedene Möglichkeiten an,
ISRs so zu deklarieren, das die Latenz klein bleibt.
Die Erfahrung zeigt aber, das das in nur sehr wenigen Fällen wirklich
nötig ist und meistens durch ein wenig Überlegen und eine bessere
Programmstruktur behandelt werden kann, ohne auf die Tricks wie
'ISR_NAKED' usw. zurückgreifen zu müssen.
m.n. schrieb:> Ach nee.> Es geht hier doch um möglichst schnelle Reaktion auf Interrupts. Wenn es> richtig zeitkritisch ist, kommt man - insbesondere beim AVR - um> Assembler nicht umhin. Die neueren AVR haben noch die Möglichkeit, über> GPIORx-Register SREG und ein, zwei Register über IN/OUT-Befehle zu> sichern, was die Ausführung noch einmal beschleunigt.> Kann man dann noch den Compiler anweisen, ein paar interne Register> unberührt zu lassen und dadurch PUSH und POP zu vermeiden, steigert das> die Geschwindigkeit nochmals. Dafür ist Assembler erste Wahl!
Das mag alles sein. Nur ist die Thematik deshalb eben kein Grund,
pauschal gegen C vorzugehen. Jeder C-Programmierer weiß dass man ab und
zu auch direkt was in Assembler schreiben muss. Darum geht es hier gar
nicht.
Cyblord ---- schrieb:> Das mag alles sein. Nur ist die Thematik deshalb eben kein Grund,> pauschal gegen C vorzugehen.
Ach, es ist hier doch üblich, überspitzt zu formulieren, um überhaupt
wahrgenommen zu werden. Ich gehe davon aus, daß c-hater weiß, was er
macht und das er das auch kann ;-)
Cyblord ---- schrieb:> Jeder C-Programmierer weiß dass man ab und> zu auch direkt was in Assembler schreiben muss.
Wenn das so wäre, gäbe es diesen Beitrag nicht. C-Programmierer fallen
nicht vom Himmel und müssen das Handwerk erst erlernen.
m.n. schrieb:> Es geht hier doch um möglichst schnelle Reaktion auf Interrupts.
Die Registersituation macht klar, dass ziemlich viel Code im
Interrupt-Handler steckt. Also nicht bloss 1-2 Bitoperationen auf Ports
oder so. Das steht eine einfachen Lösung per Assembler etwas im Weg.
Cyblord ---- schrieb:> Das mag alles sein. Nur ist die Thematik deshalb eben kein Grund,> pauschal gegen C vorzugehen. Jeder C-Programmierer weiß dass man ab und> zu auch direkt was in Assembler schreiben muss.
Auf Anhieb fällt mir da in der Codesammlung ein Basic-Interpreter ein,
der nebenher auch noch ein Video-Signal erzeugt. Das man letzteres in
Assembler schreiben muss ist denke ich jedem klar. Da geht es um jeden
Taktzyklus. Abgesehen davon .... mhhm .... kann ich mich an kein
Beispiel hier im Forum erinnern, das zwingend Assembler erfordert hätte.
Mag sein, dass es welche gab, aber viel mehr als 2 Handvoll in 10 Jahren
werden es nicht gewesen sein.
Und ob im Falle des TO die absolut mögliche geringste Interrupt Latenz
tatsächlich notwendig ist .... kann man eher nicht beurteilen. Gerade
bei Neulingen wäre ich da sehr vorsichtig mit derartigen FOrderungen.
Wäre nicht das erste mal, dass etwas gefordert ist, was tatsächlich
niemand wirklich braucht. Zum anderen hat bis jetzt ja noch niemand die
ISR auch tatsächlich gesehen, so dass man sich mal ansehen könnte,
welche Verbrechen da wieder drinn stecken, die den Compiler zur Push/Pop
Orgie zwingen.
Karl Heinz schrieb:> Cyblord ---- schrieb:>>> Das mag alles sein. Nur ist die Thematik deshalb eben kein Grund,>> pauschal gegen C vorzugehen. Jeder C-Programmierer weiß dass man ab und>> zu auch direkt was in Assembler schreiben muss.>> Auf Anhieb fällt mir da in der Codesammlung ein Basic-Interpreter ein,> der nebenher auch noch ein Video-Signal erzeugt. Das man letzteres in> Assembler schreiben muss ist denke ich jedem klar. Da geht es um jeden> Taktzyklus. Abgesehen davon .... mhhm .... kann ich mich an kein> Beispiel hier im Forum erinnern, das zwingend Assembler erfordert hätte.> Mag sein, dass es welche gab, aber viel mehr als 2 Handvoll in 10 Jahren> werden es nicht gewesen sein.
Tasksysteme, Scheduler usw. würden mir da noch einfallen.
Oder die delay routinen der libc sind auch in ASM was wohl auch gut so
ist.
Cyblord ---- schrieb:> Oder die delay routinen der libc sind auch in ASM was wohl auch gut so> ist.
Sonst würde der Compiler die unnötigen Schleifen wegoptimieren ;-)
Karl Heinz schrieb:> Abgesehen davon .... mhhm .... kann ich mich an kein> Beispiel hier im Forum erinnern, das zwingend Assembler erfordert hätte.
Ich zeig Dir mal eins:
http://www.mikrocontroller.net/attachment/184587/qcnt_6sub.s
Es geht um eine 4-fach Flankenauswertung per Interrupt bis 500 kHz mit
einem ATmega88 @ 20 MHz. PUSH und POP sind nicht vorhanden.
Natürlich weiß ich, daß die Auswertung von Inkrementalgebern per
Interrupt ganz böse ist ;-)
m.n. schrieb:> Karl Heinz schrieb:>> Abgesehen davon .... mhhm .... kann ich mich an kein>> Beispiel hier im Forum erinnern, das zwingend Assembler erfordert hätte.>> Ich zeig Dir mal eins:> http://www.mikrocontroller.net/attachment/184587/qcnt_6sub.s> Es geht um eine 4-fach Flankenauswertung per Interrupt bis 500 kHz mit> einem ATmega88 @ 20 MHz. PUSH und POP sind nicht vorhanden.
Gut.
Dann sind das 2 Beispiele.
Sonst noch was?
Karl Heinz schrieb:> Gut.> Dann sind das 2 Beispiele.> Sonst noch was?
Wie wär's hiermit:
Beitrag "Projektvorstellung: µMk64 - 2-MHz Heimcomputer aus 5 AVRs"Cyblord ---- schrieb:> Eine Hochsprache> erfordert am Ende viel mehr Können, weil die abstrakten Möglichkeiten> vielfältiger sind. Bei Assembler muss der Fokus immer zum großen Teil> auf niedrigem Level liegen, schon damit alles technisch überhaupt> funktioniert. Bei Hochsprachen verschiebt sich das, und es geht um> Konzepte.
Sorry, aber ich glaube mein vorgenanntes Projekt beweist da das
Gegenteil. Ich musste dafür sowohl abstrakte Konzepte als auch Low-Level
paralell bearbeiten und aneinender anpassen. Für einen Fokus auf
Low-Level ist das Projekt 'ein wenig' zu komplex und ein Compiler, der
Code für mehrere Prozessoren so aneinander anpasst ist mir auch noch
nicht untergekommen.
Grüße
Mark
Mark Leyer schrieb:> Karl Heinz schrieb:>> Gut.>> Dann sind das 2 Beispiele.>> Sonst noch was?>> Wie wär's hiermit:> Beitrag "Projektvorstellung: µMk64 - 2-MHz Heimcomputer aus 5 AVRs"
An dem Projekt war aber nichts "notwendig". Das war eine
Selbstgeißelung.
Schon die Rahmenbedingungen sind doch absurd. Vorsätzliche Einschränkung
der Messmittel usw.
Das kannst du doch nicht ernsthaft als Beispiel für sinnvollen ASM
Einsatz hernehmen.
> Sorry, aber ich glaube mein vorgenanntes Projekt beweist da das> Gegenteil. Ich musste dafür sowohl abstrakte Konzepte als auch Low-Level> paralell bearbeiten und aneinender anpassen. Für einen Fokus auf> Low-Level ist das Projekt 'ein wenig' zu komplex und ein Compiler, der> Code für mehrere Prozessoren so aneinander anpasst ist mir auch noch> nicht untergekommen.
Fleißarbeit halt. Siehe oben. Es geht um SINNVOLLEN Einsatz von ASM, wo
er notwendig ist, nicht um zwanghaften Rätselwahn.
Natürlich kann man am Ende alles in ASM machen, das hat niemand
bezweifelt. Du hättest auch den Lötkolben weg lassen können und
stattdessen alles mit einem Feuerzeug (oder Feuerstein) löten können.
Damit hätten wir dann gleich die sinnlosigkeit eines Lötkolbens bewiesen
oder wie?
Mark Leyer schrieb:> Sorry, aber ich glaube mein vorgenanntes Projekt beweist da das> Gegenteil.
Gleich vorweg: schönes Projekt.
Aber 9 Mannmonate?
CPU Emulation: ok, da sind Zyklen wichtig
Video wurde schon angesprochen
SD-Karte: gähn. Gibts in C
Soundchip: irgendwo in der Codesammlung gibt es eine SID Emulation.
(Ist zwar nicht die, die ich suche, aber trotzdem:
Beitrag "ATMEGA8 Soundgenerator/Synthizer")
Das man Dinge in Assembler machen kann stellt doch keiner in Frage.
Die Frage ist, wie sinnvoll ist es alles in Assembler zu machen, wenn
ich in der selben Zeit in C viel mehr schaffen kann, weil ich mich um
den ganzen Kleinkram eben nicht kümmern will und das auch nicht muss,
weil das Ergebnis vom Compiler mehr als gut genug ist.
Dass es Bereiche gibt, in denen man auf Assembler zurück fallen wird und
muss, stellt keiner in Frage. Ich denke da zb an die bekannte FFT von
Elm-Chan. Die ist sicherlich nicht ohne Grund in Assembler geschrieben.
Aber: die ist nur Teil eines Projektes. Der Rest wird dann in
Hochsprache geschrieben. Warum? Weil es in der Laufzeit schnell genug
ist und in der Entwicklungszeit schneller geht.
Ob das Projekt an sich 'sinnvoll' ist oder nicht will ich hier nicht
diskutieren, manche fahren halt gerne mit dem Auto, andere erwandern
sich unbefahrbare Strecken zu Fuß, 'Sinn' macht das jeweils nur für
jeden einzelnen seinen Interessen zu folgen und Spaß dabei zu haben.
Der Punkt ist einfach der, dass mein Projekt nur in ASM möglich ist. Das
Konzept basiert darauf, dass bis zu vier AVRs abwechselnd auf einen
gemeinsamen RAM zugreifen und das komplett nur über die jeweilige
Software synchronisiert. Das bekommt halt kein Compiler so hin.
Es war genau mein Ziel einen Computer zu entwickeln, der so vorhersehbar
taktgenau funktioniert wie ein C64. Um dieses Ziel zu erreichen war nur
der Einsatz von ASM sinnvoll bzw. überhaupt möglich. Ich hätte mir auch
viele andere Ziele setzen können, die ich vielleicht auch mit deutlich
weniger Arbeit in C hätte erreichen können. Ich hätte mir auch einen
RaspPi nehmen und einen C64-Emulator schreiben können, hätte viel Arbeit
gespart und so weiter. Aber das wäre niemals das gewesen, was ich haben
wollte, es hätte nur nach Außen ähnlich ausgesehen.
Aber das ist nicht der Punkt, der Punkt ist, dass ich ein festes Ziel
hatte, dass ich so nur mit ASM sinnvoll erreichen konnte in der Form und
mit dem Ergebniss was die Geschwindigkeit angeht. Ob meine Ziele
'sinnvoll' oder 'notwendig' waren ist alleine meine Sache, ist
schließlich ein Hobbyprojekt und kein gewerblicher Auftrag. Aber in
Bezug auf meine konkreten Ziele war nur der Einsatz von ASM sinnvoll.
Karl Heinz schrieb:> Angeboten hab ich das schon öfter, angenommen hat es noch nie wer.
Na, wer hat/investiert auch schon Zeit und Energie für ein größeres
Programm, um in einem solchen Forum ganz ohne eigenen Nutzen bloß etwas
nachzuweisen? Das wird Dir natürlich ebenso klar sein wie die etwas
unredlichen Rahmenbedingungen: So wie Du dabei pauschal und etwas albern
unterstellst, ich würde der Hochsprache unabhängig jedweder Ausgangslage
die Sinnhaftigkeit absprechen, so total subjektiv, situationsabhängig
und ungeeignet für einen objektiven Sprachvergleich bei nicht allzu
komplexen, großen Programme sind Kategorien wie
- Entwicklungszeit (von vorhandenem Code und Programmiererkönnen
bestimmt)
- Fehlerfreiheit (vom "sachgemäßen" Umgang mit den Sprachmitteln
bestimmt)
- Anpassbarkeit/Erweiterbarkeit (in jeder Sprache uneingeschränkt
möglich)
Und um gleich noch die unerwähnte Portabilität mit ins Boot zu nehmen:
Die braucht man gar nicht unbedingt und überall- insbesondere wenn man
die OBJEKTIVEN Vorteile einfachen Asm-Codes wie bei Speed und
Platzverbrauch, kombiniert mit einer hinreichend großen
Controllerspannweite so wie bei der AVR-Architektur für sich zu nutzen
weiß. Also bleiben wir doch bitte bei diesen objektiven, wirklich
vergleichbare Kriterien, die ich in meinem wieder mal gelöschten Beitrag
schon angesprochen hatte und die doch (der Speed) allein für das
Threadproblem hier verantwortlich zeichnen. Aber Du "ahnst" ja selber
schon
> dass man in einer Sprache wie C den Komfort ... bezahlen muß
Trotzdem, ich hätte da auch schon was vorbereitet. Etwas Code für eine
zwar recht einfache, aber doch typische Problemstellung aus der Praxis:
LED0 = KEY0.state; // an solange Taste gedrückt
LED1.toggle = KEY1.press // wechsel bei jeder Drückflanke
LED2.off = KEY2.press_short; // kurz drücken - aus
LED2.on = KEY2.press_long; // lang drücken - an
Alle Eingänge schön entprellt natürlich.
Kommt das jemandem bekannt vor? Ja, das ist das Beispiel aus
Beitrag "C++ auf einem MC, wie geht das?"
an dem sich die Protagonisten gepflegter OOP seit Monaten zwar
akademisch elegant, aber doch bislang erfolglos mit ihrem Wust an C++
Konstrukten abarbeiten... Dort wo es gepaßt und den C++lern die
Messlatte für eine einfache Problemlösung aufgezeigt hätte wurde der
Code natürlich gelöscht ;-(
Dann eben hier nochmal. Möge das doch jemand kürzer/schneller in C
kodieren! Aber Achtung, ich sehe im Fall der Fälle noch weiteres
Optimierungspotential ;-)
> Die einzige Ausnahme ist, wenn man ein oder mehrere Register für nur> eine ganz spezielle Aufgabe exklusiv reservieren kann. Zugegeben mit den> Registern des AVR ist das bis zu einem gewissen Grad möglich, aber auch> hier wieder: mit steigender Komplexität
Und dieser gewisse Grad langt bei 32 verfügbaren allgemeinen Registern
durchaus sehr weit: Wie im Beispielcode gezeigt nehme ich R9-R15 in
Interrupts zur schnellen Registersicherung- und dort dann meist nur für
die universellen Pointerregister + Status. Das langt für Millionen
Einsatzfälle- und wer sagt denn das es tragisch ist, für zusätzlich
benötigte Register punktgenau Push/Pop zu bemühen? Gerne verpacke ich
ganz orgienfrei auch die gesamte Funktionalität im Interrupt- das
Hauptprogramm schläft dann nur noch energiesparend.
Cyblord ---- schrieb:> Eine Hochsprache> erfordert am Ende viel mehr Können, weil die abstrakten Möglichkeiten> vielfältiger sind.
Richtig! Als Hobbybastler kann ich aber fragen: Braucht es das?
Bei Millionen einfacher Steuerungsanwendungen?
> Bei Hochsprachen verschiebt sich das, und es geht um> Konzepte. Und das kann man nicht mehr so einfach auswendig lernen wie> einen Befehlssatz mit ein- bis zweihundert Befehlen.
Richtig! Nicht mehr so einfach... d.h. komplizierter! Ganz schnell
unnötig kompliziert! Das Aufwand-Nutzen Verhältnis der Problemstellung
nicht mehr angemessen.
> Es geht um SINNVOLLEN Einsatz von ASM, wo> er notwendig ist, nicht um zwanghaften Rätselwahn.
Es geht um sinnvollen Einsatz von Hochsprache,
wo sie nötig ist, nicht um zwanghaften Rätselwahn ;-)
Moby ist wach geworden!
Jetzt fehlt nur noch ein Vertreter der STM32-Fraktion, der für
Assemblerprogrammierung (vielleicht zu Recht) garkeinen Sinn mehr sieht.
Dann noch eine große Tüte Karamellen - heute ist der letzte Tag dafür
;-)
Moby schrieb:> unredlichen Rahmenbedingungen: So wie Du dabei pauschal und etwas albern> unterstellst, ich würde der Hochsprache unabhängig jedweder Ausgangslage> die Sinnhaftigkeit absprechen
Dann frag ich mich, was der Spruch von wegen
1
... Stört natürlich das Weltbild des C-Evangeliums ...
eigentlich sollte?
> so total subjektiv, situationsabhängig> und ungeeignet für einen objektiven Sprachvergleich bei nicht allzu> komplexen, großen Programme sind Kategorien wie>> - Entwicklungszeit (von vorhandenem Code und Programmiererkönnen> bestimmt)
finde ich nicht. Immerhin ist das einer der wesentlichen Kanckpunkte in
der industriellen Softwareentwicklung.
> - Fehlerfreiheit (vom "sachgemäßen" Umgang mit den Sprachmitteln> bestimmt)
Nicht nur. Auch algorithmische Fehlerfreiheit. Die wächst ganz
automatisch mit dem Umfang des Programms in LOC.
> - Anpassbarkeit/Erweiterbarkeit (in jeder Sprache uneingeschränkt> möglich)
Die Frage ist: welche Details muss ich noch im Kopf haben, wenn ich 2
Jahre später wieder an denselben Code gehe.
> Trotzdem, ich hätte da auch schon was vorbereitet. Etwas Code für eine> zwar recht einfache, aber doch typische Problemstellung aus der Praxis:>> LED0 = KEY0.state; // an solange Taste gedrückt> LED1.toggle = KEY1.press // wechsel bei jeder Drückflanke> LED2.off = KEY2.press_short; // kurz drücken - aus> LED2.on = KEY2.press_long; // lang drücken - an>> Alle Eingänge schön entprellt natürlich.
sorry.
Aber das ist mir zu banal.
PeDa Entprellung und eine simple Hauptschleife. Sache auf 10 Minuten.
Höchstens.
> Kommt das jemandem bekannt vor? Ja, das ist das Beispiel aus> Beitrag "C++ auf einem MC, wie geht das?"> an dem sich die Protagonisten gepflegter OOP seit Monaten zwar> akademisch elegant, aber doch bislang erfolglos mit ihrem Wust an C++> Konstrukten abarbeiten...
Ich han den Thread nicht weiter verfolgt. Hab also auch keine Ahnung was
dort die Entwicklung ist. Ich würde allerdings mal schätzen, dass es da
um prinzipielle Themen geht um prinzipielle Herangehensweisen.
> Dort wo es gepaßt und den C++lern die> Messlatte für eine einfache Problemlösung aufgezeigt hätte wurde der> Code natürlich gelöscht ;-(
Kann nichts dazu sagen. Hab den Thread nicht verfolgt.
Da aber alle die PeDa Lösung kennen, ist die Aufgabenstellung trivial in
C zu lösen. Die einzig interessante Frage, die ich mir vorstellen
könnte, lautet: wie kann ich das in OOP verpacken, so dass ich möglichst
keinen Penalty zahle.
Das ihr da natürlich mit einer Assemblerlösung nicht gerne gesehen seid,
ist mir dann auch klar. Denn das ist in Wirklichkeit überhaupt nicht
gefragt, wenn sich die Diskussion um Konzepte und Varianten bzw. deren
Vergleich dreht. Das wäre dann eine einfache Themenverfehlung.
> Dann eben hier nochmal. Möge das doch jemand kürzer/schneller in C> kodieren! Aber Achtung, ich sehe im Fall der Fälle noch weiteres> Optimierungspotential ;-)> Und dieser gewisse Grad langt bei 32 verfügbaren allgemeinen Registern> durchaus sehr weit:
Schön.
Wie wärs mit einer nicht so trivialen Aufgabenstellung.
Heizungssteuerung. Brenner per PWM angesteuert. Dazu ein DS1820 als
Temperaturaufnehmer. Nein, 2 DS1820. Die Aussentemperatur sollte auch
mit eingehen
Dazu eine Tageszeit abhängige Temperaturkurve (die Heizung soll ja nicht
dauernd laufen, wenn ich zur Arbeit bin), die natürlich auch auf
Wochentage eingeht. Temperaturkurve bitte in 3 Ausführungen "bin da",
"bin nicht da", "Freundin ist da, daher bitte etwas wärmer".
Das ganze garniert mit einem LCD, Drehencoder und Menüsteuerung.
Wie siehts jetzt mit deinen Registern aus?
Moby schrieb:> Cyblord ---- schrieb:>> Eine Hochsprache>> erfordert am Ende viel mehr Können, weil die abstrakten Möglichkeiten>> vielfältiger sind.>> Richtig! Als Hobbybastler kann ich aber fragen: Braucht es das?> Bei Millionen einfacher Steuerungsanwendungen?
Das geht am Kern des Problems vorbei.
Die Frage lautet nicht "einfach oder nicht einfach".
Die Frage lautet: muss ich auch noch den letzten Taktzyklus aus dem
Programm rausholen oder nicht?
Wenn es für meine Steuerung keine Rolle spielt, ob die Regelschleife
10µs länger dauert oder nicht, weil das bei den mechanischen
Unzuverlässigkeiten des Systems völlig untergeht, dann braucht auch kein
Mensch das feilschen um Taktzyklen. Siehe zb dein LED-Beispiel: völlig
uninteressant, ob das 10 Prozessortakte schneller geht oder nicht. Kein
Mensch kann den Unterschied ohne Messmittel feststellen.
Karl Heinz schrieb:> Dann frag ich mich, was der Spruch von wegen... Stört natürlich das> Weltbild des C-Evangeliums ...> eigentlich sollte?
Eine Anspielung auf
Jörg Wunsch schrieb:> Moby schrieb:>> Asm formuliert klar, einfach, eindeutig.>> Bitte eröffne deinen eigenen Assembler-Evangelismus-Thread.Karl Heinz schrieb:> Immerhin ist das einer der wesentlichen Kanckpunkte in> der industriellen Softwareentwicklung.
Am Punkt Hobbybedarf/Industriebedarf scheiden sich die Geister.
Karl Heinz schrieb:> Die Frage ist: welche Details muss ich noch im Kopf haben, wenn ich 2> Jahre später wieder an denselben Code gehe.
So gut die Doku so wenig Details nötig im Kopf... Bei Asm wirklich nicht
anders als in Hochsprache.
Karl Heinz schrieb:> Aber das ist mir zu banal.
Triviales Problem- meine Rede. Aber schau nochmal in besagten Thread ;-)
Für einen Vergleich hinsichtlich Speed und Codebedarf langt das völlig.
Karl Heinz schrieb:> Die einzig interessante Frage lautet:
wie solls in C++ einfacher gehen? Unbeantwortet.
Karl Heinz schrieb:> Wie siehts jetzt mit deinen Registern aus?
Das weiß ich nicht und habe leider auch keine Zeit und keinen Bedarf, es
herauszufinden. Die Aufgabenstellung klingt anspruchsvoll,
möglicherweise hast Du ja den Code zuhause schon am Laufen ;-) Was ich
weiß ist, daß ich für meine Heizungssteuerung (Fernheizung) nur einen
Bruchteil dieses Aufwands treiben muß.
Karl Heinz schrieb:> Die Frage lautet nicht "einfach oder nicht einfach".
Doch. Die Frage lautet 'einfach oder nicht einfach'.
Einfach ist, die paar Dutzend Asm-Instruktionen auf eine schön
überschaubare Controllerhardware anzusetzen. Schwieriger ist, erst
Hunderte Seiten C-Literatur dafür in den Kopf zu bekommen, die
Entwicklungsumgebung unnütz aufzublasen und Code-Controlle an einen zu
konfigurierenden Compiler abzugeben.
Karl Heinz schrieb:> dann braucht auch kein> Mensch das feilschen um Taktzyklen. Siehe zb dein LED-Beispiel:
Nein, siehe dieses Threadthema! Was mein LED-Beispiel angeht - es geht
dort nicht um die Prozessortakte. Es geht um eine konkrete
Aufgabenstellung und die prinzipielle Frage, ob das in Hochsprache
genauso kurz und schnell hinzubekommen ist. Versuch doch mal. Wenns bloß
10 Minuten dauert...
Moby schrieb:> Doch. Die Frage lautet 'einfach oder nicht einfach'.> Einfach ist, die paar Dutzend Asm-Instruktionen auf eine schön> überschaubare Controllerhardware anzusetzen. Schwieriger ist, erst> Hunderte Seiten C-Literatur dafür in den Kopf zu bekommen, die> Entwicklungsumgebung unnütz aufzublasen und Code-Controlle an einen zu> konfigurierenden Compiler abzugeben
Als nächstes erzählst du uns, dass du keinen Führerschein hast, weil der
Straßenverkehr viel zu komplex ist und die Verkehrsregeln viel zu
umfangreich sind.
TriHexagon schrieb:> Als nächstes erzählst du uns, dass du keinen Führerschein hast, weil der> Straßenverkehr viel zu komplex ist und die Verkehrsregeln viel zu> umfangreich sind.
Und für den Hobbybereich reicht es sich nicht mehr als 100m vom Haus zu
entfernen. Damit ist gezeigt: Laufen reicht völlig und ist an Einfacheit
nicht durch ein Auto zu schlagen.
DAS ist seine ganze Argumentation und damit bekommt er immer wieder
Leute die den Fehler machen mit ihm zu disktutieren.
> Einfach ist, die paar Dutzend Asm-Instruktionen auf eine schön> überschaubare Controllerhardware anzusetzen.
Damit hat er natürlich recht. Nur was kann man unter solchen Prämissen
schon machen? Seine Blinky Programme scheinen ihm Funktion genug. Dann
finde ich es völlig korrekt dass er bei ASM bleibt. C wäre dafür
Overkill.
Nur wie bekommt man die, von Karl-Heinz oben beschriebene Steuerung, in
ein paar Dutzend ASM Anweisungen? Ich würde das gerne mal sehen.
Ich schlage vor, Moby zeigt uns mal sein komplexestes Projekt. Dann
zählen wir mal die Instruktionen. Ich bin gespannt was der Moby in ein
paar Dutzend ASM Anweisungen (ich würde sagen <50 wären wohl ok?) für
magische Funktionalität verpackt hat.
Cyblord ---- schrieb:> TriHexagon schrieb:>> Als nächstes erzählst du uns, dass du keinen Führerschein hast, weil der>> Straßenverkehr viel zu komplex ist und die Verkehrsregeln viel zu>> umfangreich sind.>> Und für den Hobbybereich reicht es sich nicht mehr als 100m vom Haus zu> entfernen. Damit ist gezeigt: Laufen reicht völlig und ist an Einfacheit> nicht durch ein Auto zu schlagen.> DAS ist seine ganze Argumentation und damit bekommt er immer wieder> Leute die den Fehler machen mit ihm zu disktutieren.
Ja damit hast du recht. Mit ihm lässt sich nicht diskutieren, das haben
die letzten Monate immer wieder gezeigt. Er kennt halt nur diese eine
Seite der Medaille und eine Menge Halbwissen, was er mal so
aufgeschnappt hat.
Zum Autovergleich: wie kommt es, dass so viele ein Auto haben, obwohl
Autos doch nur für den kommerziellen Gebrauch sinnvoll sind :P .
Ich habe auch nur hobbymäßig mit Microcontrollern zu tun, trotzdem sehe
ich keinen Grund darin ASM zu verwenden, wenn ich es nicht muss. Ich
brauche bei ASM Code sehr viel länger als bei ASM und die Fehlersuche in
ASM ist oft die Hölle. Mit C programmiere ich AVR, ARM (Cortex) und
x86/x64 ohne etwas neu erlernen zu müssen. Meinen FAT Treiber habe ich
für AVR geschrieben, aber nativ am PC getestet und debuggt. Aber der
Punkt ist doch: ein Code der dasselbe leistet, aber nur ein Viertel der
Laufzeit benötigt ist cool, aber doch nur Spielerei, wenn der langsamere
Code genauso die Anforderungen erfüllt und weniger Arbeitszeit in
Anspruch nimmt.
Karl Heinz schrieb:> Heizungssteuerung. Brenner per PWM angesteuert. Dazu ein DS1820 als> Temperaturaufnehmer. Nein, 2 DS1820. Die Aussentemperatur sollte auch> mit eingehen> Dazu eine Tageszeit abhängige Temperaturkurve (die Heizung soll ja nicht> dauernd laufen, wenn ich zur Arbeit bin), die natürlich auch auf> Wochentage eingeht. Temperaturkurve bitte in 3 Ausführungen "bin da",> "bin nicht da", "Freundin ist da, daher bitte etwas wärmer".> Das ganze garniert mit einem LCD, Drehencoder und Menüsteuerung.>>> Wie siehts jetzt mit deinen Registern aus?
Also für solche langweiligen reinen Fleißaufgaben braucht man doch
nichtmal irgendeinen Interrupt, ich sehe hier auch keinerlei Sachen
drin, die auch nur näherungsweise das Attribut zeitkritisch verdienen
würden. Leicht übertrieben: Das könnte man mit Relais-Logik lösen, wenn
das olle Klappern der Relais nicht so störend wäre...
Das geht also sowas von völlig am Thema des Threads vorbei (zur
Erinnerung: Es ging um Minimierung von Interruptlatenzen), daß es
eigentlich gelöscht gehört.
Bastler schrieb:> Thema war Interrupt-Latenz in C!
Nunja, dabei hat sich ja bereits vor gefühlten 3000 Postings
herausgestellt, daß die Möglichkeiten von C im, darauf positiven Einfluß
zu nehmen, doch arg begrenzt sind und selbst in den besten Inkarnationen
der C-Compiler letztlich doch nur darauf hinauslaufen, zumindest die
exklusiven Teile der ISRs in Asm zu schreiben...
Und selbst wenn das nicht so wäre, bleibt immer noch die Frage,
inwiefern eine Anwendung, die keinerlei Timing-Probleme haben kann,
weil sie schlicht nichts bearbeitet, was wirklich schnell erfolgen muß,
irgendwas dazu beitragen könnte, eben solche zu lösen...
Also mit 3..4 ASM Opcodes da optimieren, wo man's braucht. Trotzdem
versuchen die Ritter des AVR Opcodes ihr Reinheitsgebot durchzusetzen.
In welcher Sprache wohl der AVR-Assembler geschrieben ist? Hoffentlich
was Koscheres!
Bastler schrieb:> Also mit 3..4 ASM Opcodes da optimieren, wo man's braucht.
Also allumfassendes Fazit: Wenn's wirklich effizient sein soll, muß es
am Ende eben doch Asm sein.
> Trotzdem> versuchen die Ritter des AVR Opcodes ihr Reinheitsgebot durchzusetzen.
Ooops? ES wurde nur dargestellt, daß zeitkritische Sachen in Assembler
einfach einfacher zu lösen sind, weil man sich eben nur mit den
Timing-Constraints selber auseinander setzen muß und nicht auch noch mit
einer Sprache, die Code ohne definiertes Zeitverhalten produziert und
zumindest im Bezug auf die Nutzung von Interrupts auch noch überaus
ineffizent ist, weil sie ihre verschissene Runtime-Umgebung zu mehr oder
weniger großen Teilen über den Kontextwechsel hieven muß, sobald es in
der ISR über allereinfachste Zuweisungs-Operationen hinausgeht.
Es gibt auch Dinge, die ich "hasse" im Sinne von "selbst nicht machen
mag". Nur warum sollte ich andere davon abhalten, diese Dinge zu machen.
Solang mich keiner dazu zwingt. Manche zwingen aber. Und zwar sich
selbst zur Missionierung anderer. Das nervt!!
c-hater schrieb:> Also allumfassendes Fazit: Wenn's wirklich effizient sein soll, muß es> am Ende eben doch Asm sein.
So wie es aussieht ist das Fazit wohl eher, dass die ASM Fraktion ob der
gestellten Aufgabe in heftige Rückzugsgefechte gerät. Die oben
skizzierte Steuerung sehe ich momentan hier weder in ASM noch in
Relaislogik realisiert.
Natürlich nur weil es Offtopic ist. Versteht sich Jungs.
By the way, welches Relais würdest du für die DS18B20 Ansteuerung
empfehlen?
Also die Sache scheint damit wohl abgehakt. Tragts mit Fassung.
Moby schrieb:> Versuch doch mal. Wenns bloß> 10 Minuten dauert...
Oder auch nicht ;-)
Natürlich idt es immer einfach, unrealistische Forderungen in den Raum
zu werfen und bei Nichterfüllung als "Totschlagargument" herzunehmen.
c-hater schrieb:> Also für solche langweiligen reinen Fleißaufgaben braucht man doch> nichtmal irgendeinen Interrupt
Darauf tippe ich jetzt auch mal. Die eigentliche Herrausforderung dürfte
nicht die Registerverwendung sein, sondern die Regelung des
Temperaturverlaufs dem Hausherren recht zu machen.
Cyblord ---- schrieb:> Ich schlage vor, Moby zeigt uns mal sein komplexestes Projekt.
Ich schlage vor, zeig Du erst mal irgendwas ;-)
> Ich bin gespannt was der Moby in ein> paar Dutzend ASM Anweisungen (ich würde sagen <50 wären wohl ok?) für> magische Funktionalität verpackt hat.
Ich bin mir gar nicht mal sicher, ob Du das so schnell herausfindest ;-)
Bastler schrieb:> Manche zwingen aber. Und zwar> sich selbst zur Missionierung anderer. Das nervt!!
Aber woher denn... Zwingen können nur echte Tatsachen, wie es die
effiziente, zeit-und codesparende Asm Programmierung eine ist. Daher
sehe ich mich auch nicht mit irgendeinem Glauben hausieren. Weißt Du was
mich nervt? Wenn künstliche Verkomplizierung einfacher Sachverhalte
inklusive real verschlechterter Code- Effizienz als unbedingter
Fortschritt verkauft wird.
TriHexagon schrieb:> Als nächstes erzählst du uns, dass du keinen Führerschein hast, weil der> Straßenverkehr viel zu komplex ist
Man hat, was man braucht. Nicht mehr. Nicht weniger. Wer am
Straßenverkehr teilnehmen will braucht einen Führerschein.
Cyblord ---- schrieb:> Und für den Hobbybereich reicht es sich nicht mehr als 100m vom Haus zu> entfernen.
Unfug. Wenn ich weiter wegwill brauch ich ein Verkehrsmittel und ich
werde dessen Notwendigkeit auch nicht in Abrede stellen ;-)
Lothar Miller schrieb:> Und weil man sowieso nur zu Fuss die kürzeren und "schnelleren"> Wege gehen kann...
Hey da ist was dran! Gerade im Verkehrsstau (...hochkomplexer OOP
Lösungen :-)
Moby schrieb:> Cyblord ---- schrieb:>> Ich schlage vor, Moby zeigt uns mal sein komplexestes Projekt.>> Ich schlage vor, zeig Du erst mal irgendwas ;-)
Schade wenn man nur ne dicke Fresse hat gell Moby ;-) Immerhin sieht das
jetzt auch jeder.
Ich habe in der Artikelsammlung z.B. ein C-Projekt eines M-Link
Telemetrie Variosensors vorgestellt. Mit allem Code. Du darfst gerne
Beweisen dass du dieselbe Funktionalität mit wenig dutzend Opcodes in
ASM hin bekommst.
> Ich bin mir gar nicht mal sicher, ob Du das so schnell herausfindest ;-)
Wie kommst du denn darauf? Ich kann sehr wohl ASM und habe früher schon
einiges damit programmiert.
Aber wo nichts ist, kann man nichts herausfinden gelle?
> Unfug. Wenn ich weiter wegwill brauch ich ein Verkehrsmittel und ich> werde dessen Notwendigkeit auch nicht in Abrede stellen ;-)
Ach auf einmal? Das könnte man ja fast so interpretieren dass für
komplexere Projekte doch C die bessere Wahl ist. Das sagen dir hier aber
doch alle die ganze Zeit. Sehr gut.
Cyblord ---- schrieb:> Ich habe in der Artikelsammlung z.B. ein C-Projekt eines M-Link> Telemetrie Variosensors vorgestellt. Mit allem Code. Du darfst gerne> Beweisen dass du dieselbe Funktionalität mit wenig dutzend Opcodes in> ASM hin bekommst.
Läuft es jetzt wieder auf "und meiner ist größer als deiner" hinaus?
Sorry Cyblord, diese Mentalität ist mir fremd. Auch webn ich Deine
pointierte Beiträge sonst sehr schätze...
> Aber wo nichts ist, kann man nichts herausfinden gelle?
Mein kleines Beispiel weiter oben hast Du natürlich geflissentlich
übersehen ;-)
> Das könnte man ja fast so interpretieren dass für> komplexere Projekte doch C die bessere Wahl ist. Das sagen dir hier aber> doch alle die ganze Zeit. Sehr gut.
Das bestreitet glaub ich niemand. Die Frage ist doch, wo beginnt
Komplexeres?
c-hater schrieb:> Bastler schrieb:>>> Thema war Interrupt-Latenz in C!>> Nunja, dabei hat sich ja bereits vor gefühlten 3000 Postings> herausgestellt, daß die Möglichkeiten von C im, darauf positiven Einfluß> zu nehmen, doch arg begrenzt sind
Es hat sich heraus gestellt dass er gefälligst mal seine ISR zeigen
sollte, damit man mal sieht, woher eigentlich seine Push/Pop Orgien
kommen.
> weil sie schlicht nichts bearbeitet, was wirklich schnell erfolgen muß,> irgendwas dazu beitragen könnte, eben solche zu lösen...
Das spielt auf mich an. Von Mobb kam doch die Aussage: was soll ich mich
mit C rumquälen, ich leg einfach jede Variable in ein Register und gut
ists. Bei simplen Programmen langt das ja auch. Wirds aber komplexer
kommt er um Register-Belegunsschemata nicht rum - und damit auch um sehr
wahrscheinlich nicht um ein paar Push und Pop in einer ISR.
Wenn man natürlich nichts komplexeres macht, als mit 2 Taster 3 LED zu
schalten, dann ist klar, dass das in Assembler kein Problem ist.
Moby schrieb:>> Das bestreitet glaub ich niemand.
Doch eigentlich tust DU das die ganze Zeit.
> Die Frage ist doch, wo beginnt> Komplexeres?
Na z.B. bei einem Telemetriesensor, einer Heizungssteurung, eines
Kommunikationsstacks. Praktisch bei so ziemlich jeder sinnvollen
Anwendung die über dein Blinkprogramm hinaus geht.
Du hast jetzt also ernsthaft jeden C Thread mit deinem nervenden ASM
Scheiß zerlabert, nur weil du für deine trivialen Blinkprogramme kein C
brauchst? Ernsthaft? Das war deine Aussage? WOW.
Karl Heinz schrieb:> Von Moby kam doch die Aussage: was soll ich mich> mit C rumquälen, ich leg einfach jede Variable in ein Register und gut> ists.
Das hast Du mir jetzt in den Mund gelegt. Natürlich kann man nicht alle
Variablen in Registern vorhalten. In Asm aber meist die C-typischen
Push/Pop Orgien vermeiden!
> Wenn man natürlich nichts komplexeres macht, als mit 2 Taster 3 LED zu> schalten, dann ist klar, dass das in Assembler kein Problem ist.
Was soll diese Hrrablassung, Karl Heinz. Ich denk mal das weißt Du
besser ;-(
Moby schrieb:> Moby schrieb:>> Versuch doch mal. Wenns bloß>> 10 Minuten dauert...>> Oder auch nicht ;-)
Soll ich?
OK. Ich geh den Thread noch zu Ende durch, dann setz ich mich ran.
> Natürlich idt es immer einfach, unrealistische Forderungen in den Raum> zu werfen und bei Nichterfüllung als "Totschlagargument" herzunehmen.
Was ist daran unrealistisch?
> Darauf tippe ich jetzt auch mal.
Interessanterweise hatte ich in dem Programm sogar einen Interrupt. :-)
zum einen läuft die Encoderauswertung drüber, zum anderen gibt es da
noch eine Zutat, die ich nicht erwähnt hatte: Die Systemuhr läuft
Interrupt-getrieben vom 230V Netz.
> Die eigentliche Herrausforderung dürfte> nicht die Registerverwendung sein, sondern die Regelung des> Temperaturverlaufs dem Hausherren recht zu machen.
Nö. Die stellt sich der Hausherr selber ein. Dazu hat man ja ein LCD
samt Drehencoder und ein Menüsystem, so dass man täglich auf die Minute
festlegen kann, wann die Heizung auf welche Temperaturvorgabe gehen
soll. Und zum Komfort kann man auch noch einstellen, ob diese
Tageseinstellung für jeden Wochentag extra gelten soll, oder für alle
Werktage (und Samstag + Sonntag haben ihre jeweils eigenen
Einstellungen) oder für alle Wochentage gemeinsam. Natürlich alles im
Eeprom gespeichert. Der Platz im Mega16 ist das schon etwas eng
geworden. Für einen Web-Server hats nicht mehr gereicht aber für eine
Fernsteuerung per UART reichte es noch. Muss halt der PC-Server per UART
das Web-Interface zur Heizung spielen.
Bin in Summe 3 Abende daran gesessen :-)
Cyblord ---- schrieb im Beitrag #4017591
> Na z.B. bei einem Telemetriesensor, einer Heizungssteurung, eines> Kommunikationsstacks. Praktisch bei so ziemlich jeder sinnvollen> Anwendung die über dein Blinkprogramm hinaus geht.
Natürlich, natürlich. Praktisch jede Anwendung... Ich verrat Dir
trotzdem nicht, was ich alles in welcher Menge in Asm progge... Oh Mist,
von meiner Heizungssteuerung war ja schon in einem anderen Thread die
Rede ;-(
Karl Heinz schrieb:> Soll ich?
Dann aber bitteschön eigenständig und nicht nur Peter D's
Entprellroutine ansteuern ;-)
> Interessanterweise hatte ich in dem Programm sogar einen Interrupt. :-)> zum einen läuft die Encoderauswertung drüber...
Also Programm doch schon fertig, ist ja unfair. Aber von mir
verlangen... Ich hätt da auch noch bei so einigen Projekten Arbeit zu
delegieren ;-)
Moby schrieb:> Karl Heinz schrieb:>> Soll ich?>> Dann aber bitteschön eigenständig und nicht nur Peter D's> Entprellroutine ansteuern ;-)
Tja. Siehst du.
Das ist eben einer der grossen Vorteile: ich kann Code mehr oder weniger
fix&fertig aus dem Hut zaubern. Copy&Paste genügt. Ich brauch mich nicht
mit nicht passenden Registerbelegungen rumärgern, muss mir nicht merken
welcher Wert beim Funktionsaufruf in welches Register muss, etc.
Soviel zum Thema: Auch Entwicklungszeit kostet was.
Ich hab in einem Projekt wirkich besseres zu tun, als mich um die 150-te
Tastenentprellung zu kümmern. So spannend ist das Thema dann auch wieder
nicht. Die Zeit steck ich lieber in eine ordentliche Menüführung.
Du schreibst ja auch nicht in jedem Projekt die 16*16 Bit Multiplikation
neu. Oder ?
Und ich denke, du glaubst mir auch so, dass ein
1
...
2
3
while(1){
4
5
if(get_keystate(1<<KEY_0))
6
LED_PORT|=(1<<LED1);
7
else
8
LED_PORT&=~(1<<LED1);
9
10
if(get_keypress(1<<KEY_2))
11
LED_PORT!=(1<<LED2);
12
13
...
14
}
nicht wirklich das große Problem ist. Auch wenn ich das jetzt nicht noch
mit den Entprellroutinen aus dem Fundus lauffähig pimpe :-) Und
komplexer wirds nicht.
> Also Programm doch schon fertig, ist ja unfair. Aber von mir> verlangen...
Ach komm. Das war aber sowas von klar, dass du da nichts machen würdest.
Da sitzt du nämlich ein paar Wochen drann, bis du die ganzen
Registerfehler aus der Datenverwaltung raus hast. Denkst du echt, ich
hätte noch nie was in Assembler programmiert? Da täuscht du dich. Ich
hab schon genug gemacht und ich kenn auch all die kleinen Fallen und
Probleme die unweigerlich mit wachsender Komplexität entstehen. Mal
vergisst man dort einen Pop und zerschiesst sich den Stack, mal ist das
Flag im Statusregister, das eine halbe Stunde vorher noch das Ergebnis
des Vergleichs beinhaltet hat zerschossen, weil man unbedacht 1, 2
Befehle dazwischen geschoben hat. Dann braucht man mal schnell ein
Hilfsregister für eine kurze Zwischenrechnung und vergisst, dass da noch
ein Ergebnis drinnen steht, das 30 Anweisungen später eigentlich noch
gebraucht würde. etc. etc. Been there, done that. Gerade wenn die
Entwicklungszeiten länger werden, sind es genau diese Details, die man
alle im Kopf haben müsste und doch nach ein paar Tagen nicht mehr hat.
Die meisten guten C-Programmierer hier können meistens auch ziemlich gut
Assembler programmieren. Das scheinst du gerne zu vergessen.
Im übrigen hatte ich grade einen Versuch gemacht.
Das allererste AVR Programm, dass ich je gesehen habe, war dieses hier
Beitrag "AVR-Lauflicht"
Kann mich noch gut erinnern, wie ich das analysiert habe. Von AVR hatte
ich keine Ahnung, PWM kannte ich nur vom hörensagen. War eine spannende
Sache rauszukriegen, wie der Überblendeffekt zustande kommt.
Ich hab das vorhin mal nach C übersetzt, weil es mich interessiert hat,
was der Compiler draus macht.
Wenn ich mal das übliche Vorgeplänkel weg lasse, wo die Interrupt Vektor
Tabelle aufgesetzt wird und die Data bzw. BSS Sektion initialisiert wird
(ok, das könnte man dem Ding vorwerfen: der Initialisiercode ist im
Programm drinnen, obwohl es nichts zu initialisieren gibt), dann bleibt
das hier übrig
1
48: 8f e1 ldi r24, 0x1F ; 31
2
4a: 87 bb out 0x17, r24 ; 23
3
4c: 90 e0 ldi r25, 0x00 ; 0
4
4e: 80 e0 ldi r24, 0x00 ; 0
5
50: 2d ef ldi r18, 0xFD ; 253
6
52: 3e ef ldi r19, 0xFE ; 254
7
54: 40 e0 ldi r20, 0x00 ; 0
8
56: 5e ef ldi r21, 0xFE ; 254
9
58: 8f 5f subi r24, 0xFF ; 255
10
5a: 86 39 cpi r24, 0x96 ; 150
11
5c: 69 f4 brne .+26 ; 0x78 <main+0x30>
12
5e: 9f 5f subi r25, 0xFF ; 255
13
60: 96 39 cpi r25, 0x96 ; 150
14
62: 81 f4 brne .+32 ; 0x84 <main+0x3c>
15
64: 82 2f mov r24, r18
16
66: 88 0f add r24, r24
17
68: 81 60 ori r24, 0x01 ; 1
18
6a: 85 ff sbrs r24, 5
19
6c: 85 2f mov r24, r21
20
6e: 32 2f mov r19, r18
21
70: 28 2f mov r18, r24
22
72: 2f 71 andi r18, 0x1F ; 31
23
74: 94 2f mov r25, r20
24
76: 06 c0 rjmp .+12 ; 0x84 <main+0x3c>
25
78: 98 17 cp r25, r24
26
7a: 10 f4 brcc .+4 ; 0x80 <main+0x38>
27
7c: 38 bb out 0x18, r19 ; 24
28
7e: ec cf rjmp .-40 ; 0x58 <main+0x10>
29
80: 28 bb out 0x18, r18 ; 24
30
82: ea cf rjmp .-44 ; 0x58 <main+0x10>
31
84: 84 2f mov r24, r20
32
86: fc cf rjmp .-8 ; 0x80 <main+0x38>
und ich finde: da kann man nicht meckern. Das schenkt sich nicht viel,
auch wenn mir da jetzt ein paar dubiose Sequenzen auffallen, die man
besser schreiben könnte. Aber was solls. Schnell genug ist das Teil auf
jeden Fall und ob ich jetzt den DELAY auf 150 oder auf 149 setze um eine
mir genehme Umlaufgeschwindigkeit zu kriegen ist sowas von egal.
Ich habe bei einer Heizungssteuerung (sic) mal eine abgesetzte Station
in Assembler programmiert. Also
- RS485 Slave per Interrupt
- Text-LCD Ausgabe
- DS18B20/S20, Umrechnung 1/16 in 1/10 Grad
- Schalterabfrage (PeDa Version)
- Abfrage einer DCF77 Uhr
Summe ~1300 Bytes Code, Tiny2313. Im RAM landeten nur Callstack und
UART-Puffer. Alle Variablen passten in Register, ein paar waren noch
frei. In dieser Dimension geht das mit AVR recht gut und flüssig, d.h.
so lange die Register ausreichen. Bis auf die Temperaturumrechnung ist
das auch nahezu reiner 8-Bit Code, entsprechend übersichtlich.
Die Verwendung von Assembler war Vorsatz, ich wollte es so. In C wärs
vielleicht klüger, keinen 2313 zu nehmen, wird sonst vmtl. knapp. Die
Zentrale war in C/C++ geschrieben, mit RTOS-Kernel in einem Mega32.
Karl Heinz schrieb:> Das ist eben einer der grossen Vorteile: ich kann Code mehr oder weniger> fix&fertig aus dem Hut zaubern.
Und Du meinst, ich nicht? Nun gehört auch eine Entprellung beliebig
ausgewählter Portpins dazu, samt Gerüst für Press/Release Routinen und
Drückzeit ;-)
Denn eins ist wohl klar : Die einzelne Asm-Lösung an sich gewinnt in
punkto Entwicklungszeit meist keinen Blumentopf. Den gewinnt sie erst im
Paket mit allerlei Standard Routinen in der Hinterhand, die man über die
Jahre aufbaut.
> hab schon genug gemacht und ich kenn auch all die kleinen Fallen und> Probleme die unweigerlich mit wachsender Komplexität entstehen. Mal> vergisst man dort einen Pop und zerschiesst sich den Stack, mal ist das> Flag im Statusregister, das eine halbe Stunde vorher noch das Ergebnis> des Vergleichs beinhaltet hat zerschossen, weil man unbedacht 1, 2> Befehle ...
Das möchte ich auch nicht bezweifeln. Meine Erfahrung über die Jahre ist
aber die: Mit einem gesunden Fundus an Hardware-Ansteuerungs-,
Zahlen/String Umwandlungs- und allerhand weiterer nützlicher Routinen,
zweitens einer ausgereiften Softwaresystematik und drittens schließlich
dem Beharrenkönnen bei einer immer besser beherrschten Architektur
schließt Asm zumindest bei nicht allzu komplizierten Problemstellungen
in jeder Hinsicht zur Hochsprache auf- unter Beibehaltung der
Asm-typischen Vorteile versteht sich.
Moby schrieb:> Mit einem gesunden Fundus an Hardware-Ansteuerungs-,> Zahlen/String Umwandlungs- und allerhand weiterer nützlicher Routinen,
Yep. Und da finde ich es ganz nett, die praktisch gleichen Routinen auf
AVR und ARM native/thumb verwenden zu können, wie ein leichtes printf,
DS18x20, Text-LCD usw.
A. K. schrieb:> Ich habe bei einer Heizungssteuerung (sic) mal eine abgesetzte> Station in Assembler programmiert.
Kann ja gar nicht sein... Behauptet zumindest Cyblord ;-)
Moby schrieb:> Karl Heinz schrieb:>> Das ist eben einer der grossen Vorteile: ich kann Code mehr oder weniger>> fix&fertig aus dem Hut zaubern.>> Und Du meinst, ich nicht? Nun gehört auch eine Entprellung beliebig> ausgewählter Portpins dazu, samt Gerüst für Press/Release Routinen und> Drückzeit ;-)> Denn eins ist wohl klar : Die einzelne Asm-Lösung an sich gewinnt in> punkto Entwicklungszeit meist keinen Blumentopf. Den gewinnt sie erst im> Paket mit allerlei Standard Routinen in der Hinterhand, die man über die> Jahre aufbaut.
Keine Frage.
Bleibt aber immer noch das Problem, dass du die Routinen nicht einfach
so copy&paste übernehmen kannst. Denn normalerweise passen die
Registerbelegungen der einzelnen Funktionsgruppen dann eben doch nicht
zusammen :-)
Du kannst mir aber gerne zb ein Menüsystem zeigen, dass mehrstufige
Menühierarchien verwalten kann, Werte anzeigen und ändern. Kannst dazu
gerne auch deine Tastenroutinen und LCD Funktionen benutzen.
(Ok, ich gebs zu. Ich such mir natürlich Dinge raus, von denen ich
ausgehen kann, dass du nie und nimmer mit den Registern auskommen wirst
und entweder SRAM oder Flash mit einbeziehen musst. Womit dann das Thema
Datenstrukturen schlagend wird, was in Assembler dann schon ein wenig
Umsicht erfordert)
> schließt Asm zumindest bei nicht allzu komplizierten Problemstellungen> in jeder Hinsicht zur Hochsprache auf- unter Beibehaltung der> Asm-typischen Vorteile versteht sich.
Tja. und genau da liegt das Problem. In der überwiegenden Mehrheit der
Fälle braucht man eben nicht auch noch den letzten Taktzyklus aus dem
Programm rausholen. Womit sich der Vorteil dann recht schnell eher in
Luft auflöst. Denn wenn du mal ehrlich bist: Ob in deinem Tastenbeispiel
die ISR 10 Takte länger braucht oder nicht, ist Jacke wie Hose.
Karl Heinz schrieb:> Bleibt aber immer noch das Problem, dass du die Routinen nicht einfach> so copy&paste übernehmen kannst. Denn normalerweise passen die> Registerbelegungen der einzelnen Funktionsgruppen dann eben doch nicht> zusammen :-)
Nicht immer, aber oft. Das gehört zum Punkt Softwaresystematik. Die
Datenübergabe findet aber auch "standardisiert" über fixe Puffer statt.
Puffer, aus denen sich weitgehend unabhängige Bausteine in einem
Timerinterrupt dann bedienen (UART/TWI/Displayausgaben z.B.)
> Du kannst mir aber gerne zb ein Menüsystem zeigen, dass mehrstufige> Menühierarchien verwalten kann...
Nein, das kann ich nicht weil schlichtweg bislang keine
Notwendigkeit bestand. Ich mags lieber dezentral, nicht tausend
Funktionen unter einem Dach. Dazu langte mir bislang auch ein einfaches,
scrollendes Menü auf einem 16x2 Display. Aktueller ist freilich ein
schönes Webinterface- oder Bedienlösungen auf PC Basis.
> Tja. und genau da liegt das Problem. In der überwiegenden Mehrheit der> Fälle braucht man eben nicht auch noch den letzten Taktzyklus aus dem> Programm rausholen. Womit sich der Vorteil dann ...
Problem? Entweder braucht man es bei zeitkritischen Vorgängen
(Threadthema!) wirklich oder man nimmt den Vorteil so mit und
Können wir uns einfach darauf einigen, in Zukunft die bissigen
Zwischenrufe in C-Threads zu unterlassen, die nichts zum jeweiligen
Thema beitragen? Dann wäre schon viel erreicht. Wir alle sind es euch
doch vergönnt, wenn ihr Spass daran habt, eine halbe Stunde lang
auszuknobeln, wo man in 20 Anweisungen noch 2 Taktzyklen finden kann,
die niemand wirklich vermisst.
Ich versprech auch hoch und heilig, ich werde in Assembler Threads nie
die Aussage fallen lassen, dass man das in C in einem Viertel der Zeit
schon längst fertig hätte.
Karl Heinz schrieb:> Können wir uns einfach darauf einigen, in Zukunft die bissigen> Zwischenrufe in C-Threads zu unterlassen, die nichts zum jeweiligen
Ich will guten Willen demonstrieren, wenn nicht gerade das Blaue vom
Himmel an den Haaren herbei gezogen wird ;-)
> Wir alle sind es euch> doch vergönnt, wenn ihr Spass daran habt, eine halbe Stunde lang> auszuknobeln, wo man in 20 Anweisungen noch 2 Taktzyklen finden kann,> die niemand wirklich vermisst.
Das ist aber schön, Karl Heinz.
Nur war das gar nicht das Thema.
> Ich versprech auch hoch und heilig, ich werde in Assembler Threads nie> die Aussage fallen lassen, dass man das in C in einem Viertel der Zeit> schon längst fertig hätte.
Das kann dort gerne jedermann behaupten und ich werde mir wieder die
Zeit nehmen, mich damit auseinanderzusetzen.
Ich würde vorschlagen man einigt sich nun endlich mal auf eine
Aufgabenstellung, die man auch Au nem Steckbrett aufbauen kann und dann
mal los: ASM vs. C, wobei die Anforderung natürlich Funktion,
Wartbarkeit und Codegrösse bzw. Geschwindigkeit ist. Dann ist ein für
alle mal Ruhe.
Anschließend macht man einen Artikel davon.
A. K. schrieb:> Die Verwendung von Assembler war Vorsatz, ich wollte es so. In C wärs> vielleicht klüger, keinen 2313 zu nehmen, wird sonst vmtl. knapp.
So ist es heutzutage. Seinerzeit gab es den AT90S2313, wo mit C nicht
viel auszurichten war bei 2k Flash, die aber auch recht übersichtlich in
Assembler programmiert werden konnten. Gut, mit Kleckern ist es heute
vorbei.
Was mich speziell an der ISRs beim AVR in C stört, ist das elende
'Gepusche' der Register. Die Ursache dafür ist oben schon erwähnt.
Beispiel: eine Timer-ISR, die alle 10 ms aufgerufen wird und völlig
zeitunkritisch ist, kann man ja ruhig etwas umfangreicher gestalten. Nur
für die ersten Mikrosekunden nach Aufruf der ISR sind alle weiteren ISRs
gesperrt. Das Timerflag wird mit Aufruf der ISR automatisch gelöscht,
sodaß als erster Befehl gleich ein 'sei' stehen könnte, um die Priorität
herabzusetzen. (Ich darf das!)
In C geht das so nicht, wodurch man zwangsläufig per Assembler zumindest
den ISR-Kopf anpassen muß.
Karl Heinz schrieb:> Gut.> Dann sind das 2 Beispiele.> Sonst noch was?
Noch eins: PWM per Software, die (auch mehrkanalig) mit hoher Taktrate
arbeiten muß.
Im Übrigen sind viele Teile einer C-Bibliothek ebenfalls in Assembler
geschrieben, selbst die Grundrechenarten bei float. Jeder Takt der hier
eingespart werden kann, zahlt sich in höherer Geschwindigkeit eines
C-Programmes aus.
> in C geht das nicht...
Dann würd ich mich mal informieren, was in C auf dem AVR so alles geht.
Hier ist ein guter Ort dafür, denn hier gibt es die, die diese
"Programm-Schnipsel-Sammlung" für uns alle gebaut haben.
m.n. schrieb:> Was mich speziell an der ISRs beim AVR in C stört, ist das elende> 'Gepusche' der Register. Die Ursache dafür ist oben schon erwähnt.> Beispiel: eine Timer-ISR, die alle 10 ms aufgerufen wird
Ich sehe das entspannter. Im in C/C++ programmierten Zentralsystem,
einem Mega32/16Mhz, läuft der RTOS-Timer mit 10kHz, wird also alle 100µs
aufgerufen. Daraus können manche Delays von 1-Wire Protokoll per RTOS
abgewickelt werden, statt Warteschleifen. Klar, bei dieser
Interrupt-Rate geht spürbar Rechenzeit drauf. Ist aber genug davon
vorhanden.
> Teile der C-Bibliothek sind in ASM geschrieben...
Noch besser: der Compiler erzeugt auch ASM-Code und danach wird sogar
ein Assembler benutzt, damit die Maschine den auch ausführen kann.
Hat eigentlich schon mal jemand den Atmel Schrieb zum Thema "wie habe
wir den AVR so entworfen, daß ein C-Compiler leichtes Spiel hat. Das ist
kein 51er, wo C entweder 1:1 ASM ist, Nürnberger Schreibweise, oder
Berge von Befehlen notwendig sind um Einfachstes zu machen. Und selbst
da machen das viele mit C.
m.n. schrieb:> So ist es heutzutage. Seinerzeit gab es den AT90S2313, wo mit C nicht> viel auszurichten war bei 2k Flash
Würde ich jetzt nicht behaupten. Hab grad einem RasPi einen I2C-Slave
verpasst. Da der das nicht selbst kann ergab das einen Tiny841 als
I2C-Slave, der dieses I2C in UART-Kommunikation mit dem RasPi umsetzt.
800 Bytes Code, in normalem C.
Allerdings ist ein I2C-Slave tatsächlich genau so eine Stelle, wo
Assembler relevant werden kann. Wenn man das umdrehen muss, d.h. der
RasPi als I2C-Master mit einem AVR als I2C-Slave reden soll. Dank des
clock stretching Bugs des RasPi wirds bei 100kHz I2C-Takt in C verdammt
eng im Interrupt. Da kommt es wirklich auf die µs an.
A. K. schrieb:> Ich sehe das entspannter.
Ich verstehe, Du kommst aus dem südwestdeutschen Raum ;-)
Im Allgemeinen kann man das auch entspannt sehen, aber sobald die UART
noch mit 115 kBd und weitere INTs dazukommen, kann es eng werden.
A. K. schrieb:> Da der das nicht selbst kann, gab das einen Tiny841
Na ja, mit 8 kB Flash in der Hinterhand, kann man 'mutig' sein. Ob es
dann 800 Byte oder 2 kB werden, läßt einen völlig kalt.
m.n. schrieb:> Ich verstehe, Du kommst aus dem südwestdeutschen Raum ;-)
Sind die Restdeutschen alle verkrampfter? ;-)
> Im Allgemeinen kann man das auch entspannt sehen, aber sobald die UART> noch mit 115 kBd und weitere INTs dazukommen, kann es eng werden.
Ok, die läuft mit 38400. 115200 wären aber wohl auch kein Problem, sind
da nur nicht nötig.
> Na ja, mit 8 kB Flash in der Hinterhand, kann man 'mutig' sein. Ob es> dann 800 Byte oder 2 kB werden, läßt einen völlig kalt.
Dessen UART allerdings läuft mit 115200. Bei 7.37MHz.
A. K. schrieb:> Dank des> clock stretching Bugs des RasPi wirds bei 100kHz I2C-Takt in C verdammt> eng im Interrupt. Da kommt es wirklich auf die µs an.
Wo Du das so schreibst, fällt mir noch eine Anwendung ein.
Als der SAA1101 (video sync generator) nicht mehr lieferbar war,
brauchte ich einen Ersatz. Ein ATtin2313 - schön in Assembler
programmiert - war die Lösung. Der mußte auf 67 ns genau arbeiten ;-)
A. K. schrieb:> m.n. schrieb:>> Ich verstehe, Du kommst aus dem südwestdeutschen Raum ;-)>> Sind die Restdeutschen alle verkrampfter? ;-)
Nicht unbedingt. Aber wenn ich mit Hamburg telefoniere, dauert das
Gespräch 2 Minuten. Mit Karlsruhe und dem gleichen Thema >= 20 Minuten
;-)
Ingo schrieb:> Ich würde vorschlagen man einigt sich nun endlich mal auf eine> Aufgabenstellung, die man auch Au nem Steckbrett aufbauen kann und dann> mal los: ASM vs. C, wobei die Anforderung natürlich Funktion,> Wartbarkeit und Codegrösse bzw. Geschwindigkeit ist. Dann ist ein für> alle mal Ruhe.
Ich schlage vor, einen LED Bargraph, der je nach Spannung an einem
ADC-Pin den Bargraph steuert. Mit der Option, per Jumper, einen
gefüllten Bargraph oder einfach nur das oberste der angesteuerten LEDs
auszuwählen.
Die ADC-Werte werden per Poti vorgegeben. Die ADC-Werte werden über
einen gleitenden Mittelwert von 2^n gemittelt. Samplefrequenz 1kHz.
Controller wäre noch zu definieren (Mega88?).
Das kann jeder auf nem Breadboard aufbauen und ist mit standard
Bauteilen zu schaffen die jeder in der Bastelkiste hat ;).
Wie wär's?
Zusammenfassend:
- LED Bargraph an PortD
- Analogwert an PC5 oder ähnlich
- Aref = VCC
- Interner OSC
- Modusjumper an PC0
- Atmega88
Ingo schrieb:> Is wohl zu anspruchsvoll ;)
Ganz und gar nicht. Den Level könnte/sollte man eher noch steigern.
Das Problem ist nur: Wer opfert schon seine Zeit dafür? Für eine
spezielle Lösung die man nicht braucht? Sinnvoller ist doch da etwas,
was jeder verwenden kann. Ein konkretes Beispiel hab ich weiter oben
geliefert.
Karl Heinz schrieb:> Die meisten guten C-Programmierer hier können meistens auch ziemlich gut> Assembler programmieren.
Da gebe ich dir erstmal zu 100% Recht.
Du vergisst allerdings, die Gründe für diesen offensichtlichen Fakt zu
erwähnen. Sehr wahrscheinlich vergißt du das genau deshalb, weil die ein
völlig anderes Licht auf diesen Sachverhalt werfen würden...
Karl Heinz schrieb:> Ich such mir natürlich Dinge raus, von denen ich> ausgehen kann, dass du nie und nimmer mit den Registern auskommen wirst> und entweder SRAM oder Flash mit einbeziehen musst. Womit dann das Thema> Datenstrukturen schlagend wird, was in Assembler dann schon ein wenig> Umsicht erfordert)
Ach watt, kaum mehr als in C. Für Datenstrukturen schreibt man sich
einmal ein paar Makros und kann die dann praktisch genauso deklarieren
wie du in C deine structs deklarierst.
Es sieht dann im Endeffekt zwar eher wie eine Pascal-Record-Deklaration
aus, hat aber leider aus denselben technischen Gründen wie bei C (als
Bastard eines Macroassemblers) diese unlogisch verkehrte Reihenfolge von
Typ und Bezeichner...
Karl Heinz schrieb:> Ich versprech auch hoch und heilig, ich werde in Assembler Threads nie> die Aussage fallen lassen, dass man das in C in einem Viertel der Zeit> schon längst fertig hätte.
...oder auch überhaupt keine Chance hat, das Problem zu lösen.
Allein die Existenz von Unmassen von Asm-Code in vielen (eigentlich fast
allen) AVR-C-Programmen zeigt doch absolut überzeugend, daß Asm oft
zwingend NÖTIG ist, um C auf die Beine zu helfen.
Freiwillig tut sich doch kaum ein C-ler Asm an. Wenn sie es doch tun,
kann es nur einen Grund dafür geben: Es ist einfach NÖTIG.
Umgekehrt habe ich noch nie erlebt, daß ein Asm-Programm auf C
ausweichen müßte, um ein konkretes Problem lösbar zu machen...
Ihr C-ler habt es doch angeblich so mit der Logik? Also wie würdest du
denn diese nicht wegzudiskutierenden Tatsachen werten, ohne dich in die
Abgründe logischer Widersprüche zu verstricken?
c-hater schrieb:> Freiwillig tut sich doch kaum ein C-ler Asm an. Wenn sie es doch tun,> kann es nur einen Grund dafür geben: Es ist einfach NÖTIG.
Das ist doch einfach nur noch Getrolle. Provokation, damit endlich die
Schimpfworte fiegen.
Ich hatte oben von einem Projekt berichtet, in dem ich bewusst beides
verwendete. Und zwar nicht weil es nötig war. Da hätte statt des
Tiny2313 auch ein Mega8 reingepasst. Nur war das mein erstes Projekt mit
µCs und da wollte ich einfach mal beide Varianten drin haben, also
einmal Assembler, und einmal das übliche C/C++ (plus simples RTOS, auch
das war nicht zwingend) mit den für mich neuen AVRs.
Hatte schon genug mit Assembler zu tun, und den unterschiedlichsten
Maschinen. Und hatte mir in einem früheren Projekt eigens einen simplen
Compiler gebaut, um dem Programm mehr Struktur und bessere Lesbarkeit
beizubringen. Aber dicht genug am Assembler dran, um die Z80 nicht zu
überfordern, zumal es damals keine brauchbaren C Compiler dafür gab.
Natürlich gibt es Anwendungen, in denen Assembler sinnvoll ist. Und es
kann auch sehr sinnvoll sein, C Code mit einzelnen Assembler-Stücken
anzureichern, beispielsweise zur Unterstützung bestimmter Befehle. GCCs
Methode dazu ist zwar nicht trivial, aber ungemein leistungsfähig, weil
sie sich nahtlos ins C integriert. Eine solche nahtlose Integration von
Assembler-Befehlen in ein C Programm hatte ich selber mal in einem C
Compiler implementiert - und entsprechend genutzt.
Nur: Warum muss man da eine Religion draus machen und alle Leute
beschimpfen, die anders handeln als man selbst? Rübe ab, wie ISIS?
Manche sind eben nicht so religiös, sondern pragmatisch oder auch mal
neugierig.
Karl Heinz schrieb:> Keine Frage.> Bleibt aber immer noch das Problem, dass du die Routinen nicht einfach> so copy&paste übernehmen kannst. Denn normalerweise passen die> Registerbelegungen der einzelnen Funktionsgruppen dann eben doch nicht> zusammen :-)
Ich habe noch nicht eine Zeile Assembler von Moby gesehen, geschweige
denn einen ganzen Code Block. ^^
A. K. schrieb:> Manche sind eben nicht so religiös, sondern pragmatisch oder auch mal> neugierig.
Ja, die pragmatische Problemlösung sollte schon Vorrang haben.
Der konkrete Mensch sollte unter konkreten Voraussetzungen mit konkreten
Anforderungen und konkreten Aufgabenstellungen zunächst mal überhaupt zu
einem akzeptablen Ergebnis kommen.
Die optimale Lösung ist allerdings keine Religion.
Die gibt es wirklich!
F. Fo schrieb:> Ich habe noch nicht eine Zeile Assembler von Moby gesehen, geschweige> denn einen ganzen Code Block.
Jo Foldi, denn musste mal hier a bisserl aufmerksamer sein, nich?
Kleiner Provokateur Du ;-)
Moby schrieb:> Die optimale Lösung ist allerdings keine Religion.> Die gibt es wirklich!
Yep, es gibt sie. Und nicht nur eine. Es gibt mehrere optimale Lösungen,
weil abhängig von Randbedingungen und Betrachter. Und was einstmals eine
optimale Lösung war, das kann sich im Laufe der Zeit als Knieschuss
erweisen (Softwerker können ein Lied davon singen).
c-hater schrieb:> Umgekehrt habe ich noch nie erlebt, daß ein Asm-Programm auf C> ausweichen müßte, um ein konkretes Problem lösbar zu machen...
Oh doch. Ich portiere gerade meinen alten Bassverstärker Controller auf
C, weil ich die Schnauze voll habe und das Projekt immer komplexer wird.
Mit dem Wireless-DMX Szenenkontroller sollte ich das auch machen, habe
aber im Moment keine Lust.
c-hater schrieb:> Allein die Existenz von Unmassen von Asm-Code in vielen (eigentlich fast> allen) AVR-C-Programmen zeigt doch absolut überzeugend, daß Asm oft> zwingend NÖTIG ist, um C auf die Beine zu helfen.
Nö. Zeig mir eine eine Zeile Assembler in meinem 3-Phasen Umrichter...
C ist einfach besser protierbar, und das hat auch schon Karl Heinz
gesagt. Ich habe den Grossteil meiner BLDC FOC vom Mega88 auf den
XMega128/192 und auf STM32 protiert, ohne dafür mehr als ein,zwei Tage
zu benötigen.
War aber klar, das es wieder mal der übliche FlameWar wird - Kinners,
der TE hat nun mal in C geschrieben, deswegen ist die ganze ASM
Diskussion eigentlich völlig unnötig.
c-hater schrieb:> Allein die Existenz von Unmassen von Asm-Code in vielen (eigentlich fast> allen) AVR-C-Programmen zeigt doch absolut überzeugend, daß Asm oft> zwingend NÖTIG ist, um C auf die Beine zu helfen.
Die Formulierung "in (eigentlich fast allen) AVR-C-Programmen" ist eine
unangebrachte polemische Übertreibung. Das stimmt so nicht.
Aber: Die Existenz von ASM-Code in diversen AVR-C-Programmen, wo ASM gar
nicht nötig wäre, zeigt mir eher, wieviele schlechte C-Programmierer
rumlaufen.
Matthias Sch. schrieb:> C ist einfach besser protierbar, [...]
Ein einfaches Beispiel: IRMP läuft auf allen ATMegas, vielen
ATTinys, diversen STM32Fxx, verschiedenen PICs und neuerdings auch auf
ATXmega.
Moby wäre da mit Assembler aufgeschmissen.
Frank M. schrieb:> Die Formulierung "in (eigentlich fast allen) AVR-C-Programmen" ist eine> unangebrachte polemische Übertreibung. Das stimmt so nicht.
In Mobys Betrachtungsweise schon. Da muss nur ein winzigkleines sei()
drin sein und er haut dir dein reines C-Programm als
C/Assembler-Mischung um die Ohren. ;-)
Leute, aus Sicht der Hardware ist Assembler auch nur so eine
Hochsprache. Die Maschine braucht nur Bit-Muster. Wie die zustande
kommen, interessiert die nicht.
BTW, es gab auch Zeiten da hab ich in Assembler programmiert. Als
Compiler, welcher Sprache auch immer, nicht verfügbar/erschwinglich
waren. Aber als ich eine (Raub-)Kopie von Turbo-Pascal in die Finger
bekam, war ASM nur noch ein Stiefkind. Und daß man heute C(++) Compiler
in Qualität eines GCC für "umme" bekommt, und zwar für einige der von
mir beackerten Maschinen (x86,370,AVR), das ist ein großes Glück. Und
für einige anderen gibts es SDCC (Z80/8051). Wenn z.B. meine Tochter in
der Schule 8051-ASM machen darf, dann kann SDCC eine Vorlage liefern
(nicht weitersagen). Oder für die Firmware der 10€ Cypress-LAs, die auch
aus C-Code besteht.
Man kann eben Maschinen quälen, oder sich selbst. Ganz nach persönlichem
Gusto.
Und man kann natürlich immer noch das Ergebnis des GCC als Vorlage für
optimierten ASM-Code an zeitkritischen Stellen dienen.
AVR schrieb im Beitrag #4019438:
> mir beackerten Maschinen (x86,370,AVR)
Einschliesslich Pflege steinalter 360/370er Assembler-Programme aus den
70ern? Muss das ein Spass sein. ;-)
Ja zu Zeiten als man Buchhaltung noch in ASM geschrieben hat ;-)
Aber da gibt es inzwischen (seit 25 Jahren) bessere Sprachen, deren
Nennung den entsprechenden Hassern die Blutdruck durch die Decken gehen
liese. Fängt auch mit A an. Ich benutze immer die Sprache die am
bequemsten ist, unter den gegebenen Umständen: was gibt es, was kostet
es, macht es mir Spaß (als Umkehr von "kotzt es mich an", z.B. COBOL).
Als ich auf der /370 (eigentlich war es ja schon eine /390) unterwegs
war, gab es COBOL oder ASM. Aufgrund der Mächtigkeit der
370er-Maschinenbefehle war für mich ASM immer das einfachere, also ASM.
Als ich sah, was der GCC für AVRs erzeugt, war mein Bedarf nach ASM nur
noch gering.
A. K. schrieb:> Und was einstmals eine> optimale Lösung war
... ist es entweder nie gewesen oder diverse Rahmenbedingungen
(Hardware, neue Anforderungen) haben sich drastisch geändert. Optimal
ist eine Lösung natürlich, wenn sie, um es wieder auf DAS einfache
Beispiel zuzuspitzen, etwa das Ein-Schalten eines Verbrauchers A mit sbi
PORTA,0 angibt. Da gibts nix zu verbessern, nix einzusparen, es ist
simple, merkfähige Systax. So ginge das fortlaufend auch mit
2,4,100,10000 Anweisungen. Der Asm-Programmierer wird es in der Regel
zwar auch nicht 100%ig optimal schaffen, aber er ist da "der Natur nach"
näher dran. Er kann mit den kleinstmöglichen Codeteilen sparend die
schnellsten passgenauesten Softwaregebäude für ein Problem bauen. Der
ASMler muß nicht mit den Beton-Fertigteilen der Hochsprache hantieren,
ohne die Möglichkeit zu verlieren, selbst solche Fertigteile zu
konstruieren. Der C-Werker könnte das natürlich bis zu einem gewissen
Maß unterlaufen, indem er einzelnes in Asm einbaut. Aber zu welchem
Preis? Zur kombinierten C/Asm-Lösung wären zwei Sprachen und damit ein
Vielfaches an Sprachelementen zu beherrschen, inklusive der gesteigerten
Fehlermöglichkeiten. Den ganzen Aufwand sieht der lernende Einsteiger
ganz besonders- der Profi in den besten Lebensjahren dann
selbstbewußt-selbsttäuschend natürlich überhaupt nicht, bis seine
geistigen Fähigkeiten in älteren Jahren dann wieder nachlassen ;-)
Frank M. schrieb:> Ein einfaches Beispiel: IRMP läuft auf allen ATMegas, vielen> ATTinys, diversen STM32Fxx, verschiedenen PICs und neuerdings auch auf> ATXmega.>> Moby wäre da mit Assembler aufgeschmissen.
Ja, ein schönes Programm. Eines wo Hochsprache angebracht ist, weil hier
Portabilität das Primat über Ressourcensparung hat. Du wirst natürlich
zugeben, daß STM32 und selbst ATXmega dafür reichlich überdimensioniert
sind- wenns schon ein kleiner Tiny stemmt.
Cyblord ---- schrieb:> Du hast jetzt also ernsthaft jeden C Thread mit deinem nervenden ASM> Scheiß zerlabert,
Nein. Aber bei passender Gelegenheit ganz dezent darauf hingewiesen, daß
dieses oder jenes Problem (siehe nochmal Threadthema!) jetzt in Asm so
nicht bestünde bzw. einfacher lösbar ist. Daß dieses Salz in die offenen
Wunden der Hochsprache immer gleich so heftige Gegenreaktionen
hervorruft ist zwar verständlich, aber doch nicht meine Schuld ;-)
Moby schrieb:> Cyblord ---- schrieb:>> Du hast jetzt also ernsthaft jeden C Thread mit deinem nervenden ASM>> Scheiß zerlabert,>> Nein. Aber bei passender Gelegenheit ganz dezent darauf hingewiesen, daß> dieses oder jenes Problem (siehe nochmal Threadthema!) jetzt in Asm so> nicht bestünde bzw. einfacher lösbar ist.
Ich finde meine Formulierung besser und passender.
Moby schrieb:> Ja, ein schönes Programm. Eines wo Hochsprache angebracht ist, weil hier> Portabilität das Primat über Ressourcensparung hat.
Ich bin mir nicht sicher, ob Du das mit Assembler wesentlich
ressourcensparender hinbekommen würdest. Auch in C kann man durchaus auf
Ressourcen achtgeben.
> Du wirst natürlich> zugeben, daß STM32 und selbst ATXmega dafür reichlich überdimensioniert> sind- wenns schon ein kleiner Tiny stemmt.
Du denkst verkehrt:
IRMP ist nicht dafür gedacht, die Hauptanwendung auf dem µC zu sein.
Wenn, dann läuft IRMP nur nebenher, um die eigentliche Anwendung zu
unterstützen. Also warum soll ich einen Tiny an einen STM32 anklemmen,
um IR-Befehle zu verstehen?
In Deiner kleinen überschaubaren Welt scheint ein µC nur genau eine
Sache zu tun und sonst gar nichts. Dass man mit µCs auch komplexe
Anwendungen verwirklichen kann, ist offenbar zu Dir noch nicht
vorgedrungen. Ist ja auch klar: Sobald die Sache etwas größer wird,
stößt man mit Assembler ruckzuck an seine Grenzen und der Debug-Aufwand
wird unverhältnismäßig hoch.
P.S.
Nicht, dass Du mich für einen verbohrten ASM-Hasser hältst: Ich verstehe
verschiedene Assembler-Sprachen, in denen ich auch früher programmiert
habe. Aber das ist über 20 Jahre her. Für mich ist das heutzutage
Folter.
Moby schrieb:> Da gibts nix zu verbessern, nix einzusparen,
Doch. Den Assembler kannst du einsparen. Was C gegen Assembler, das ist
Assembler gegen Maschinensprache. Also ist der einzig richtige und
definitiv optimale Ansatz sowas wie handcodiert als Hexfile oder
ROM-Image. Schon hat man einen weitere Sprache eingespart, die weder der
Programmier noch gar die Maschine für die Lösung benötigt und die völlig
unnötige Komplexität einbringt.
> Der C-Werker könnte das natürlich bis zu einem gewissen> Maß unterlaufen, indem er einzelnes in Asm einbaut.
Die wenigsten C-Werker tun das selbst, in Anwendungen. Kaum jemand
programmiert selbst Asm-Module und nur wenige verwenden GCC-Inline-Asms.
Letzteres schon deshalb, weil diese Spezifikationstechnik nicht jedem
liegt.
Was jeder verwendet: Asm-Code, den andere geschrieben haben. Ob das
sei() ist, oder die Delay-Loops usw. Nur interessiert niemanden, wie das
implementiert wurde.
Moby schrieb:> Cyblord ---- schrieb:>> Du hast jetzt also ernsthaft jeden C Thread mit deinem nervenden ASM>> Scheiß zerlabert,>> Nein. Aber bei passender Gelegenheit ganz dezent darauf hingewiesen, daß> dieses oder jenes Problem (siehe nochmal Threadthema!) jetzt in Asm so> nicht bestünde bzw. einfacher lösbar ist. Daß dieses Salz in die offenen> Wunden der Hochsprache immer gleich so heftige Gegenreaktionen> hervorruft ist zwar verständlich, aber doch nicht meine Schuld ;-)
Und? Sollen wir jetzt etwa zum Ausgleich in jedem ASM Problem Thread
schreiben: "Mit einer Hochsprache/C wäre das nicht passiert". Das ist
total sinnvoll, erinnert mich irgendwie an "mit Linux wäre das nicht
passiert". Ja wäre wahrscheinlich nicht passiert, dafür passieren damit
andere Dinge.
Moby schrieb:> Du wirst natürlich zugeben, daß STM32 und selbst ATXmega dafür reichlich> überdimensioniert sind- wenns schon ein kleiner Tiny stemmt.
Häh? Willst du damit sagen ein STM32 ist überdimensioniert für IRMP?
IRMP lässt man doch nicht zum Selbstzweck laufen, sondern weil man
dieses Feature in einem Projekt benötigt.
Du kannst dich drauf verlassen dass der STM32 sich nicht langweilt, weil
der noch ganz andere Dinge beackert.
IRMP ist in nem Projekt eher ne Nebenbaustelle. Etwas, womit der
Programmierer nix zu tun haben will weil es a) nicht die eigentliche
Problemstellung ist und b) weils vor ihm schon zig andere gelöst haben.
Genauso wie FAT, Webserver, bestimmte Algorithmen...
Aber es liegt mir fern dich von irgendwas zu überzeugen. Du hast mir in
diesem Forum schon viele unterhaltsame Stunden beschert, z.B. in der
Arbeit aufn Klo.
Dein Name, und noch ein paar Namen mehr, sind jedesmal ein Garant für
nette Unterhaltung.
Moby schrieb:> sbi PORTA,0
Ist übrigens nicht das geeignetste Programm, um einen Verbraucher zu
schalten. Weil der Code nicht selbstdokumentierend ist. Das ist ein
weiteres Kriterium, wo eine Hochsprache vorne liegt.
Ein
Moby schrieb:> Nein. Aber bei passender Gelegenheit ganz dezent darauf hingewiesen, daß> dieses oder jenes Problem (siehe nochmal Threadthema!) jetzt in Asm so> nicht bestünde bzw. einfacher lösbar ist.
Und du wirfst Vereinbarungen, die man sich vorher erarbeitet hat und
einem definierten, sinnvollen Zweck dienen - z.B. die ABI, von Bord. Die
Konsequenzen daraus unterschlägst du oder redest sie klein. (In dem du
möglichst kleingranuliert die Umgebung und die Situation spezifizierst)
Die Konsequenz aus den Anforderungen ist größerer Code und mehr
Operationen, in sofern richtig. Aber auch mehr und nicht weniger
Kontrolle bei der Einhaltung von Anforderungen. Diese sind nunmal nicht
nur "funktioniert in diesem Aufbau", sondern auch die Verifizierbarkeit,
Dokumentation, Modularität, Wiederverwendbarkeit, Interoperabilität und
funktionale Sicherheit. Ganz zu Schweigen vom Rest des Kapitels über
nicht funktionale Anforderung im Lastenheft.
Nicht umsonst geht man sogar über Hochsprachen wie C noch hinaus und
lässt Code in diesen durch eine Anforderungs/Modulbeschreibung
automatisch erzeugen. Das stellt noch eine weitere Abstraktionsebene dar
und effektiv mehr Code, der aber auch deutlich mehr
Anforderungen/Arbeitskraft gerecht wird.
Dein
> das Ein-Schalten eines Verbrauchers A mit sbi PORTA,0
erfüllt für sich nicht erkennbar die Anforderung vom Einschalten eines
Verbrauchers. Es erfüllt genau das was sbi auf der Platform definiert:
Das setzen eines Bits. Weder ist der Verbraucher definiert (kein
Bezeichner) noch dessen Logik (high/low active). Kurzum: zwischen der
Anweisung "Ein-Schalten eines Verbrauchers" und "sbi PORTA,0" besteht
keine unmittelbare Beziehung.
Natürlich kann man alle Anforderungen auch alleine in Assembler
realisieren. Aber der Aufwand all diese einzelnen Aspekte für die
Struktur, Funktionsblöcke und Anweisung zu betrachten und zu bewerten
übersteigt den Implementierungsaufwand schon um Potenzen.
Maxx schrieb:> Aber auch mehr und nicht weniger> Kontrolle bei der Einhaltung von Anforderungen. Diese sind nunmal nicht> nur "funktioniert in diesem Aufbau", sondern auch die Verifizierbarkeit,> Dokumentation, Modularität, Wiederverwendbarkeit, Interoperabilität und> funktionale Sicherheit. Ganz zu Schweigen vom Rest des Kapitels über> nicht funktionale Anforderung im Lastenheft.
Du redest von Anforderungen industrieller Softwareentwicklung.
Ich bin Hobbybastler. Ein solcher genießt den einzigartigen Luxus,
Hard-und Software ganz zielgerichtet und aufwandsminimiert an seinen
Projekten zu orientieren. Deswegen übersteigt
Maxx schrieb:> der Aufwand all diese einzelnen Aspekte für die> Struktur, Funktionsblöcke und Anweisung zu betrachten und zu bewerten
meinen Implementierungsaufwand nicht um Potenzen, sondern er ist so
schlicht nicht vorhanden. Der beste Test ist immer noch die Praxis- und
wenns dann funktioniert ;-)
Cyblord ---- schrieb:> Ich finde meine Formulierung besser und passender.
Das sei Dir doch zugestanden. Das MUSS ein C-Mensch so empfinden.
Deshalb werde ich jetzt aber keine Beschwerde beim Moderator starten ;-)
Frank M. schrieb:> Auch in C kann man durchaus auf> Ressourcen achtgeben.
... und stößt trotzdem schnell an Grenzen (Threadthema!). Dann geht
höchstens noch die Compiler-Optimierung los. Danke, brauch der ASMler
nicht.
Frank M. schrieb:> In Deiner kleinen überschaubaren Welt scheint ein µC nur genau eine> Sache zu tun
Du meintest LEDs zu schalten? Da irrst Du Dich.
Im ersten Teil hast Du aber Recht. Nur versteh doch, die kleine
überschaubare Welt leitet sich nicht aus simplen Anwendungen, sondern
aus der gezielten Sprachverwendung (und der dadurch auch möglichen
niederfrequenten Controllerauswahl) ab. Das ist glatte, pure Absicht!
Das SOLL so sein!
Frank M. schrieb:> Ist ja auch klar: Sobald die Sache etwas größer wird,> stößt man mit Assembler ruckzuck an seine Grenzen
Ja das tut sie. Beim einen früher, beim anderen später.
Bis dahin aber gibts nichts Besseres ;-)
A. K. schrieb:> Also ist der einzig richtige und> definitiv optimale Ansatz sowas wie handcodiert als Hexfile oder> ROM-Image.
Was soll der Blödsinn? Wer soll das lesen?
Asm vereint zwei faszinierende Eigenschaften:
100% Zugriff auf Instruktionen und Hardwareressourcen- und das Ganze
lesbar!
TriHexagon schrieb:> Sollen wir jetzt etwa zum Ausgleich in jedem ASM Problem Thread> schreiben: "Mit einer Hochsprache/C wäre das nicht passiert".
Gerne. Hab nix dagegen. Die Sorte Probleme, die Asm in allen üblichen
Steuerungsanwendungen nicht lösen kann würd ich gern noch kennenlernen.
le x. schrieb:> EinEnableLed();> sagt mehr aus.
Ja, sagt mehr aus, aber auch nicht mehr... Prinzipiell müsste es ja kein
Problem sein, auch in AVR-Asm "PORTA,0" einen passenden Alias-Namen
geben zu können. Ist so nicht vorgesehen, muß es halt die Doku leisten.
Kosmetik.
le x. schrieb:> Etwas, womit der> Programmierer nix zu tun haben will weil es a) nicht die eigentliche> Problemstellung ist und b) weils vor ihm schon zig andere gelöst haben.> Genauso wie FAT, Webserver, bestimmte Algorithmen...>> Aber es liegt mir fern dich von irgendwas zu überzeugen.
Davon brauchst Du mich nicht zu überzeugen, das handhabe ich selber so.
Ist das Thema, ich meine das ursprüngliche Thema mittlerweile beendet?
Schon schlimm genug, dass fast jeder zweite Thread in einen Cortex
Glaubenskrieg endet, muss es jetzt auch noch ein ASM Krieg werden?
Mein lieber Moby, ich kann dem ASM auch einiges abgewinnen, obwohl ich
noch nicht viel las und noch kein einziges Programm geschrieben habe.
Das kommt noch, wenn ich mal wieder weniger um die Ohren habe und es
meinem Sohn wieder besser geht.
Aber muss du denn unbedingt überall mit deinem ASM rein hauen?
Hier ging es doch eigentlich um die Takte bis eine ISR ausgelöst wird.
Ich schlage dir vor mal ein ganz tolles ASM Tutorial zu schreiben, das
alles andere in den Schatten stellt. Da kann dann jeder selbst lesen,
wenn er will.
Es ist ja schön, dass du so dafür brennst, aber lass doch mal alle
anderen in Ruhe.