Forum: Mikrocontroller und Digitale Elektronik warum braucht Blinkbeispiel 780 byte Flash?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Matthias W. (matt007)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
auf einem Atmega4809 läuft ein LED-Blink-Beispiel. Siehe das zip. 
Compiliert wurde mit WinAVR auf Basis GCC 8.4.0. Da der Code nicht viel 
macht stellt sich die Frage wofür die 780 bytes Flash im Einzelnen 
verbraucht werden.

von Christoph M. (mchris)


Bewertung
2 lesenswert
nicht lesenswert
Erzeuge doch mal ein Map-File und schau nach, welche Bibliotheken 
dazugelinkt werden.

von c-hater (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Matthias W. schrieb:

> auf einem Atmega4809 läuft ein LED-Blink-Beispiel. Siehe das zip.
> Compiliert wurde mit WinAVR auf Basis GCC 8.4.0. Da der Code nicht viel
> macht stellt sich die Frage wofür die 780 bytes Flash im Einzelnen
> verbraucht werden.

Das ist doch einfach rauszukriegen. Schau dir das Listfile an. Lerne, es 
zu verstehen und mach' es besser.

Ist nicht mehr ganz so einfach wie früher, aber immer noch recht 
problemlos möglich...

von Harald (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Vermutung: Startup-Code (Speicher und Variablen initialisieren, Stack, 
etc.)

von Arduino Fanboy D. (ufuf)


Bewertung
0 lesenswert
nicht lesenswert
Matthias W. schrieb:
> Da der Code nicht viel
> macht stellt sich die Frage wofür die 780 bytes Flash im Einzelnen
> verbraucht werden.
Wenn du dir die Hexdatei anschaust, wirst du feststellen, dass das eine 
Textdatei ist. Mit Adressen usw.
Es ist also keinesfalls der Platz im Flash, die 780 (791) Byte
Eher um die 60% davon.
Über die Hälfte von den 50% geht für die Interrupttabelle drauf.

: Bearbeitet durch User
von Mario M. (thelonging)


Angehängte Dateien:

Bewertung
1 lesenswert
nicht lesenswert
Das eigentliche Programm belegt etwa 110 Bytes. Dazu noch mal ungefähr 
160 Bytes für die Interruptvektoren.

von Arduino Fanboy D. (ufuf)


Bewertung
1 lesenswert
nicht lesenswert
Mario M. schrieb:
> Das eigentliche Programm belegt etwa 110 Bytes. Dazu noch mal ungefähr
> 160 Bytes für die Interruptvektoren.
So ist es!


Arduino sagt zu dem Programm:
Der Sketch verwendet 264 Bytes (0%) des Programmspeicherplatzes. Das 
Maximum sind 48640 Bytes.
Globale Variablen verwenden 0 Bytes (0%) des dynamischen Speichers, 6144 
Bytes für lokale Variablen verbleiben. Das Maximum sind 6144 Bytes.

--
Die  264 Bytes sind incl. der Interruptvektoren

: Bearbeitet durch User
von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Bewertung
-9 lesenswert
nicht lesenswert
Tja, Ardummino-Sprech und C sind halt kein Assembler.

Beitrag #6295582 wurde von einem Moderator gelöscht.
von Nicht W. (nichtsowichtig)


Bewertung
0 lesenswert
nicht lesenswert
Wieviel KB benötigt die selbe Funktionalität mit Assembler?

Beitrag #6295590 wurde von einem Moderator gelöscht.
von P. Hagemann (Gast)


Bewertung
1 lesenswert
nicht lesenswert
yboM schrieb im Beitrag #6295590:
> Ben B. schrieb:
>> Tja, Ardummino-Sprech und C sind halt kein Assembler.
Immer reitet man auf die Kleinen herum;-)
>
> Was die meisten Hochsprachenjongleure so alles an Ressourcen auf ihren
> Controllern verschleudern ist ihnen wohl gar nicht mehr bewusst. Aber
> was solls, nehmen wir eben eine 32bittige Nummer größer :)
Der Verbrauch relativisiert sich doch bei größeren Programmen. Es ist 
wichtiger eine Anwendung in einem vernünftigen Zeitrahmen zügig umsetzen 
zu können anstatt um jedes Byte Speicherplatz feilschen zu müssen. Warum 
den kleinsten ATtiny nehmen wenn ein Wald und Wiesen 328er bequem 32K 
aufweist? Es ist falscher Ehrgeiz und Zeitverschwendung unnütze 
Optimierungen machen zu müssen anstatt vernünftig programmieren zu 
können.
>
> Nicht W. schrieb:
>> Wieviel KB benötigt die selbe Funktionalität mit Assembler?
Das ist ein Apfel- und Mandarinenvergleich.
>
> KB? Wahnsinnig?
> Blinkbeispiele gehen in Asm mit ein paar Dutzend Bytes los...
Für unverbrauchten Speicherplatz gibt's aber immer noch kein Geld 
zurück...

Es geht halt darum immer effizient Programmieren zu können um unnötigen 
aufgebauschten Code zu vermeiden. Deshalb sollte man schon schauen was 
sich der Compiler da in ASM denkt. Auch ist es ganz nützlich 
veschiedenste Wege zu verfolgen um einen Instinkt dafür zu bekommen was 
effizient funktioniert und was Speicherplatz verschwendet und CPU Zyklen 
unnötig verschwendet. Es lohnt sich auch den MAP file ab und zu zu 
studieren.

