Hallo Leute, das Programm das ich im Anhang mitgeschickt habe ist für meine Hardware zu gross geworden. Damit ich es überhaupt in Teilen testen kann, habe ich Funktionen in Main.c auskommentiert, die aber wichtig sind. Das Einfachste wäre, einen mega16 statt einem Mega 8 zu verwenden, aber die Hardware ist blöder Weise schon fertig. Wo habe ich noch Sparpotential?
Hast du vielleicht unnötige Bibliotheken mit dazu gelinkt? Hast du -Os im Makefile gesetzt, so dass der Compiler auf Größe Optimiert? Ansonsten sollte das doch eigentlich in 8K reinpassen!?
Da gibts ne Menge: - nimm char statt int, wenns ausreicht - nimm unsigned statt signed, wenns ausreicht - nimm float nur wo nötig - fasse gleichartige Funktionen zusammen Peter
Ich hab mir mal deine Funktion 'daten_auswerten_1' vorghenommen. Im Original, mit O3 kompiliert: Program: 5730 bytes Nachdem ich sie umgestrickt habe: Program: 5496 bytes also 234 Bytes gespart (und, so denke ich, einen Fehler gefunden) 'daten_auswerten_2' ist nicht ganz so einfach. Das Hauptproblem dürfte hierbei die float-Arithmetik sein. Durch Probieren hab ich gefunden, dass zb. rsl = rsl + ( demost[0] - '0' ); weniger Code erzeugt als rsl = rsl + ( demost[0] - 48.0 ); usw. Ich denke aber mal, dass man durch Durchforsten der komplizierten if-Bedingungen wieder einiges einsparen kann. Ein anderer heisser Kandidat, ist für micht die Funktion ir_string() aus ir_out.c Wenn du da ein paar Tabellen einführst und den grossen switch-case rauswirfst, muesste 1. Der Code wesentlich klarer werden 2. ein Einsparungspotential da sein. (Vielleicht probier ich das noch). Grundlegend solltest du dir aber ueberlegen, ob die Gleitkomma- Arithmetik überhaupt notwendig ist oder ob da nicht auch was anderes ausreichend wäre (zb ein int oder long, wobei alle Zahlen implizit mit 1000 multipliziert sind. 1.0 wird dann als 1000 in einem int gespeichert, 1.45 wäre 1450, usw.)
Ooops. Ich sollte die daten_auswerten1 auch zeigen. Hier ist sie: char convert( char* Digit ) { return ( *Digit - '0' ) * 10 + ( *(Digit+1) - '0' ); } void daten_auswerten_1 (void) { if( tabcount == 3 && demost[0] ==';') { if( demost[1] == 'V' ) setbit( status2, 7 ); else clearbit( status2, 7 ); } if( tabcount == 4 ) { if( demost[0] ==';' && demost[1] !=';' && zeichenzaehler == 1 ) tag = convert( &demost[1] ); if( demost[0] == '.' && demost[1] !=';' ) { if( zeichenzaehler == 4 ) monat = convert( &demost[1] ); else if( zeichenzaehler == 7 ) jahr = convert( &demost[1] ); } } if( tabcount == 5 ) { if( demost[0] ==';' && demost[1] !=';' && zeichenzaehler == 1 ) stunde = convert( &demost[1] ); if( demost[0] ==':' && demost[1] !=';' ) { if( zeichenzaehler == 4 ) minute = convert( &demost[1] ); else if( zeichenzaehler == 7 ) { sekunde = convert( &demost[1] ); step = 3; //test } } } }
Nachdem du in daten_auswerten_1 immer wieder auf demost[0] und demost[1] zugreift, könnte es einige ersparnis bringen diese zuerst in lokale registervariable zu legen und mit diesen Variablen zu arbeiten.
1 | void daten_auswerten_1 (void) |
2 | {
|
3 | register uint8_t v0, v1; |
4 | |
5 | v0 = demost[0]; |
6 | v1 = demost[1]; |
7 | |
8 | if( tabcount == 3 && v0 ==';') { |
9 | if( v1 == 'V' ) |
10 | ...
|
11 | }
|
12 | ...
|
13 | }
|
Zudem kannt du im unteren Bereich (tabcount==4 und 5) demost[1] !=';'; ausklammern.
Hallo. Kannst du dir nicht eine eigene sprintf() stricken, die nur die benötigten Funktionen enthält? printf() braucht allein schon ca. 5k an Speicher. Für characters und Dezimalzahlen sollte das nicht schwer sein, nur die Floats werden komplizierter. Falls du die durch Fixkommazahlen ersetzen könntest, ginge das aber auch. Gruss
Falls Du das Programm(habe mir den Quelltext nicht angesehen) nicht kleiner bekommst, kannst Du ja mal probieren es auf den ATmega168 umzuschreiben. Sollte nicht so schwierig sein.
ich könnte die floats auch durch Strings ersetzen, aber ich komme mit den Dingern einfach in C nicht klar. Zeichenweis kopieren bis eine ; kommt wäre nicht das Problem, aber dann komme ich mit dem zeug nicht mehr klar. Einfaches Beispiel: sprintf(sendstring,"DIS!%c", 0x0d); send_string_uart(sendstring); Das ist schon nicht so gut. Das müßtre doch auch direkt gehen, sowas wie send_string_uart("DIS!"); aber wie bekomme ich 0x13 ans Ende der Ausgabe?
send_string_uart("DIS!"); aber wie bekomme ich 0x13 ans Ende der Ausgabe? send_string_uart("DIS!\n");
send_string_uart("DIS!\n"); bzw. send_string_uart("DIS!\r"); wenns wirklich CR sein muss.
> printf() braucht allein schon ca. 5k an > Speicher. % avr-size ~/avr/lib/avr4/libprintf_flt.a text data bss dec hex filename 2684 0 0 2684 a7c vfprintf_flt.o (ex /user/jwunsch/avr/lib/avr4/libprintf_flt.a)
es muss ganz sicher CR sein, aber wenn ich es recht in Erinnerung habe ging \r nicht, aber ich bin mir nicht ganz sicher obs daran lag oder an einem anderen Fehler
Ich hab mal ein wenig rumprobiert. Die grösste Zunahme, die ich gesehen habe ist die floating point Arithmetik. Sobald da irgendwas reinkommt, schnalzt die Statistik nach oben.
> send_string_uart("DIS!"); aber wie bekomme ich 0x13 ans Ende der > Ausgabe? Falls alle Stricke reissen: send_string_uart( "DIS!\x13" ); Aber was hat das mit float zu tun?
@Karl Heinz << Aber was hat das mit float zu tun? erst mal nix. Es ging um die wegrationalisierung des speicherfressenden sprintf Vielen Dank an alle, die sich hier so hingebungsvoll um mein Problem kümmern. Ich werde mal versuchen, die floats rauszulassen ... An dem Versuch, die Sache mit Strings zu behandeln, bin ich allerdings schon einmal furchtbar gestrandet ...
> An dem Versuch, die Sache mit Strings zu behandeln
Nicht Strings. Fixed Point Arithmetik.
Ist im Grunde ganz einfach: Du rechnest immer nur mit
ganzen Zahlen, merkst Dir aber, dass das Komma an
der zb. 2. Stelle steht.
Du kannst das und machst das schon seit Jahren.
Zb. rechnest du 2 Euro 60 plus 3 Euro 70 ergibt 6 Euro 30
oder mit Gleitkomma: 2.60 + 3.70 -> 6.30
Du hast aber gelernt, dass du das ganze aber auch komplett in Cent
rechnen kannst:
260 cent plus 370 cent ergibt 630 cent
260 + 370 -> 630
Das ist auch nichts anderes als oben. Denk dir einfach
ein Komma zwischen die Hunderter und Zehnerstelle und du hast
wieder deine Eurorechnung von oben.
Hi, falls du dein Code nicht weiter optimiert bekommst sollte der Mega8 Nachfolger helfen. http://www.atmel.com/dyn/products/product_card.asp?part_id=3303
@André Kronfeldt Du hat natürlich Recht 0x0d muss es heissen und nicht 0x13
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.