Forum: Mikrocontroller und Digitale Elektronik Speicherrecourcen reduzieren in C-Programm


von Johnny66 (Gast)


Lesenswert?

Hallo,

habe inzwischen ein relativ großes Programm für den Atmega8 geschrieben 
(in C). Und ich bin an der Grenze des Flash Speichers angekommen. Jetzt 
versuche ich den Code zu komprimieren... Gibt es da allgemeine Tricks 
und Tipps... in der Richtung "statt Switch Case eine For Schleife 
verwenden" oder so?

Ich möchte in meinem Programm u.a. Int in Strings konvertieren und 
Strings nach float. Dazu verwende ich itoa und atof... Wenn ich atof 
einsetze belegt mein Programm aber 1kB mehr Speicher! Kann das sein?
Das Problem ist, ich habe eine Zahl in einem String die ich mit einer 
anderen Zahl multiplizieren muss und anschliessend auf einem LCD 
ausgebe.
Gäbe es da noch andere Wege außer atof und dann zurück in einen String?

Johnny

von Floh (Gast)


Lesenswert?

Johnny66 schrieb:
> float
Wenn du die float-Rechnungen durch Festkommaarithmetik ersetzen kannst 
gewinnst du viel Ressourcen. Die Float-Funktionen brauchen recht viel 
Speicher.
:-)

von Peter D. (peda)


Lesenswert?

Johnny66 schrieb:
> Ich möchte in meinem Programm u.a. Int in Strings konvertieren und
> Strings nach float. Dazu verwende ich itoa und atof...

Hä ???

Wie wärs einfach mit:
1
float superkomplizierte_wandlung_int_nach_float( int zahl )
2
{
3
  return zahl;
4
}


Peter

von Johnny66 (Gast)


Lesenswert?

@Floh: ja, das ist eine Idee, danke!

@Peter: da habe ich mich nicht gut ausgedrückt, sorry. Das ist nicht 
eine Zahl, da gehts um zwei "Baustellen"... einmal will ich eine Int in 
einen String konvertieren und an einer anderen Stell möcht ich eine 
float aus einem String lesen.

von holger (Gast)


Lesenswert?

>und an einer anderen Stell möcht ich eine
>float aus einem String lesen.

Pffffh, auch da lässt sich was mit Festkomma machen.

von Falk B. (falk)


Lesenswert?


von Stefan B. (stefan) Benutzerseite


Lesenswert?

Gesetz von Moore praktisch anwenden: Atmega168 nehmen. Der hat doppelt 
so viel Flash.

von Johnny66 (Gast)


Lesenswert?

Achja... wenn ich das richtig gesehen habe, dann ist der Atmega168 
identisch wie der Atmega8 aufgebaut... nur mit doppelt so großen Flash 
Speicher. D.h. ich brauche in meiner Schaltung und in meinem Programm 
nichts ändern und kann den µC einfach ersetzen?
Wenn ich das Programm nicht komprimiert bekomme werde ich das 
wahrscheinlich machen müssen...

Trotzdem interessiert es mich, wie man so programmiert dass man wenig 
Speicher belegt.

von Oliver J. (skriptkiddy)


Lesenswert?

Johnny66 schrieb:
> Achja... wenn ich das richtig gesehen habe, dann ist der Atmega168
> identisch wie der Atmega8 aufgebaut... nur mit doppelt so großen Flash
> Speicher. D.h. ich brauche in meiner Schaltung und in meinem Programm
> nichts ändern und kann den µC einfach ersetzen?
So einfach ist es leider nicht. Der Atmega8 und der Atmega168 sind nur 
pinkompatibel. Das heißt du kannst deine Schaltung schonmal behalten. 
Allerdings sind sie nicht binärkompatibel. Das heißt du wirst Codeteile 
portieren müssen. Welche das sind, siehst du in der Appnote AVR094 [1].
Das ist zwar die Portierung von Mega8 auf Mega88, aber der Mega168 ist 
zum Mega88 binärkompatibel. Praktisch heißt das Portieren zum Schluss 
meist nicht mehr als ein paar Registernamen/Bitnamen und 
Interruptvektoren im Quelltext anpassen.

[1] http://www.atmel.com/dyn/resources/prod_documents/doc2553.pdf


Gruß Skriptkiddy

von Seltsam (Gast)


Lesenswert?

> Trotzdem interessiert es mich, wie man so programmiert dass man wenig
> Speicher belegt.

Schlaumeierantwort: In dem man aufgeblasenen Code durch schlankeren Code 
ersetzt.

S.o. Floatingpoint statt Fixkomma.

Weniger oder kürzere Textmeldungen benutzen. Texte splitten und 
Recyclen.

Funktionen zu inlinen statt statisch definieren, wenn Funktionen 
vorhanden sind, die sich dafür eignen. Aufruftiefe eher flach halten.

Schlankere Datentypen verwenden. Lokale Variablen bevorzugen.

Externe Libraries unter die Lupe nehmen und granularer machen, damit der 
Linker unbenutzte Funktionen weglassen kann.