Viele Wege führen nach Rom...

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Bewertung
0 lesenswert
nicht lesenswert
Wie lang wäre das in Assembler... allein das LED-Blinken, nichts 
drumherum...? Pin Toggle und Verzögerungsschleife, reiner Schätzwert 
wären so 25..30 Befehle mit Controller-Initialisierung, bei zwei Byte 
pro Befehl wären das 50..60 Bytes Flash.

Bei Verwendung eines Hardware-Timers geht's noch kleiner, sind dann nur 
ein paar Register schreiben und 'ne Endlosschleife. Sind vielleicht 5 
Register, macht 10..12 Befehle, plus der JMP für die Endlosschleife sind 
13, macht 26 Bytes Flash und der µC langweilt sich zu Tode.

Edit:
Aber stimmt schon, man hat den ganzen Flash bezahlt,
da kann man auch den ganzen Flash nutzen. :D

: Bearbeitet durch User
von sid (Gast)


Bewertung
1 lesenswert
nicht lesenswert
P. Hagemann schrieb:
> Es ist
> wichtiger eine Anwendung in einem vernünftigen Zeitrahmen zügig umsetzen
> zu können anstatt um jedes Byte Speicherplatz feilschen zu müssen. Warum
> den kleinsten ATtiny nehmen wenn ein Wald und Wiesen 328er bequem 32K
> aufweist? Es ist falscher Ehrgeiz und Zeitverschwendung unnütze
> Optimierungen machen zu müssen anstatt vernünftig programmieren zu
> können.

Dem möchte ich widersprechen wollen.

Versteh mich nicht falsch, ich mag C-esques lieber als assembler,
aber weil ich in C(und Tochtergesellschaften) schneller bin als in 
Assembler beim tippen;
ich bin ehrlich gesagt froh dass ich assembler einigermassen flüssig 
lesen kann und nur selten nochmal nachgucken muss...schreiben? nene 
ungern.

Aaaber es macht doch NULL Sinn einen Speicher grundlos vollzuballern,
noch weniger einen Atmega zu nehmen wenn ein ATTiny reicht
Klar ist son ArduinoKlon schön billig und dufte zum spielen,
aber ernsthaftere Projekte sollten doch bitte IMMER optimiert sein
(so wenig wie möglich soviel wie nötig.. hard und software);
denn je schmaler der Fussabdruck, desto schneidiger der Ablauf.
OPtimierter Code ist NIEMALS unnütz!
er ist schlanker, schneller und leichter zu warten.
Er ermöglicht Kosteneinsparungen bei der Produktion und
wenn man ordentlich coden gewöhnt ist,
dann dauert es nichteinmal soo viel länger als hingerotze 
Ressourcenverschwendung.

Glücklicherweise machen fast alle compiler aus gutem Hochsprachen-Code 
mindestens vernünftigen Assembler Code (nein nicht immer perfekt, aber 
immer öfter mindestens gut genug)
Und fast immer reicht das schon :D

'sid

von P. Hagemann (Gast)


Bewertung
2 lesenswert
nicht lesenswert
sid schrieb:
> Dem möchte ich widersprechen wollen.
Und dem möchte ich hiermit NICHT widersprechen wollen;-)

Stimmt ja alles. Trotzdem bilde ich mir mit über 20 Jahren an 
Programmiererfahrung einigermaßen effizient programmieren zu können. Ich 
habe mit Assembler angefangen und diese Erfahrung hat definitiv Einfluss 
auf die Planung und den Ressourceneinsatz sowohl als auch Denkweise.

Speziell bei Arduino sieht man schön den Unterschied. Wenn man z.B. 
typisch 10 IO Pins a la Arduino "Pinmode" mit direktem Registerzugriff 
ersetzt kann man sich schon leicht über 100 Bytes an Speicherplatz 
ersparen. Man muss halt wissen wo es Sinn hat und wo nicht. Man muss 
fast einen sechsten Sinn haben um Einsparmöglichkeiten weitgehend 
erkennen zu können. (Besonders gut kann das unser Peter hier im Forum. 
Sein beigetragener C Code lässt fast jeden ASM Programmierer vor Neid 
erblassen;-) ).

Bei schmächtigen uC mit sehr begrenzten Ressourcen kommt man mit der 
vollen Hose nicht weit. Da muss man sich immer überlegen welche 
Auswirkungen die Art der Programmierung hat. Auch muss man ein Auge 
dafür haben Redundanzen möglichst zu vermeiden und schnell zu erkennen. 
Auch die sinnvolle Teilung von Arbeit durch ISRs und Main-Line Code darf 
man nicht übersehen wo das Sinn hat. Genau wie bei ASM ist klares Denken 
und Planung und viel Erfahrung Voraussetzung für hochperformante FW 
unter begrenzten Ressourcen.

Allerdings ist mittlerweile die Zeit gekommen wo viele moderne begehrte 
Anwendungen und Geräte wegen der Internet Anbindung und 
Sicherheitsanforderungen und hochauflösenden Displays nur noch mit 
32-Boliden mit ihren aufgeblasenen Frameworks zufriedenstellend 
funktionieren kann. Oft hat man deswegen nicht viel Einblick was sich da 
hinter den Kulissen eigentlich abspielt weil so viele fremde Ressourcen 
immer öfters eingesetzt werden.

