Forum: Compiler & IDEs Zähler: erzeugte exe viel zu groß


von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

hier ein kleines C-Programm
für einen Zähler mit dem AT2313.
Leider ist das hex 17kB groß und
passt so gar nicht rein.

Den Code habe ich von
www.mino-elektronik.de/fmeter/fmeterx.htm
geladen und für den GCC angepasst.

Im C-Code habe ich hinten das verwendete
Makefile auskommentiert angehängt.

Hat jemand von Euch eine Ahnung, wie
ich den Code, der bei Mino sonst problemlos
in den 2313 passt mit dem GCC hineinbekommen
kann?

Wo kommt die riesige Codelänge her?

Vielen Dank für Eure Beiträge.

von Markus Kaufmann (Gast)


Lesenswert?

Das Standard-Makefile vom gcc packt wohl tausend libs dazu. Schau mal,
was man da entfernen kann.

Markus

von Stefan (Gast)


Lesenswert?

Benutzt Du die neueste Version von WinAVR? In den älteren wurde eine Lib
versehentlich immer mit dazugelinkt (habe ich hier im Forum gelesen,
such mal danach).

Stefan

von Matthias (Gast)


Lesenswert?

@Markus: Danke für die Idee.
Hier die fraglichen Einstellungen im Makefile,
was hinten im Code auch zur Info so angehängt ist:
  LDFLAGS += -mmcu=$(MCU)
# --- link: instructions to create elf output file from object files
---
%.elf: $(OBJ)
  $(CC) $(OBJ) $(LIB) $(LDFLAGS) -o $@
Hast Du eine Idee, was hier noch optimiert werden kann?

@Stefan: Danke für den Tipp.
Die WinAVR-Datei heißt WinAVR-20030913-bin-install.exe
eine neuere Datei gibt es meines Wissens nicht.

von Matthias (Gast)


Lesenswert?

wir haben gerade noch mal getestet
und festgestellt, daß ein Programm
mit einer einzigen floating point
Operation mehr als 5kB länger ist als ohne.

float fvar=1.234
fvar*=fvar       : 13424 bytes hex-file

die folgende Zeile zusätzlich hinzu:
fvar/=fvar       : 14802 bytes hex-file
also 1.4kB mehr für das simple /-Zeichen

ohne floating point Operation: 8899 bytes

Sollte der C-Compiler von Mino hier so
viel besser sein? Er bekommt es ja wohl
in den 2313. Wir so nie . . . :-(

von Peter Fleury (Gast)


Lesenswert?

Bitte WinAVR Sample Makefile (\Winavr\sample\makefile) verwenden und
an dein Projekt anpassen. Dein Makefile ist veraltet.

von Joerg Wunsch (Gast)


Lesenswert?

Kann schon sein, daß der IAR besser mit float umgehen kann.  Die
Bibliotheksfunktionen des GCC, die das machen, sind alle nicht gerade
klein.  Ich wäre auch nie auf die Idee gekommen, einen '2313 mit flot
zu quälen. ;-)

Ggf. kann man sich natürlich stattdessen mit scaled integer behelfen.
Ein größerer Prozessor ist vermutlich aus Pinkompatibilitätsgründen ja
eher nicht drin.

von Michael (Gast)


Lesenswert?

>Ggf. kann man sich natürlich stattdessen mit scaled integer behelfen.

Das sagt sich immer so leicht :-)
Wenn man einen großen Dynamikbereich verarbeiten muß, sind floats immer
effizienter - vorausgesetzt, es werden nicht noch trig.-Funktionen
dazugelinkt.

@Joerg: könntest Du nicht einmal compilieren und linken, damit man
erfährt, wie groß der Code wird, wenn man GCC optimal nutzt - egal auf
welchem Prozessor der Code nachher laufen soll ?

von Peter D. (peda)


Lesenswert?

Ja, der AVR-code ist halt in 16-Bit Worten, da brauchts dann eben mehr,
als z.B. beim 8051.

Hier mal als Beispiel mein Frequenzmesser aufm AT89C2051:

Main: 691 Byte
Float-Library: 979 Byte
Gesamt: 1670 Byte = 82% Auslastung

Das past also noch bequem in die 2kB.


Beim AVR sollte es für Float aber schon ein ATMega8 sein, der AT90S2313
ist definitiv zu klein dafür.


Peter

von Michael (Gast)


Lesenswert?

>>Beim AVR sollte es für Float aber schon ein ATMega8 sein, der
>>AT90S2313 ist definitiv zu klein dafür.

Das stimmt doch garnicht: siehe Link ganz oben.
Paßt auch in 2K FLASH und ist viel besser als dem Peter seinen :-)