Wertetabellen durch Näherungsfunktionen ersetzen. Oder Funktionen durch 
Tabellen ersetzen. Geforderte Genauigkeit überdenken und 
Tabellen/Formeln anpassen.

Softwarefunktionen durch Hardwarefunktionen ersetzen.

PAP überarbeiten und verschlanken. Features weglassen.

von Johnny66 (Gast)


Lesenswert?

Danke!

@Seltsam: wenn ich externe Dateien mit Funktionen einbinde, dann werden 
doch nur die Funktionen eingebunden, die ich wirklich brauche oder?
Und die Variablem werden doch im RAM abgelegt oder? Bringt das was für 
den Flash, wenn ich z.B. statt long int, short int verwende?

von Seltsam (Gast)


Lesenswert?

WinAVR-Toolchain:

Der Linker arbeitet auf der Ebene der Objektdateien. Wenn du in einer 
Objektdatei die Funktionen foo() und bar() hast, aber nur foo() benutzt, 
kann bar() als toter Code in deinem Programm landen. Und Libraries (*.a) 
Dateien sind Archive von Objektdateien. Diese Situation kannst du mit 
dem MAP und dem LSS File einfach feststellen.

Die Initialwerte von globalen und statischen Variablen müssen auch im 
Flash vorhanden sein. Der Startupcode initialisiert die Variablen mit 
den Werten aus dem Flash. Ob das beim Defaultwert (0) ebenso ist, weiss 
ich nicht aus dem Stegreif. Ich vermute, dass nur die Werte ungleich 
Defaultwert iM Flash gespeichert sind und es für den Defaultwert eine 
Ausnullschleife im Startup gibt.

Abhängig von deinem Programm solltest du wo möglich short int statt long 
int benutzen. Noch besser wäre es, wenn du auf 8-Bit gehen kannst wo 
möglich. Du sparst Platz bei den Initialwerten und beim Code. Um 
16-Bit zu verarbeiten sind deutlich mehr Register (=> PUSH/POP) und 
Verarbeitungscode erforderlich als für 8-Bit Werte. Aufpassen: Bei der 
Umstellung Programm peinlich genau aut Integerüberläufe prüfen!

von uitrg789 (Gast)


Lesenswert?

Die Zeit, die du damit verbringst, Deinen Code zu "komprimieren", kostet 
Dich viel mehr, als den µC mit größerem Flash zu kaufen.

Es sei denn, Du willst den µC verkaufen und musst die Software da
irgendwie reinquetschen.

Andersrum geht beim "Komprimieren" häufig die Uberschaubarkeit und 
Struktur des Codes soweit kaputt, dass man den Code danach sowieso nicht 
mehr warten kann.

Daher meine Empfehlung: Sauber Programmieren und wenn's nicht reicht, 
den nächstgrößeren µC einsetzen.

von U.R. Schmitt (Gast)


Lesenswert?

uitrg789 schrieb:
> Andersrum geht beim "Komprimieren" häufig die Uberschaubarkeit und
> Struktur des Codes soweit kaputt, dass man den Code danach sowieso nicht
> mehr warten kann.

Na ja, auf der anderen Seite führt so aufräumen manchmal dazu daß der 
Code entrümpelt und "gewachsene" Geflechte besser strukturiert neu 
gemacht werden. Dann erreicht man damit gerade eine bessere 
Überschaubarkeit.

von uitrg789 (Gast)


Lesenswert?

Ich bin davon ausgegangen, dass der Code vor dem "Komprimieren" noch 
sauber war. Inklusive Überschaubarkeit und Struktur.

Und nicht ein schrottiger Happy-Coding-Code.

von Karl H. (kbuchegg)


Lesenswert?

uitrg789 schrieb:
> Ich bin davon ausgegangen, dass der Code vor dem "Komprimieren" noch
> sauber war. Inklusive Überschaubarkeit und Struktur.
>
> Und nicht ein schrottiger Happy-Coding-Code.

In den meisten Fällen ist er aber genau letzteres :-)

von Sam .. (sam1994)


Lesenswert?

uitrg789 schrieb:
> Die Zeit, die du damit verbringst, Deinen Code zu "komprimieren", kostet
> Dich viel mehr, als den µC mit größerem Flash zu kaufen.
>
> Es sei denn, Du willst den µC verkaufen und musst die Software da
> irgendwie reinquetschen.
>
> Andersrum geht beim "Komprimieren" häufig die Uberschaubarkeit und
> Struktur des Codes soweit kaputt, dass man den Code danach sowieso nicht
> mehr warten kann.
>
> Daher meine Empfehlung: Sauber Programmieren und wenn's nicht reicht,
> den nächstgrößeren µC einsetzen.

Unsinn. Wenn man jedes mal doppelt so viel Flash braucht spart man mehr 
als wenn man effizient programmieren kann.

von Johnny66 (Gast)


Lesenswert?

Danke Leute für die Tips!

Habe vorhin auch noch das Tutorial zur AVR-GCC-Codeoptimierung 
entdeckt... das Tool avr-nm ist ja auch recht hilfreich um festzustellen 
welche Funktion besonders viel Speicher belegt.

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.