Die Möglichkeiten die moderne Gerätschaften bieten, wie Feld-Upgrades 
werden durch schlampige Einstellung und "Time to Market" Druck wieder 
massiv relativiert. Früher musste der Entwickler schon von vornherein so 
sorgfältig wie möglich planen und ausführen weil seine uC mit Maske 
hergestellt wurde. Ein VCR oder CD-Abspielgerät musste ohne FW-Upgrades 
beim Kunden funktionieren. Heute wird dem zu Folge der Bananen Marketing 
gefroent und unreifer Code voller Bugs produziert weil man eben 
erwartet, dass alles beim Kunden reifen soll und wegen Scrum und Co. man 
sich kaum noch Zeit für stille Planung eingesteht. Und wenn man diesen 
Einwurf macht, wird einem entgegen geworfen, bei der hohen Komplexität 
moderner Geräte ginge es eben nicht anders. Wenn Entwickler hohe 
Design-Qualität produzieren sollen, müssen sie viel Ruhe haben und vor 
der obligatorischen heißen Luft aus den Geschäftsräumen abgeschirmt 
werden. Was soll man sich nun nur von der FW-Qualität in modernen 
Automobilen denken? Wird da etwa auch schon angewandte Bananen Politik 
betrieben? Aha, ich habs! Mit 5G und generelle Funkanbindung kann man ja 
den Gurken über Nacht neue, verbesserte FW verpassen.

Die Blütezeit der Mikroprozessorentwicklung hat wahrscheinlich schon 
seit einiger Zeit den Summit erreicht. Die hohe notwendige Komplexität 
der meisten wichtigen Anwendung lässt viele Entwickler nur noch 
Ausschnitte des Gesamtbilds erkennen. Es gibt da wegen der zahlreichen 
externen Bibliotheken und Frameworks viele Schwarze Löcher und man kann 
das Gesamtbild nicht mehr klar genug sehen und analysieren. Man verlässt 
sich mehr und mehr auf "Es wird schon gut gehen"...

Irgendwie kann ich mich nicht des Eindrucks erwehren, dass bei modernen, 
hochkomplexen Gerätschaften der Zufriedensheitfaktor und die 
Zufriedensheitsspanne neben einer vernünftigen Lebensdauer beim Kunden 
stetig immer weniger wird.

Speziell bei vieler embedded Haus-Elektronik im Haus sollte man 
jahrzehntelange Funktionstüchtigkeit erwarten. Bei vielen Internet 
angebundenen Gadgets ist das schon lange nicht mehr unbedingt der Fall 
wenn auch Ausnahmen die Regel glücklicherweise hin und wieder 
bestätigen.

Aber das heißt nicht unbedingt, dass man nicht auch mit bescheideneren 
Mitteln noch nette und nützliche Gerätschaften konstruieren kann.

Ja, Ja! Jeder sieht halt die Welt anders...