von Peter D. (peda)


Lesenswert?

@Michael,

"ist viel besser als dem Peter seinen"

und was ist viel besser daran ?



Peter

von Michael (Gast)


Lesenswert?

Alles !

von Peter D. (peda)


Lesenswert?

Nichts !

von Matthias (Gast)


Lesenswert?

@Peter, Michael: Wieso streitet ihr denn?
Vermutlich habt Ihr ja beide recht.
In Michaels optimiertem Assemblercode
stecken wirklich eine Menge Funktionen.

Es geht hier doch nicht darum, wer jetzt
wirklich mehr Funktionen in seinem
Programm drin hat, sondern auf welche
Art ein verständlich geschriebenes
C-Programm in einen kleinen Mikrocontroller
passt. Dazu möchte ich gerne zurückkommen.
Das ist es doch, was die Leser hier interessiert.

Und da sagt der Michael, daß er das Zählerprogramm
mit seinem IAR in den Speicher des 2313 bekommt.

Wir bekommen dies derzeit mit dem GNU nicht fertig.

Peter schafft es auf dem 8051 mit seinem
eigenen Code.

Auf den 8051 umsteigen geht aber nicht . . .

Würde es vielleicht gehen die Bibliothek
eines besseren Compilers beim GCC einzubinden?

Hat jemand vielleicht schon mal sowas gemacht
und kann ein paar Sätze dazu sagen?

von Joerg Wunsch (Gast)


Lesenswert?

> Würde es vielleicht gehen die Bibliothek eines besseren Compilers
> beim GCC einzubinden?

Für die Zeit, die Du dafür brauchst, kannst Du Dir wahrscheinlich
mehrere ATmega128 leisten. ;-)

Mich hat neulich jemand angeschrieben, der optimierten
Gleitkommafunktionen geschrieben hat.  Schick mir 'ne Mail und ich
bringe Dich mit ihm in Kontakt.  Vielleicht kannst Du das ja mal
testen, was er so gemacht hat.

von Peter D. (peda)


Lesenswert?

@Matthias

"In Michaels optimiertem Assemblercode..."

Ich dachte, hier geht es um C ?

Ich habe beim 2051 jedenfalls keinen Assembler oder sonstige spezielle
Optimierungen verwendet.
Float und Assembler schließen sich doch gegenseitig aus.

Warum willst Du denn nicht den Mega8 nehmen ?


"...stecken wirklich eine Menge Funktionen."

Der einzige Unterschied ist doch nur, daß ich LED-Anzeigen mag, da die
besser ablesbar sind.
Ansonsten hat mein Source-Code die volle Funktion und ist nicht nur ein
auf 140kHz eingeschränktes Beispielprogramm.
Die 0,0025 Hz kann eh keiner nutzen oder willst Du immer 7 Minuten
warten, ehe Du merkst, daß gar keine Frequenz mehr anliegt ?
Deshalb benutze ich ein Timeout von 2s (0.5Hz).


Peter

von Michael (Gast)


Lesenswert?

>>Ich habe beim 2051 jedenfalls keinen Assembler oder ...
Ist Assembler jetzt verboten ?

>> Float und Assembler schließen sich doch gegenseitig aus.
Ach so !

Was Peter nicht braucht, daß braucht keiner.

Nun gut.
Peters Float.lib hat 979 Byte meine dagegen nur 650 Byte. Damit ist
Peter der Sieger ! Er ist halt der Größte - wie immer.

von Joerg Wunsch (Gast)


Lesenswert?

Kannst Du Dir bitte einen anderen Kindergarten suchen?

Michael, wenigstens wiedermal ein eindrucksvoller Beweis, wofür das
deutsche Usenet Realnamen haben möchte.  Solch
Kindergartenargumentation kommt (fast) immer nur von Leuten, die sich
gern hinter der Anonymität eines Pseudonyms verstecken.  Jeder normale
Mensch würde sich für diesen Argumentationsstil einfach schämen.

plonk

von Peter D. (peda)


Lesenswert?

"Ist Assembler jetzt verboten ?"

Natürlich nicht, aber in der C-Rubrik doch etwas OT.


">> Float und Assembler schließen sich doch gegenseitig aus.
Ach so !"

Ja, zumindest kenne ich keinen Assembler, der float-Symbole erlaubt.
Und damit braucht man ein externes Tool, was float in den
entsprechenden 32-Bit Wert umwandelt.
D.h. float ist in Assembler extrem umständlich zu handhaben.

