Forum: Mikrocontroller und Digitale Elektronik Code abspecken


von Markus (Gast)


Lesenswert?

Hallo,

ich möchte auf einem Arduino Nano 2 libs verwenden + wenige Zeilen 
eigener Code.
Die libs sind U8glib für ein Grafikdisplay und UIPEthernet für ein 
Ethernetshiled mit ENC28J60 Controller.

Leider Umfasst der fertige code nun 32.618 Bytes und passt somit nicht 
auf den Arduino.
Ich habe schon mal angefangen dinge in der U8glib rauszuwerfen, 
hauptsächlich Grafigroutinen da ich ohnehin nur Text ausgeben möchte. 
Hat leider nix gebracht. Entweder compiliert es nur das was es ohnehin 
benötigt wird oder ich hab das falsche gelöscht.

Daher nun die Fragen:
- Was kann, soll oder muss ich in den beiden libs löschen damit sich der 
code veringert?
- Bringt es was einen anderen Compiler zu nehmen, z.b. es mit dem AVR 
Studio zu compilieren?
- Ich habe noch einen ISP Programmer hier. Könnt ich dan auf den USB 
bootloader verzichten und damit mein Programm unterbekommen?

Danke euch!

von Pandur S. (jetztnicht)


Lesenswert?

Dann hast du moeglicherweise zuviele funktionen verwendet...

floating point raus ?

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Anderer Compiler wird nicht viel bringen. AVR Studio basiert zudem auch 
auf dem GCC. Das ist eben der Nachteil von C++ und vorgefertigten Libs. 
Hier erkauft man sich Bequemlichkeit und Übersichtlichkeit durch 
Speicher. Dass man mit ein paar Zeilen Code komplexe Peripherie 
einbinden kann und auf das Internet zugreifen,  muss ja irgendwo 
herkommen. Das einfachste wird es wohl sein einfach einen anderen 
Controller uz nehmen. Z.B. den Atmega 2560

von Peter D. (peda)


Lesenswert?

Markus schrieb:
> Ich habe schon mal angefangen dinge in der U8glib rauszuwerfen,
> hauptsächlich Grafigroutinen da ich ohnehin nur Text ausgeben möchte.
> Hat leider nix gebracht.

Kann auch nicht.
Der große Brocken sind die verschiedenen Zeichensätze. Ein GLCD versteht 
kein ASCII, d.h. die Routinen müssen jedes Zeichen erst in das 
Pixelmuster umsetzen.
Vielleicht kanst du Zeichensätze abwählen.

Und Ethernet ist noch nie klein gewesen.

Für Ethernet + GLCD sind nur 32kB doch ganz o.k.

: Bearbeitet durch User
von Markus (Gast)


Lesenswert?

Thomas Holmes schrieb:
> Anderer Compiler wird nicht viel bringen. AVR Studio basiert zudem
> auch
> auf dem GCC. Das ist eben der Nachteil von C++ und vorgefertigten Libs.
> Hier erkauft man sich Bequemlichkeit und Übersichtlichkeit durch
> Speicher. Dass man mit ein paar Zeilen Code komplexe Peripherie
> einbinden kann und auf das Internet zugreifen,  muss ja irgendwo
> herkommen. Das einfachste wird es wohl sein einfach einen anderen
> Controller uz nehmen. Z.B. den Atmega 2560

:-) Zum einen merkst du an das man es sich mit libs einfach macht, zum 
anderen empfilst du mir es mir einfach zu machen indem ich einen anderen 
Controller nehme.

Ich würde es gern vermeiden, einen anderen Controller zu nehmen. Das ist 
auch mit viel Aufwand und Geld verbunden. Ein Board selber machen möcht 
ich nicht, das Arduino Board mit dem Controller ist viel größer -> 
gröseres Gehäuse. Das Ethernet Shild passt genau auf den Nano, nicht auf 
den großen..etc.