von Hobbyist (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Hallo

Danke an  P. Hagemann  für den kleinen Einblick in die Welt der Profis.

Ich bin reiner Hobbyist und immer noch Anfänger habe aber schon 
Assembler, "echtes" C und Arduino C++ mit all seinen Vereinfachung 
genutzt.
Assembler ist sehr befriedigend aber trotzdem Anstrengen für jemanden 
für mich der mehr aus der Hardwareecke und Gedankenwelt kommt und immer 
wider verstehen will wie der µC und das Programm bis in das letzte Bit 
und Register arbeiten.
Aber ich sehe selbst in der Hobbyecke auch die unglaublichen Vorteile 
der Hochsprachen und "Black Boxes" - man kommt schnell zu einen 
Ergebniss und hat ein relativ universelles Programm was auf vielen 
Controllern funktioniert und "jeder" versteht der die Sprache 
beherrscht.

Und wo Geld verdient werden muss zählt halt nur das Ergebniss und nicht 
der Spaß und Erkenntnissgewinn der Programmierer - leider?!

Hobbyist

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Mario M. schrieb:
> Das eigentliche Programm belegt etwa 110 Bytes. Dazu noch mal ungefähr
> 160 Bytes für die Interruptvektoren.

das sind zusammen 270 byte.

und warum sagt dann AVRDUDE:
1
reading input file "main.hex"
2
writing flash (780 byte)
3
writing
4
780 bytes of flash written
5
verifying
6
780 bytes of flash verified

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
sid schrieb:
> Es ist falscher Ehrgeiz und Zeitverschwendung unnütze Optimierungen machen zu 
müssen

das mag so sein.

aber nachdenken darf man doch wenn angeblich ~270 byte benötigt werden 
für Programm und dann flashen von 780 bytes angezeigt wird?

auf dem chip wird ein Bootloader verwendet. Der gehört jedoch nicht zu 
diesem Programm. Er liegt mit 512byte darunter.

AVRDUDE wird sicher nicht jedesmal wieder diesen Bootloader flashen. 
Zählt AVRDUDE den Platz für den Bootloader da irrtümlicherweise mit?

woher kommt sonst die Diskrepanz?

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Matthias W. schrieb:
> ~270 byte benötigt werden für Programm
> ein Bootloader ...  512byte
> und dann flashen von 780 bytes
Passt aufs Byte: 512+270 = 782

> AVRDUDE wird sicher nicht jedesmal wieder diesen Bootloader flashen.
Woher nimmst du diese Sicherheit? Wie sieht die Kommandozeile für den 
AVRDUDE aus?

von Matthias W. (matt007)


Bewertung
3 lesenswert
nicht lesenswert
sid schrieb:
> OPtimierter Code ist NIEMALS unnütz!
> er ist schlanker, schneller und leichter zu warten.

ja ! ältere digitale Voltmeter wie Keithley 197 kamen mit wenig 
Prozessorleistung/Speicher aus. Updates waren nicht nötig und doch gab 
es verlässliche Ergebnisse.

mein Geräteaufbau von 1988 aus HP9000-Rechner mit 68000-CPU und 1MB RAM, 
GPIB-Messdatenerfassungssystem mit 68000, GPIB-Plotter, GPIB-Drucker, 
GPIB-Festplatte, GPIB-Diskettenlaufwerk, HIL-Graphiktablett brauchte nie 
Updates und funktionierte über die 2 Jahre die ich es nutzte stets 
vorhersagbar fehlerfrei.

neuere Geräte die ich Jahre später nutzte machten im Vergleich dazu 
Probleme - trotz oder gerade wegen massiv mehr Rechenleistung, 
USB-GPIB-Converter usw. Ich empfand das als keine gute 
Weiterentwicklung.

mein Eindruck ist - es wird vieles heute aufgeblasen und 
undurchsichtiger aber nicht zwingend auch besser. Vielleicht wäre eine 
Rückbesinnung nötig und sinnvoll. Man denke an Autos die rumstehen bei 
VW weil offenbar ein Problem mit der Software-Einbringung besteht?

es ist gut zu wissen wie die Dinge innen laufen. Das wird schwerer je 
größer chips und Softwarepakete sind.

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Wie sieht die Kommandozeile für den AVRDUDE aus?

die steht oben im Makefile im geposteten zip.
im Terminalfenster kommt:
1
avrdude -v -v -p atmega4809 -c arduino -P COM11 -U flash:w:main.hex

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Woher nimmst du diese Sicherheit?

weil AVRDUDE den Code für den Bootloader zu diesem Zeitpunkt gar nicht 
hat. Der Bootloader wurde zuvor aufgebracht.

AVRDUDE merkt daß da ein Bootloader ist und verweigert dann mit einer 
wenig aufschlussreichen Meldung das Flashen.

Dieses Problem verschwand als ich per Linkerflag das Blinkprogramm um 
512byte nach oben verlegte. Siehe Makefile im zip.

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Passt aufs Byte: 512+270 = 782

dann zeigt AVRDUDE die geflashen Bytes falsch an. Oder AVRDUDE hat dazu 
noch den Bootloader ausgelesen und dann zusammen mit dem Programm neu 
geflasht. Dazu sehe ich jedoch keinen Hinweis in den Ausgabemeldungen.

wahrscheinlicher ist daß AVRDUDE bei der Meldung die 512byte für den 
Bootloader irrtümlich nicht abgezogen hat.

dasselbe "Problem" tritt auch in der Arduino-IDE auf wenn man da den 
Code über den Bootloader hochlädt.

es werden offenbar unterschiedliche Codegrößen gemeldet ob der 
Bootloader da ist oder nicht, obwohl der Code für das Blinken stets 
derselbe ist.

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Mario M. schrieb:
> Das eigentliche Programm belegt etwa 110 Bytes. Dazu noch mal ungefähr
> 160 Bytes für die Interruptvektoren.

Danke Mario !
es gibt also keinen Platzbedarf hier für Bibliotheken.
es sind auch keine includiert oder genutzt worden.

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Ben B. schrieb:
> Wie lang wäre das in Assembler...

gute Frage.

> allein das LED-Blinken, nichts
> drumherum...? Pin Toggle und Verzögerungsschleife, reiner Schätzwert
> wären so 25..30 Befehle mit Controller-Initialisierung, bei zwei Byte
> pro Befehl wären das 50..60 Bytes Flash.

die Vektortabelle wird mit C und Assembler gleich sein.
die Verzögerungsschleife ist hier in Assembler. Siehe delay.c.
wo soll der Overhead dann herkommen? die paar Register schreiben?

von Yalu X. (yalu) (Moderator)


Bewertung
2 lesenswert
nicht lesenswert
Ja, der Avrdude zählt bei

1
writing flash (780 byte)

auch die "Löcher" mit, an denen nichts geschrieben wird. In deinem Fall
gibt es so ein Loch im Adressbereich von 0x0000 bis 0x01FF. Tatsächlich
werden also nur 780-512=268 Bytes geschrieben und verifiziert.

Du wirst im Hexfile auch nur genau diese 268 Datenbytes finden. Mehr
kann der Avrdude nicht schreiben, denn irgendwoher müssen die Daten ja
kommen.

Zum leidigen Thema C vs. Assembler:

Der vom Compiler erzeugte Code für main und initialization ist optimal,
delayloop32 ist sowieso schon in Assembler geschrieben.

Die restlichen Bytes entfallen auf die Interruptvektortabelle und den
Startcode. Beides wird in diesem trivialen Beispiel nicht zwingend
benötigt und könnte deswegen weggelassen werden. Das geht mit den
entsprechenden Compiler- und Linker-Optionen auch für C-Programme, hat
aber keinen praktischen Nutzen, da gerade bei solch trivialen Programmen
sowieso nur ein winziger Bruchteil des verfügbaren Speichers benötigt
wird.

von Wilhelm M. (wimalopaan)


Bewertung
-1 lesenswert
nicht lesenswert
Matthias W. schrieb:
> Lothar M. schrieb:
>> Wie sieht die Kommandozeile für den AVRDUDE aus?
>
> die steht oben im Makefile im geposteten zip.
> im Terminalfenster kommt:
>
1
> avrdude -v -v -p atmega4809 -c arduino -P COM11 -U flash:w:main.hex
2
>

Wozu denn jetzt einen Bootloader auf ein UPDI-Device?

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Die restlichen Bytes entfallen auf die Interruptvektortabelle und den
> Startcode.

Danke für den Hinweis. Hast Du einen Link wo der Startcode erklärt wird? 
Wie kann man den näher ansehen? Brauche ich einen Disassembler oder geht 
das auch eleganter?

was wird in der Interruptvektortabelle eingetragen wenn ich als Anwender 
nichts definiert habe?

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> Wozu denn jetzt einen Bootloader auf ein UPDI-Device?

weil es bequemer ist das Board (genauso wie einen Arduino nano) über die 
serielle Schnittstelle zu flashen ohne einen Programmer noch dazu 
anhängen zu müssen. Per UPDI brachte ich den Bootloader drauf.

genauso hättest Du fragen können warum denn einen Bootloader beim 
Atmega328p, wo der doch auch ISP hat. Nur nehme ich das so gut wie nie 
her.

und warum dann einen Bootloader beim LPC1343? Bootloader haben ihre 
Nachteile, sie vereinfachen aber auch manches.

Jeder kann entscheiden wann er wozu welches Tool nutzen möchte.

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Das geht mit den
> entsprechenden Compiler- und Linker-Optionen auch für C-Programme

Danke für den Hinweis !

von Wilhelm M. (wimalopaan)


Bewertung
-1 lesenswert
nicht lesenswert
Matthias W. schrieb:
> Wilhelm M. schrieb:
>> Wozu denn jetzt einen Bootloader auf ein UPDI-Device?
>
> weil es bequemer ist das Board (genauso wie einen Arduino nano) über die
> serielle Schnittstelle zu flashen ohne einen Programmer noch dazu
> anhängen zu müssen. Per UPDI brachte ich den Bootloader drauf.

Nein. Für Updi brauchst Du am PC auch nur eine serielle Schnittstelle. 
Keinen programmer. Und wenn Du Dir schon über Platzbedarf Gedanken 
machst, dann sollte Dir eine Bootloader zu denken geben ;-)