Ich habe auch einen Frequenzmesser in Assembler geschrieben. Statt mich
dann aber mit float abzuquälen, habe ich da einfach die
Standardroutinen auf 56Bit Integer aufgebohrt.


"Peters Float.lib..."

Ist nicht meine, sondern die von Herrn Keil.


Peter

von Michael (Gast)


Lesenswert?

Jörg,

die Schuhe, die Du hier verteilst, ziehe ich mir nicht an.


Weiter oben hatte ich Dich gebeten, den Quellcode mit Deinen
Möglichkeiten zu übersetzen, damit Matthias - um dessen Anfrage geht es
hier letztlich - einen Eindruck bekommt, was 'optimal' zu erwarten
ist. Vielleicht hast Du auch ein Beispiel für 'scaled integer', was
man für 6 gültige Dezimalstellen verwenden kann:
'Butter bei die Fische'.

Im Laufe der Zeit hatte ich verschiedene AVR-GCC Version geladen und
getestet. Obwohl ich GNU-CC seit Anfang der 90er kenne - so richtig bin
ich mit der AVR-Lösung nie warm geworden. Und wenn ich hier die Fragen
und Antworten zu dem Thema lese, wird mir das auch klar:

Eine Version ist nicht mehr aktuell; eine Neuere läuft nur, wenn zuvor
alles Alte gelöscht wurde; die Version xxx - die war doch immer nur
Beta. Selbst die Beispielprogramme liefen nicht wie erwartet.

Wenn ich mich richtig erinnere, reserviert printf() über 300 Byte für
den Ausgabepuffer. Auf einer 32-Bit Mühle kein Problem. Bei
printf()-Problemen beim AVR würde ich z.B. die Empfehlung erwarten,
nimm die Quelle, magere sie ab, und freue Dich über den reduzierten
Code und nicht den Rat: printf() - bloß nicht !

Und auf Grund dieser Ratschläge und Erfahrungen entstehen dann
Gerüchte, was man angeblich machen darf und was nicht.
Dem stimme ich so nicht zu.

von Joerg Wunsch (Gast)


Lesenswert?

@Michael:

> die Schuhe, die Du hier verteilst, ziehe ich mir nicht an.

Die Kritik war ja nicht gegen das, was Du jetzt rauskramst, sondern
gegen einen Diskussionsstil wie:

> Was Peter nicht braucht, daß braucht keiner.

...sowie die ,,meiner ist länger als deiner'' Argumentation.

> Weiter oben hatte ich Dich gebeten, den Quellcode mit Deinen
> Möglichkeiten zu übersetzen, ...

Ich habe keine anderen Möglichkeiten als Matthias auch bzw. als die
genannten.  Nein, es ist nicht mein Problem, ich würde mir ein solches
Projekt nicht mit einem AT90S2313 antun, sondern dafür wenigstens
einen ATmega8 oder sowas nehmen -- der Mehrpreis liegt in Höhe der
Versandkosten der gängigen Elektronikversender.  Insofern müßte
Matthias sich schon mal selbst mit demjenigen in Verbindung setzen,
der mir die besseren Gleitkommaroutinen eingereicht hat, aber ich habe
von ihm da bislang noch keine email bekommen.  Keine Frage, auch der
AVR-GCC hat hier durchaus Optimierungspotential, eine Operation wie
»x << 256« kann man sicher bereits im Compiler optimieren (wird ja
bei Integer auch so gemacht).

Nein, ein Beispiel für scaled Integer habe ich auch nicht zur Hand,
siehe oben, es war ja auch nicht mein Problem.  Ich wollte nur einen
möglichen Lösungsvorschlag aufzeigen.  Im Übrigen ist ein 32-bit
Integer logischerweise genauer als ein 32-bit Float (der hat nur eine
Genauigkeit von 24 bit), nur der Dynamikbereich fehlt eben.