von Markus (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Für Ethernet + GLCD sind nur 32kB doch ganz o.k.

Wenn jetzt noch in den Controller passen würde wäre es noch besser :p

Beim Ethernet brauch ich eigentlich auch nur die möglichkeit ein UDP 
Paket abzusetzen. Den rest bräuchte ich eigentlich nicht. Mal schaun ob 
ich da was an code spaaren kann. Ist es den warscheinlich, dass ich das 
kleiner bekomme oder wird nur das compiliert was auch gebraucht wird? 
ich lösche hier schon die ganze Zeit frölich dur die Gegend ohe auch nur 
ein bit zu spaaren....

von Karl H. (kbuchegg)


Lesenswert?

Erst mal vom Linker ein Map File anfordern und dort nachsehen, was 
wieviel Speicher frisst. Ich denke auch, dass du wohl auf die/den Fonts 
als Speicherfresser stossen wirst.

Dann hängt es davon ab, um wieviel du über der Grenze drüber bist. Wenn 
nicht viel fehlt, kann man versuchen nicht benötigte Funktionen zu 
identifizeren und rauszuwerfen. Auch über die Verkürzung von 
Text-Konstanten kann man das eine oder andere Byte gewinnen.
Dann ist a natürlich noch der Bootloader. Wenn du den nicht brauchst, 
dann ist das schon ein ordentliches Stück Flash, dass da frei wird.

von Karl H. (kbuchegg)


Lesenswert?

Markus schrieb:

> Beim Ethernet brauch ich eigentlich auch nur die möglichkeit ein UDP
> Paket abzusetzen. Den rest bräuchte ich eigentlich nicht. Mal schaun ob
> ich da was an code spaaren kann. Ist es den warscheinlich, dass ich das
> kleiner bekomme oder wird nur das compiliert was auch gebraucht wird?

Eher unwahrscheinlich. Denn geade Ethernet besteht ja nicht nur aus 
Funktionen, die du aufrufst, sondern auch aus Funktionalitäten, die über 
Netzwerkpakete getriggert werden. Eine Ping Antwort wird nun mal über 
die eingehende Ping Anfrage getriggert.

> ich lösche hier schon die ganze Zeit frölich dur die Gegend ohe auch nur
> ein bit zu spaaren....


Map File ansehen!
Ohne zu kontrollieren, was wieviel Speicher frisst und wie alles kleiner 
wird, ist das sinnlos.

von drucker (Gast)


Lesenswert?

ansonsten hilft es auch noch:

- so wenig globale Variablen zu verwenden wie möglich
- globale Funktionen und Variablen, wenn diese nur in der einen Datei 
verwendet werden, als static zu deklarieren
- den compiler auf size optimieren lassen

Viel Glück

von u8glib (Gast)


Lesenswert?

Hallo Markus

Welchen Font verwendest du denn? Ist es nur einer oder mehrere?
In den Wiki Pages der u8glib sind ja alle Fonts inklusive des benötigten 
Speicherplatzes dokumentiert. Villeicht tut es ja auch ein kleinerer 
Font. Ausserdem gibt es zu jedem Font eine abgespeckte Veriante (Postfix 
"r"), der die ASCII Zeichen von 128 bis 255 nicht enthält.

Oliver

von Georg (Gast)


Lesenswert?

Markus schrieb:
> Ist es den warscheinlich, dass ich das
> kleiner bekomme oder wird nur das compiliert was auch gebraucht wird?

Compiliert wird was drin steht, ob auch einfach alles zusammengelinkt 
wird oder nur was gebraucht wird, ist eine Frage des Linkers - früher, 
als Platz noch knapp war, war es gute Praxis, dass der Linker die 
Abhängigkeiten scannt und nur das linkt, was tatsächlich aufgerufen 
wird, aber heute in Zeiten unbegrenzten Speicherplatzes sparen sich das 
viele Hersteller und z.B. Floating Point Arithmetik wird einfach 
komplett mit allen Funktionen dazugelinkt, auch wenn man nur Addition 
und Subtraktion verwendet. Dadurch kommt es dann auch zustande, dass ein 
"hello world" megabyte gross wird.

Wenn du die Sources der Libraries hast, kannst du natürlich selbst alles 
Überflüssige rauslöschen (ist aber mühsam), aber dann hast du eben keine 
universelle Library mehr, sondern eine nur für dieses eine Projekt.

Georg

von Jürgen S. (jurs)


Lesenswert?

Markus schrieb:
> Leider Umfasst der fertige code nun 32.618 Bytes und passt somit nicht
> auf den Arduino.

Kompiliert mit einer Version 1.0.x oder einer Version 1.5.7 (oder höher) 
der Arduino-IDE?

Wenn die Dateigröße sich mit einer IDE-Version bis 1.5.6 ergibt, 
verwende stattdessen die Version 1.5.7 oder höher! Diese ist auf einen 
neuen und besser optimierenden GCC-Compiler umgestellt, der knapp 10% 
kleinere Programme erzeugt.

von Markus (Gast)


Lesenswert?

u8glib schrieb:
> Welchen Font verwendest du denn? Ist es nur einer oder mehrere?

ich brauche nur einen Font. Dem Hinweis werde ich nachgehen. Vielen Dank 
dafür

Jürgen S. schrieb:
> Kompiliert mit einer Version 1.0.x oder einer Version 1.5.7 (oder höher)
> der Arduino-IDE?

Ich kann das (noch) nicht beantworten. Ich bin gerade dabei meine 
Umgebung auf AVR Studio 6 umzstellen. Bis jetzt war ich dazu zu faul, 
aber ich vermisse auch viele Funktionen vom Studio, sodass ich das jetzt 
angehe.

von Karl Käfer (Gast)


Lesenswert?


von Jürgen S. (jurs)


Lesenswert?

Markus schrieb:
> ich vermisse auch viele Funktionen vom Studio, sodass ich das jetzt
> angehe.

Ja klar doch: Deine Programmierung besteht darin, dass Dein Programm zu 
99,9% aus fremdem Code besteht (AVR LIBC, Arduino Core-Library und zwei 
Drittanbieter-Libraries), eigene Aussage von Dir:
> ich möchte auf einem Arduino Nano 2 libs verwenden
> + wenige Zeilen eigener Code.

Aber für die 0,01% des Codes, den Du im fertigen Programm tatsächlich 
selber schreibst statt aus Libraries inkludierst, vermißt Du "viele 
Funktionen" vom AVR Studio.

Anyway. Wenn Deine Toolchain steht, kannst Du so ein Testprogramm laufen 
lassen, um Dir die GCC- und AVR LIBC-Versionsnummer auf Serial ausgeben 
zu lassen
1
void setup() {
2
  Serial.begin(9600);
3
  Serial.println();
4
  
5
  Serial.print(F("__VERSION__ = "));
6
  Serial.println(F(__VERSION__));
7
  Serial.print(F("__AVR_LIBC_VERSION_STRING__ = "));
8
  Serial.println(F(__AVR_LIBC_VERSION_STRING__));
9
}
10
11
void loop() {
12
}

Wenn die Ausgabe dann so etwas in der Art ergibt:
1
Version: 4.3.2
2
AVR LIBC Version: 1.6.4
hast Du eine veraltete Arduinoversion, die größere Programme erzeugt.

Und wenn die Ausgabe so etwas ergibt:
1
Version: 4.8.2
2
AVR LIBC Version: 1.8.0
bist Du beim neueren GCC-Compiler, der besser optimierten Code und 
kleinere Programme erzeugt.

BTW: 32.618 Bytes sind weniger als die 32KB (32.768 Bytes), die auf 
einem Atmega328 als Flash-Speicher zur Verfügung stehen. Für die 
Arduino-IDE brauchst Du daher eigentlich gar kein kleineres Programm, 
sondern einfach nur eine andere Board-Definition für die "boards.txt" 
Datei, in der kein Bootloader definiert ist und die Fuses so geändert 
sind, dass kein Platz für einen Bootloader reserviert wird), und kannst 
das Programm dann über einen ISP-Programmer (ggf. "Arduino as ISP") 
statt über den Bootloader hochladen.