>
> genauso hättest Du fragen können warum denn einen Bootloader beim
> Atmega328p, wo der doch auch ISP hat. Nur nehme ich das so gut wie nie
> her.

ISP braucht einen Programmer und wesentlich mehr Pins. Updi nur einen 
(dedizierten).

von Matthias S. (da_user)


Bewertung
0 lesenswert
nicht lesenswert
sid schrieb:
> OPtimierter Code ist NIEMALS unnütz!
> er ist schlanker, schneller und leichter zu warten.

Würde ich so nicht pauschal unterschreiben.
Wenn man Code so optimiert, dass er schneller und/oder schlanker ist, 
wird u.U. der eine oder andere Trick oder Kniff angewendet, der den für 
Unwissende(re) schlechter lesbar und damit wartbar macht.

Die Kunst liegt sicherlich darin, da einen Mittelweg zu finden. Und 
Wahrscheinlich ist dieser Mittelweg meistens Situationsabhängig und 
nicht zuletzt auch persönlich geprägt.

: Bearbeitet durch User
von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> Nein. Für Updi brauchst Du am PC auch nur eine serielle Schnittstelle.
> Keinen programmer. Und wenn Du Dir schon über Platzbedarf Gedanken
> machst, dann sollte Dir eine Bootloader zu denken geben ;-)

Wilhelm - jeder hat da seine eigene Sichtweise.

UPDI braucht eine USB-SS und eine weitere brauche ich für die 
UART-Eingaben und Ausgaben des Atmega4809 über FTDI.

die 2. Schnittstelle spare ich nun und das Dranhängen des Programmers 
der in meinem Fall auf einem Steckbrett steckt.

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Matthias W. schrieb:
> Und wenn Du Dir schon über Platzbedarf Gedanken
> machst, dann sollte Dir eine Bootloader zu denken geben ;-)

die 512bytes kann ich verkraften wenn 48kB da sind. Trotzdem möchte ich 
verstehen wohin die Bytes verschwinden.

wenn die Entwicklung abgeschlossen ist kann man den Bootloader auch 
wieder rauswerfen. Niemand muss den Bootloader nutzen !

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> ISP braucht einen Programmer und wesentlich mehr Pins.

UPDI braucht auch einen Programmer - oder einen extra seriellen Port. 
Irgendwie muss man den Pin ja bedienen.

von Wilhelm M. (wimalopaan)


Bewertung
-1 lesenswert
nicht lesenswert
Matthias W. schrieb:
> Wilhelm M. schrieb:
>> ISP braucht einen Programmer und wesentlich mehr Pins.
>
> UPDI braucht auch einen Programmer - oder einen extra seriellen Port.
> Irgendwie muss man den Pin ja bedienen.

Zwischen einem Programmer und einer simplen seriellen Schnittstelle in 
Half-Duplex ist m.E. schon ein Unterschied.

Beschäftige Dich mal damit und Du wirst die Vorzüge schätzen lernen ...

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> Beschäftige Dich mal damit und Du wirst die Vorzüge schätzen lernen ...