Ich habe selbst `scaled integer' für eine ähnliche Aufgabe in anderer
Form benutzt: Zählfrequenzmesser, um einen LC-Oszillator zu messen.
Hier teste ich einfach nach bestimmten Intervallen, wie weit der
Zähler schon vollgelaufen ist, vornehmlich um einen 16-bit Überlauf zu
verhindern.  Allerdings rechne ich dann trotzdem mit float (ist auch
ein 8 bzw. 16 KB AVR), so daß ich 10 ms, 50 ms und 250 ms Zählzeit
habe.  Wenn man die Staffelung aber in 2^N macht, kann man damit
sicher auch einen scaled integer durchziehen.

> Eine Version ist nicht mehr aktuell; eine Neuere läuft nur, wenn
> zuvor alles Alte gelöscht wurde; ...

Das sind keine GCC-Probleme als solche, sondern Artefakten der Leute,
die die Windows-Ports organisiert haben.  Beklag' Dich bei avrfreaks,
daß sie ihre Version schlicht und ergreifend nicht mehr gepflegt
haben.  Ich hatte solche Probleme selbst nie, aber ich compiliere mir
meine Compiler erstens sowieso selbst, zweitens bin ich nicht mit
Windows geplagt (und möchte es auch nicht sein -- ich kenne
effektivere Methoden, mir meine Freizeit totzuschlagen ;-).

> Wenn ich mich richtig erinnere, reserviert printf() über 300 Byte
> für den Ausgabepuffer.

Du erinnerst Dich falsch.  Bitte lies den Code, bevor Du Behauptungen
aufstellst.  printf() ist ganz sicher kein Kleinkram, aber die
stillschweigende Annahme, es handele sich hier einfach um den
rübergezogenen Code einer 32-bit-Implementierung, halte ich angesichts
der freien Verfügbarkeit des Quellcodes an der Grenze zur Verleumdung.

Die Gleitkommavariante von printf() braucht in der Tat einen großen
Puffer (daher ist sie u. a. auch abgetrennt), dort habe ich mich dann
für malloc() entschlossen, da ich nicht den Stack damit belasten
wollte.  Wir können das gern diskutieren, aber bitte auf der avr-libc
Mailingliste.  Als ich seinerzeit die Implementierung von stdio
vorgestellt habe, hat keiner mit mir diskutieren wollen.

Selbstverständlich bleibt es jedermann unbenommen, die avr-libc
Quellen zu nehmen und für seine Zwecke anzupassen, eine solche
Vorgehensweise ist ausdrücklich gewünscht, dafür ist das hier
opensource.  Eine Standardbibliothek kann es naturgemäß nicht jedem
Recht machen (obwohl wir im Falle von printf/scanf schon drei
verschiedene Varianten von jedem liefern).

@Peter:

> Ja, zumindest kenne ich keinen Assembler, der float-Symbole erlaubt.

Dann hast Du Dir den gas noch nicht angesehen.

$ cat foo.s
.data
.float  .5
.double 42
$ avr-as -o foo.o foo.s
$ avr-objdump -s foo.o

foo.o:     file format elf32-avr

Contents of section .text:
Contents of section .data:
 0000 0000003f 00000000 00004540           ...?......E@

von Michael (Gast)


Lesenswert?

Jörg,

> Was Peter nicht braucht, daß braucht keiner.

Das ist das Resultat meiner Beobachtungen der letzten 1-2 Jahre im
'Forum', mit Peter konstruktiv (das meine ich nicht ironisch) über
Für und Wider zu diskutieren. Er führt sich als Platzhirsch auf, brüllt
Leute nieder und beleidigt sie auch persönlich. Es gibt einige
Beispiele, wie er auf kleinste Kritik oder Ironie, Ausfallerscheinungen
zeigt. Andreas hat irgendwo einmal vom 'ollen 8051' gesprochen. Ganz
nett und ironisch gemeint - schon ging das Gepolter los.
Es gab mal einen Betreff 'Peter Dannegger', der nur ein einziges
Schimpfwort enthielt. Der wurde gleich wieder gelöscht: korrekt. Das
hat kein Niveau. Aber es muß schon eine Form zulässig sein, diesem
Peter zu widersprechen, auch wenn es im jeweiligen Einzelfall
unverstanden bleibt.



Zu Deiner Antwort: falls ich mich falsch erinnere, tut mir leid. Aber
gleich eine Verleumdung zu unterstellen ist schon sehr heftig.


Letztlich ist es egal, wer auch immer die ganzen 'Murksversionen' vom
GCC verbrochen hat. Dem Einsteiger werden damit letzlich kaum
überwindbare Hürden in den Weg gelegt. Was ich sagen möchte, daß auch
ich trotz positiver Grundeinstellung zu GCC mit dem Versionswirrwarr
nicht klargekommen und abgetörnt worden bin. Schade.

Vielleicht sind auch unsere Ansprüche für den Durchschnitt teilweise
einfach zu abgehoben. Belassen wir es dabei.

von Matthias (Gast)


Lesenswert?

Erst mal Danke für Eure vielen aktiven Beiträge.
So kommt Leben in das Thema. :-)

@Jörg: Den Tipp mit dem Assembler, der auch
float kann finde ich sehr interessant. Danke!

@Jörg:
@Peter:
Zum Thema "ich würde ein solches
Projekt nicht mit einem AT90S2313" kann ich nur
beipflichten. Ich würde es normalerweise auch
nicht tun. Ich habe aber die kleine Platine von
Michael schon fertig und da passt nun mal kein
anderer Baustein drauf, wie ich es sehe. Oder?

Auf der anderen Seite ist klar, daß wenn man
etwas später mal in größeren Stückzahlen macht
dann natürlich schon wichtig ist, was der
Controller kostet. Daher Michaels Ansatz mit dem IAR.

@Peter: Du schreibst: "Ansonsten hat mein Source-Code die
volle Funktion und ist nicht nur ein
auf 140kHz eingeschränktes Beispielprogramm."
Lieber Peter, ich würde auch gerne einmal Deinen
Code nehmen. Mir geht es um die Funktion des Zählers.
Ich habe halt einen Frequenzgenerator, wo ich die alte
Scheibe nicht mehr mag, weil sie groß und ungenau ist.
Ich habe nun die kleine Zählerplatine von Michael.
Wenn Du einen dazu passenden Code hättest, den ich
mit dem GNU übersetzen kann und der dann eben ins
chip auf der Platine passt . . .  ein 2313 eben . . .

Die Idee mit den aufgebohrten Standardroutinen
auf 56Bit Integer finde ich interessant.

@Jörg: Gerne möchte ich die Sache mit den besseren
Gleitkommaroutinen mal verfolgen. Du hast die email
seit ein paar Minuten.

von Joerg Wunsch (Gast)


Lesenswert?

> Den Tipp mit dem Assembler, der auch float kann finde ich sehr
> interessant. Danke!

Allerdings ist Dein Problem ja nicht der generierte Compilercode,
sondern die Bibliotheken, die die einzelnen Operationen implementieren
-- es sei denn, Du willst sie Dir komplett selbst schreiben.

Du hast schon recht, zum AT90S2313 ist nichts weiter pinkompatibel,
das mehr ROM hätte.  Selbst ein ATtiny2313 wäre keine Hilfe.

Ist es eine DIL-Ausführung?  Dann hättest Du zumindest genug Platz,
eine SMD-Variante eines ATmega8 oder so huckepack mit einem Adapter
reinzunageln.

von Matthias (Gast)


Lesenswert?

@Jörg: Es ist ein DIL. Somit könnte also Huckepack
gehen. Da ist es dann aber doch einfacher den
fertigen Code von Michael, den er optimiert hat
einfach als hex zu laden.

Es ist halt nur allgemein mal interessant mal
zu sehen, was so geht mit GCC. Den AVR-Assembler
habe ich viel genutzt, aber nun wollte ich mal
was lesbareres haben, wo ich den Code dann auch
mal auf einen MSP430 portieren kann, ohne wieder
alles komplett umzuschreiben.

Daher also das Interesse für GCC und effiziente
Verfahrensweisen und portable Bibliotheken.

Leider sind die Routinen von Timo wohl eher
auf Laufzeit optimiert als auf Codegröße.
Mal sehen, was ich dazu herausfinden kann.

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

@Matthias,

"ich würde auch gerne einmal Deinen Code nehmen."

hier ist er:

http://www.mikrocontroller.net/forum/read-1-46449.html#46451

Ich bin bloß noch nicht dazu gekommen, eine Beschreibung dazu zu
machen, sonst hätte ich ihn schon in die Codesammlung gestellt.
Ich bin halt ein bischen zu sehr Perfektionist, d.h. ich will immer
alles möglichst ordentlich machen.
Daher passiert es auch hin und wieder, daß es manchmal falsch aufgefaßt
wird, wenn ich Verbesserungen oder nur meine eigene Meinung poste
(siehe oben). Damit muß man halt leben.
Immerhin sind meine Argumente auch nachvollziehbar und nicht aus der
Luft gegriffen oder beleidigend.


Der 2051 ist mit dem 2313 sogar pinkompatibel ausgenommen die
entgegengesetzte Resetpolarität. Wenn Du also die Platine nutzen
willst, könnte das eine Alternative sein, bzw. der 4051 (4kByte).

Allerdings unterstützt die Keil-Testversion kein float, aber mit dem
SDCC könnte es vielleicht in die 4kB des 4051 passen.

Etwas tricky ist am 8051 eigentlich nur das Auslesen der Timer während
sie laufen, da Überläufe auftreten können. Und da ich insgesamt 3 Byte
Zählerwerte habe, muß ich beim Auslesen 2-mal auf Überlaufe testen und
korrigieren.


Anbei auch noch die 56-Bit Routinen, falls Du doch den 2313 nehmen
willst. In Asssembler sollten die 2kB ja dicke reichen.


Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.