Hallo Forum, benutzte seit kurzem den GCC im AVR-Studio. Jetzt habe ich das Problem dass der Code für meinen 2313 etwas zu groß ist (5k7Bytes). Mir ist schon klar dass durch das einbinden von Bibliotheken der Code wächst. Wie kann man aber einstellen dass nicht alle Funktionen gelinkt werden die in der Bib drin sind. Ich benötige Funktionen aus <stdio.h> <ctype.h> und <stdlib.h> (fdevopen, printf, gets, scanf) und möchte die nicht unbedingt selber schreiben. Hab keine Ahnung wo ich das einstellen kann und von Makefiles hab ich ehrlich gesagt keine Ahnung. Schönen Gruß Timo
Bist Du sicher, dass Du z.B. printf wirklich brauchst? Wenn Du nur irgendwelche Zahlen in Strings konvertieren willst (was viele Leute z.T. aus Unwissenheit über Alternativen immer noch mit dem "Monster" printf implementieren), dann benutze besser die Funktionen itoa, dtostr usw. aus der stdlib.h. Die erzeugen signifikant weniger Overhead (weil sie eben nur spezielle Funktionen ausführen und nicht den ganzen anderen Mist mit rumschleppen) und sind deshalb für solche Aufgaben eher zu empfehlen. Und wenn Du Strings z.B. über die serielle Schnittstelle ausgeben willst, und es von der Codegröße her nicht passt, wirst Du nicht umhinkommen, zumindest die für Deine Anwendung spezifischen Ausgaberoutinen selber zu schreiben (was aber auch nicht so kompliziert ist, wenn man die Strings, die man ausgeben will, schon vorliegen hat).
Danke für deine Antwort johnny, hab mir jetzt mal das Listfile angeschaut. Da werden ja fast alle Funktionen von der Stdiolib eingebunden. Die Funktionen die ich aufrufe brauchen wohl wieder andere Funktionen aus dieser Bibliothek. Werde also nicht drum rum kommen selbst was zu schreiben. Es geht eigentlich nur darum an den UART einen Befehl (AT-Befehl) zu senden. Hab mir halt dazu ein Beispiel für nen 8535 konvertiert, allerdings sind da halt printf scanf und gets drin. Hab auch schon im Datenblatt von 2313 ein sendebeispiel für den UART gefunden. Werde mich also da heute mal ran machen. Falls Du ein Beispiel kennst immer her damit. Timo
> Es geht eigentlich nur darum an den UART einen Befehl (AT-Befehl) zu > senden. Dafür ist aber printf und das ganze Drumherum mächtiger Overkill. Ersetz das mal. Du wirst sehen, das ist nicht weiter schwer. Das Problem bei printf() ist, dass es allgemein sein muss. printf() hat ne Menge Möglichkeiten die Ausgabe zu formatieren. Auf einem µC braucht man aber >90% der Funktionalität die printf() bietet meist gar nicht. Bei größeren µC ist das kein Problem, die haben Speicher genug. Bei den Kleinen ist das aber kostbarer, verschenkter Speicherplatz.
Ich halte printf() für einen 2-KiB-Controller auch für zu heftig (und ich habe große Teile davon geschrieben -- ich preise das also eher lieber an, als die Leute von der Benutzung abhalten zu wollen :). Das Mindeste, was du aber tun kannst, ist die Umstellung von fdevopen() auf FDEV_SETUP_STREAM(), damit du das malloc() los wirst. Hab's gerade mal probiert, eine minimale Applikation (mit FDEV_SETUP_STREAM()), die printf() benutzt, um eine UART-Ausgabe zu machen, braucht mit GCC 4.1.1 und -Os für einen ATtiny2313 compiliert 2042 bytes an ROM, lässt also nur noch 6 bytes frei. Wenn du gegen die Minimalversion von printf() linken kannst (die versteht keine Feldbreiten und precision), dann sinkt der ROM-Verbrauch auf 1400 bytes -- das würde wohl gerade noch ein wenig Luft lassen für die Applikation. Wenn du was testest, denk dran, dass
1 | printf("Hello world!\n"); |
noch kein printf() mit dazu linkt; der Compiler optimiert das zu
1 | puts("Hello world!"); |
Wirklich praktikabel halte ich stdio für Controller so ab 8 KiB ROM. Allerdings gibt's da nichts mehr, was pinkompatibel zum ATtiny2313 wäre.
Nur der Vollständigkeit halber noch kurz meine Lösung: Verwende quasi die Beispiel Software aus dem Atmel Datenblatt. Hab mir auch ein paar anregungen von der Fleury Lib geholt und das ganze sieht dann folgendermaßen aus. #define F_CPU 11095200 #define UART_BAUD_RATE 19200 #define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1) void uart_init(unsigned int baudrate) { /* set baud rate */ UBRR = (unsigned char)baudrate; /* enable UART receiver and transmmitter */ UCR = _BV(RXEN)|_BV(TXEN); } void uart_putc(unsigned char data) { while (!(USR & (1<<UDRE))); UDR = data; } void uart_puts(const char *s ) { while (*s) uart_putc(*s++); } Im Main dann mit... uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); void uart_puts("Hallo Welt"); ...aufrufen. ...und der Code ist auf ein Minimum geschrupft. Schönen Gruß Timo
void uart_puts("Hallo Welt"); So aber nicht!!! Wenn so: uart_puts("Hallo Welt"); Gruß Robert
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.