ich schätze Deinen Hinweis und werde ihn im Hinterkopf behalten.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Matthias W. schrieb:

> Danke für den Hinweis. Hast Du einen Link wo der Startcode erklärt wird?
> Wie kann man den näher ansehen? Brauche ich einen Disassembler oder geht
> das auch eleganter?

Vielleicht solltest du dich mal damit vertraut machen, was das Konzept 
"Opensource Software" genau bedeutet?

http://svn.savannah.gnu.org/viewvc/avr-libc/trunk/avr-libc/crt1/gcrt1.S?revision=2519&view=markup

> was wird in der Interruptvektortabelle eingetragen wenn ich als Anwender
> nichts definiert habe?

Die Vektortabelle wird stets für das jeweilige Device maximal gefüllt, 
wobei für alle nicht explizit im Sourcecode notierten Vektoren ein 
Sprung auf __bad_interrupt eingetragen wird. Das Symbol kann man selbst 
überschreiben, ansonsten erfolgt ein Sprung auf Adresse 0.

Aber das steht da auch alles oben drin … du freust dich doch sicherlich 
über ein schönes Stück Assemblercode. :-)

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Bewertung
-1 lesenswert
nicht lesenswert
Sorry, wollte keinen Krieg Assembler vs. C oder so vom Zaun brechen.

Aber sowas wie die Interrupttabelle initialisieren mache ich bei 
Assembler-Projekten auch, selbst wenn die dann nur mit RETIs gefüllt 
ist. Obs was bringt keine Ahnung, ich erhoffe mir davon, daß falsch 
ausgelöste Interrupts abgebrochen werden oder falls sich dadurch eine 
Endlosschleife ergibt, der µC wenigstens "definiert crasht" und nicht 
irgendwie Amok läuft.

Bei extrem knappen Resourcen und einem Programm ohne Interrupts kann man 
diesen Platz aber auch für Programmcode benutzen. Manchmal retten einem 
ein paar Bytes den Arsch.

Ansonsten würde ich auch sagen, angesichts des technischen Fortschritts 
und was für leistungsstarke Controller man heute im ARM-Segment in 
Mini-Gehäusen bekommt... da kann man eine LED auch mit 32 Bit blinken 
lassen und bezahlt nicht wesentlich mehr als wenn man einen ATTiny oder 
NE555 verwendet hätte.

von sid (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Matthias W. schrieb:
> sid schrieb:
>> Es ist falscher Ehrgeiz und Zeitverschwendung unnütze Optimierungen >> machen 
zu müssen
>
> das mag so sein.

ich schrieb des aber nicht ;)

Matthias S. schrieb:
> Würde ich so nicht pauschal unterschreiben.
> Wenn man Code so optimiert, dass er schneller und/oder schlanker ist,
> wird u.U. der eine oder andere Trick oder Kniff angewendet, der den für
> Unwissende(re) schlechter lesbar und damit wartbar macht.

JA, da haste recht, in den extremen Randbereichen hat das Auswirkungen 
auf die Lesbarkeit (weil man zB assembler routinen einbettet #kicher)
Um die Extrema ging es hier aber nicht, deswegen pauschalisierte ich ;)
Aber stimmt.

P. Hagemann schrieb:
> Stimmt ja alles. Trotzdem bilde ich mir mit über 20 Jahren an
> Programmiererfahrung einigermaßen effizient programmieren zu können.

Ich wollte nichts anderes behaupten;)
Ich hab aufm Sinclair ZX81 (aber in basic) angefangen;
und während mich das nicht vor unnützen Zeilen schützt,
glaub ich auch recht kompakt (bei guter lesbarkeit) zu tippen in der 
Lage bin.

Was Du schreibst trifft übrigens nicht nur auf µC programmierung zu, 
wenn man sich mal ansieht wie unnütz aufgeblasen 'kleine' Anwendertools 
daherkommen.
Was 2000 noch spielend in einen 120MB installer passte ist heute ohne 
nennenswerte Funktionserweiterung leicht auf 1GB Grösse angewachsen.
Aber das ist wie mit dem SUV Brötchenholen zu fahren...
die passen nämlich auch spielend in nen GolfI ;)

Ich schweife ab...

'sid

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Nicht W. schrieb:
> Wieviel KB benötigt die selbe Funktionalität mit Assembler?

Je nachdem wie doof man sich anstellt mehr oder weniger. Beides ist 
möglich.

Man könnte z.B. die Interrupt-Vektor Tabelle weglassen, solange man 
keine Interrupts benötigt und damit auf ein beeindruckend kleines 
Programm kommen. Aber wozu soll das gut sein? Für nicht genutzten 
Speicher bekommt man kein Geld zurück.

sid schrieb:
> Aaaber es macht doch NULL Sinn einen Speicher grundlos vollzuballern,

Recht hast du. Hier haben wir einen Grund: Weil sich das von alleine so 
ergeben hat und es andererseits keinen Grund gibt, Zeit in eine 
Optimierung zu versenken.

Was aber durchaus Sinn macht ist die Frage des TO, um zu verstehen, was 
passiert ist und wie man es analysiert. Denn irgendwann hat er 
wahrscheinlich doch mal einen guten Grund, ein anderes Programm zu 
optimieren.

: Bearbeitet durch User
von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Wilhelm M. schrieb:
> Zwischen einem Programmer und einer simplen seriellen Schnittstelle in
> Half-Duplex ist m.E. schon ein Unterschied.