von Daniel A. (daniel-a)


Lesenswert?

Jürgen S. schrieb:
> Testprogramm laufen lassen

Viel zu aufwendig!
Etwas preprocessing reicht:
echo -e "Version: __VERSION__\nAVR LIBC Version: 
__AVR_LIBC_VERSION_STRING__" | avrgcc -E -

von Leo C. (rapid)


Lesenswert?

Daniel A. schrieb:
> Etwas preprocessing reicht:
> echo -e "Version: __VERSION__\nAVR LIBC Version:
> __AVR_LIBC_VERSION_STRING__" | avrgcc -E -

1
$ echo -e "Version: __VERSION__\nAVR LIBC Version: __AVR_LIBC_VERSION_STRING__" | avrgcc -E -
2
avrgcc: command not found

1
$ echo -e "Version: __VERSION__\nAVR LIBC Version: __AVR_LIBC_VERSION_STRING__" | avr-gcc -E -
2
# 1 "<stdin>"
3
# 1 "<command-line>"
4
# 1 "<stdin>"
5
Version: "4.8.1"
6
1 LIBC Version: __AVR_LIBC_VERSION_STRING__

1
$ echo "#include <avr/io.h>" | avr-gcc -dD -E - |grep VERSION
2
#define __VERSION__ "4.8.1"
3
#define __GXX_ABI_VERSION 1002
4
In file included from <stdin>:1:0:
5
/usr/lib/avr/include/avr/io.h:606:6: warning: #warning "device type not defined" [-Wcpp]
6
 #    warning "device type not defined"
7
      ^
8
#define _AVR_VERSION_H_ 
9
#define __AVR_LIBC_VERSION_STRING__ "1.8.0svn"
10
#define __AVR_LIBC_VERSION__ 10800UL

von Random .. (thorstendb) Benutzerseite


Lesenswert?

beim armcc gibts "One Elf Section per Function"...

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.