www.mikrocontroller.net

Forum: Compiler & IDEs Programm zu gross/ Sparpotential?


Autor: flyingwolf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: dasdas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!?

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
      }
    }
  }
}

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
void daten_auswerten_1 (void)
{
   register uint8_t v0, v1;

   v0 = demost[0];
   v1 = demost[1];

  if( tabcount == 3 && v0 ==';') {
    if( v1 == 'V' )
      ...
  }
  ... 
}

Zudem kannt du im unteren Bereich (tabcount==4 und 5)
demost[1] !=';';
ausklammern.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: flyingwolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
send_string_uart("DIS!"); aber wie bekomme ich 0x13 ans Ende der
Ausgabe?
send_string_uart("DIS!\n");

Autor: Fritz Ganter (fritzg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
send_string_uart("DIS!\n");
bzw.
send_string_uart("DIS!\r");
wenns wirklich CR sein muss.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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)

Autor: flyingwolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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?

Autor: flyingwolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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 ...

Autor: André Kronfeldt (freakazoid)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
BTW: 0x0d != 0x13 ;-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

falls du dein Code nicht weiter optimiert bekommst sollte der Mega8
Nachfolger helfen.

http://www.atmel.com/dyn/products/product_card.asp...

Autor: flyingwolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Dirk
Super Idee. Danke.

Autor: flyingwolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@André Kronfeldt
Du hat natürlich Recht 0x0d muss es heissen und nicht 0x13

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.