Für mich nicht, denn mein Laptop braucht für beides einen kleinen USB 
Stick. Ob da jetzt USB-UART oder USBASP drauf steht, macht (was den 
Komfort angeht) keinen großen Unterschied.

Was ich aber ganz gerne mache ist, zwei Adapter parallel zu benutzen:
1) Einen USB-UART für Debug Meldungen
2) Einen Programmieradapter zum Flashen.

Dann muss ich nämlich nicht immer mein Terminalprogramm  schließen, um 
zu flashen. Arduino hat das elegant unter einen Hut gebracht, aber 
Arduino ist nicht so meine Welt.

: Bearbeitet durch User
von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
sid schrieb:
> OPtimierter Code ist NIEMALS unnütz!
> er ist schlanker, schneller und leichter zu warten.

Ich disoptimiere durchaus Code, um ihn lesbarer und besser wartbar zu 
machen. Auch wenn er dann 10 Bytes größer ist.

Was Code unwartbar macht, sind Copy&Paste Monster. Ähnliche 
Codesequenzen werden hintereinander geklatscht, weil man zu faul ist, 
daraus eine Funktion zu machen. Und dann findet man einen Fehler und muß 
ihn an vielen Stellen korrigieren und alles neu testen. Und mindestens 
eine Stelle vergißt man dann zu ändern und zu testen. Der Faule muß 
hinterher umso fleißiger werden.

: Bearbeitet durch User
von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> was das Konzept "Opensource Software" genau bedeutet?

Ich habe nichts dagegen wenn man leicht finden kann (open=offen) wie das 
gemacht wird.

> 
http://svn.savannah.gnu.org/viewvc/avr-libc/trunk/avr-libc/crt1/gcrt1.S?revision=2519&view=markup

Danke für den Link Jörg.
avr-libc/crt1/gcrt1.S ist ein asm-file mit einer Vektortabelle.

Der erste Befehl könnte ein Jump zum eigentlichen Programmstart sein? 
Auch der Stack muss irgendwo festgelegt werden. Es gibt 127 Vektoren, 
also Sprünge zum Code wenn der Interrupt auftritt. Da sollte etwas 
sinnvolles hinterlegt werden. Solange die Interrupts alle gesperrt sind 
braucht man es nicht.

Im C-Code legt man dann ja fest was beim Interrupt geschehen soll und 
wohin gesprungen wird zum Code. Die Vektornummern wie "__vector_127" 
müssen ja noch auf die Vektoren des Chips abgebildet werden. Dazu wohl 
die iom4809.h.

Solange in der Software kein Interrupt definiert oder freigeschaltet 
wurde solange braucht es die Vektortabelle wohl nicht.

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> wobei für alle nicht explizit im Sourcecode notierten Vektoren ein
> Sprung auf __bad_interrupt eingetragen wird.

Danke Jörg ! dort sollte dann eine brauchbare Reaktion erfolgen.

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> du freust dich doch sicherlich
> über ein schönes Stück Assemblercode. :-)

nach so langer Zeit mal eine Abwechslung !

von Christoph M. (mchris)


Bewertung
0 lesenswert
nicht lesenswert

von sid (Gast)


Bewertung
2 lesenswert
nicht lesenswert
Peter D. schrieb:
> sid schrieb:
>> OPtimierter Code ist NIEMALS unnütz!
>> er ist schlanker, schneller und leichter zu warten.
>
> Ich disoptimiere durchaus Code, um ihn lesbarer und besser wartbar zu
> machen. Auch wenn er dann 10 Bytes größer ist.

hmm, vielleicht liegt's an der Mehrdeutigkeit des Begriffs ;)

Denke mal wie Dein Navigationssystem
"schnellste Route" (copy&paste Lösung)
"Kürzeste Route" (kleinstmöglicher Code)
"Optimale Route" (so klein wie's geht ohne unlesbar zu werden)

So in etwa.

Die letzten zehn byte sind selten Kriegsentscheidend;

ich ersetze auch nicht acht booleans mit ner uint8_t
und benutze deren bits stattdessen wenn es nicht unbedingt sein muss,
das ist nämlich echt sch[lecht] zu lesen und in xy Monaten fast 
nichtmehr zu verstehen
Aber ich nutze auch keine int64 für Werte aus nem 10bit ADC,
entpacke Schleifen nur wenn der Geschwindigkeitsvorteil wirklich 
merklich ist(und der Platz es erlaubt),
und bin in der Tat ein grosser Freund von subroutinen/Funktionen
sobald sie an mehr als einer Stelle gebraucht werden.

Das "Optimum" ist immer ein Kompromiss
zwischen allen limitierenden Faktoren.
Der einzige für mich nicht gültige Faktor ist Faulheit.
Ich mag nicht wenn man aus Faulheit eine 200byte Funktion zu schreiben 
ein 1400kb library läd zB (um es mal übertrieben auszudrücken)

Ich mag schon nicht zu gerne, wenn Code zu portabel ist und hunderte von 
ifdefs den Quelltext ins Absurde blasen nur weil zwei drei Männlein 
zusätzlich einen besonders exotischen Controller nutzen möchten
oder meinen 40 verschiedene displays unterstützen zu müssen etc.
Was leider bei opensource immer weiter umsich greift,
und Querlesern den Spass verdirbt ... anderes Thema

Aber grundlos Zeug mitzuschleppen ist schlicht Käse;
und unnötigen Ballast abzuwerfen ist die Form der Optimierung von der 
ich spreche;
ja "within reasonable efforts" natürlich,
ich verschwende auch keine Stunden um ein byte zu sparen.
Aber wenn mich 120byte ne Minute Kopfkratzen kosten sind sie weg... so 
halt.

'sid

von A. B. (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Matthias W.
***********
Vermutlich braucht dein delay den Speicher.
Die Toolchain kann auch delay()

main.c toggelt PinD.6 auf Arduino.UNO.WIFI

Programmiert/getestet mit einem USB Kabel via mEDBG.

Im Anhang Source und ATmega4809-toggle-plain-c.lss

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Matthias W. schrieb:

> avr-libc/crt1/gcrt1.S ist ein asm-file mit einer Vektortabelle.

… und vielem anderem mehr.

> Der erste Befehl könnte ein Jump zum eigentlichen Programmstart sein?

__init ist in der gleichen Datei definiert, da brauchst du nichts zu 
mutmaßen, das kannst du dir direkt ansehen.

XJMP steht in inc/macros.inc. Es abstrahiert absolute vs. relative 
Sprünge, abhängig von der Ziel-Architektur. Auf diese Weise muss man 
nicht überall, wo solche Sprünge gemacht werden, bedingt assemblieren, 
sondern kann das an einer einzigen Stelle niederschreiben.

> Auch der Stack muss irgendwo festgelegt werden.

Ja. Davon abgesehen, dass die meisten neueren AVRs das sogar direkt in 
der Hardware tun können: schau dir doch einfach die genannte Datei 
genauer an. Steht alles da drin. ;-)

> Es gibt 127 Vektoren,

Nein, bis zu 127 Vektoren.

Wie viele davon wirklich belegt werden, hängt vom konkreten Device ab.

Steht auch in dieser Datei drin. :-) (OK, in Zusammenarbeit mit dem 
iom4809.h - irgendwoher muss die Information über das Device ja kommen.)

> Solange die Interrupts alle gesperrt sind
> braucht man es nicht.

Der Startup-Code hat aber keine Ahnung, welche Interrupts alle gesperrt 
bleiben und welche nicht.  Der liegt am Ende als vorcompilierte 
Objektdatei vor und wird vom Linker hinzu gefügt.

Wenn dir ein paar ungenutzte Vektoren zu viel Verschwendung sind, dann 
musst du in den sauren Apfel beißen und deinen eigenen Startup-Code 
schreiben.

: Bearbeitet durch Moderator
von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> Der Startup-Code hat aber keine Ahnung, welche Interrupts alle gesperrt
> bleiben und welche nicht.  Der liegt am Ende als vorcompilierte
> Objektdatei vor und wird vom Linker hinzu gefügt.

der Startup-Code weiß es natürlich nicht - aber der Compiler weiß es 
schon und daher kann er ggf. das auch beim Linken dann weglassen.

aber - bei 48kB - tut das momentan genauso wenig weh wie der Bootloader 
mit seinen 512 byte. Es ist nur gut in etwa zu wissen wie die Dinge 
zusammenhängen.

Da sind Menschen wie Du wertvoll wie wissen welche Info wo steht.

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> und deinen eigenen Startup-Code schreiben.

ich habe das zwar momentan nicht vor - aber es sei die Frage gestattet - 
gibt es denn eine einfache Anleitung - vielleicht mit Beispiel - wie man 
so einen Startup-Code ggf. schreibt?

bei den ARM-Prozessoren wie z.B. LPC1343 gibt es das Thema ja auch.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Matthias W. schrieb:

> der Startup-Code weiß es natürlich nicht - aber der Compiler weiß es
> schon und daher kann er ggf. das auch beim Linken dann weglassen.

Ich glaube, du überschätzt hier deutlich die Fähigkeiten des Compilers. 
Dazu müsste er für jeden Controller jedes einzelne Interrupt-Enable-Bit 
jedes Hardwareblocks sowie den zugehörigen Interruptvektor irgendwie 
abgebildet bekommen, und dann müsste er auch noch einen Weg finden, dem 
Linker zu sagen, wie viele Vektoren er am Ende weglassen kann.

Das alles für ein paar Byte - kleine Controller haben auch nur eine 
kleinere Vektortabelle.

Matthias W. schrieb:
> aber es sei die Frage gestattet - gibt es denn eine einfache Anleitung -
> vielleicht mit Beispiel - wie man so einen Startup-Code ggf. schreibt?

Was spricht dagegen, den von mir verlinkten Startup-Code zu verstehen 
und als Vorlage für einen eigenen zu verwenden?

von Matthias W. (matt007)


Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> Was spricht dagegen, den von mir verlinkten Startup-Code zu verstehen
> und als Vorlage für einen eigenen zu verwenden?

mir wäre lieber wenn das weniger abstrahiert wäre und mehr zum Chip 
selbst passen würde ohne weitere Zwischenschritte.

natürlich ist klar daß man da verallgemeinert. Nur macht es das gerade 
Anfängern nicht leicht zu verstehen. Meine Assemblerversuche mit AVR 
liegen 17-18 Jahre zurück. Davor arbeitete ich mit Maschinensprache an 
einem selbstgebauten 8085.

Es fällt mir nicht einfach zu Deinen Code einfach rasch zu verstehen. 
Momentan ist das Thema nicht so wichtig.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.