Forum: Compiler & IDEs Code zu groß, Attiny13, WinAVR+AVR Studio


von Julian L. (julianl)


Lesenswert?

Hallo.

Vorneweg: µC-Anfänger
Software:
AVR Studio 4.13.571  Service Pack 2
AvrPluginavrgccplugin  1, 0, 0, 9 (WinAVR-20071221)

Mit dieser Ausstattung versuche ich untenstehenden Code zu compilieren, 
jedoch kommt dabei eine viel zu große Datei heraus.
An welcher falschen Einstellungen könnte es liegen?

Vielen Dank für eure Hilfe.

mfg
julian

1
Build started 23.2.2008 at 14:09:42
2
avr-gcc.exe  -mmcu=attiny13 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT test.o -MF dep/test.o.d  -c  ../test.c
3
In file included from ../test.c:3:
4
c:/winavr-20071221/bin/../avr/include/avr/delay.h:36:2: warning: #warning "This file has been moved to <util/delay.h>."
5
avr-gcc.exe -mmcu=attiny13 -Wl,-Map=test.map test.o     -o test.elf
6
avr-objcopy -O ihex -R .eeprom  test.elf test.hex
7
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex test.elf test.eep || exit 0
8
avr-objdump -h -S test.elf > test.lss
9
10
AVR Memory Usage
11
----------------
12
Device: attiny13
13
14
Program:    3760 bytes (367.2% Full)
15
(.text + .data + .bootloader)
16
17
Data:        266 bytes (415.6% Full)
18
(.data + .bss + .noinit)
19
20
21
Build succeeded with 1 Warnings...
1
#define F_CPU  8000000        // Quarzfrequenz 8MHz
2
#include <avr/io.h>
3
#include <avr/delay.h>
4
unsigned char f, i;
5
unsigned char led_abfrage(unsigned char zeit) {
6
   
7
  PORTB &= ~(1<<PB3);         //  Portb.3 auf Masse schalten
8
  PORTB |=  (1<<PB4);         //  Portb.4 auf +Ub schalten, um die LED zu 'laden'
9
  _delay_us(10);              // Ladezeit 10 (1) µs, kann ggf. noch verkleinert werden
10
  DDRB  &= ~(1<<PB4);         // Portb.4 nun zwecks Abfrage der LED-Ladung auf 'Eingang' schalten
11
  PORTB &= ~(1<<PB4);         // Pullup abschalten, sonst geht's nicht!
12
  _delay_ms(zeit);            // Entladezeit zeit_ms (1500 µs) - je kleiner, je unempfindlicher
13
  i = (PINB & (1<<PINB4));    // Ladezustand einlesen
14
  DDRB  |=  (1<<PB4);         // Portb.4 wieder auf Ausgang schalten
15
  PORTB &= ~(1<<PB4);         // Portb.4 auf Masse schalten
16
   
17
  return i;
18
}
19
int main(void) {
20
  DDRB  = 0b00011000;         // Pinb.3 und .4 auf 'Ausgang', Rest auf 'Eingang' schalten
21
  PORTB = 0b11100111;         // Pullups zuschalten, außer für Pinb.3 und .4
22
 
23
  while (1) {
24
    if ( led_abfrage(6) == 0) {          // LED durch Licht entladen?
25
      for (f = 0; f < 10 ; f++) {        // 10x blinken
26
        PORTB |=  (1<<PB3);               // PB3 auf Vcc schalten
27
        _delay_ms(32);                    // 32 ms Blitz
28
        PORTB &= ~(1<<PB3);               // PB3 auf GND schalten
29
        for (i = 0; i < 10 ; i++) 
30
          _delay_ms(32);      // ca. 320ms Pause (workaround wegen 8MHz Quarz)
31
      }
32
    }
33
  }
34
  return 0;
35
}

von Karl H. (kbuchegg)


Lesenswert?

Dein Problem liegt hier
1
  _delay_ms(zeit);            // Entladezeit zeit_ms (1500 µs) - je

Die Delay Zeit ist keine Konstante. Dadurch ist es dem Optimizer
nicht mehr möglich die Berechnung komplett zu optimieren und
du ziehst dir damit die komplette Floating Point Library ins
Programm hinein.

ersetzte das durch
1
  _delay_ms(6);

und deine Programmgröße schrumpft auf 180 bytes.

von Karl H. (kbuchegg)


Lesenswert?

Nachtrag:
Wenn du eine variable Wartezeit brauchst, dann mach es so,
dass das Argument zu _delay_ms auf jeden Fall eine Konstante
ist
1
#define F_CPU  8000000        // Quarzfrequenz 8MHz
2
#include <avr/io.h>
3
#include <avr/delay.h>
4
unsigned char f, i;
5
6
void delay( unisgned char ms )
7
{
8
  unsigned char i;
9
10
  for( i = 0; i < ms; ++i )
11
    _delay_ms( 1 );
12
}
13
14
15
unsigned char led_abfrage(unsigned char zeit) {
16
   
17
  PORTB &= ~(1<<PB3);         //  Portb.3 auf Masse schalten
18
  PORTB |=  (1<<PB4);         //  Portb.4 auf +Ub schalten, um die LED zu 'laden'
19
  _delay_us(10);              // Ladezeit 10 (1) µs, kann ggf. noch verkleinert werden
20
  DDRB  &= ~(1<<PB4);         // Portb.4 nun zwecks Abfrage der LED-Ladung auf 'Eingang' schalten
21
  PORTB &= ~(1<<PB4);         // Pullup abschalten, sonst geht's nicht!
22
  delay( zeit );              // Entladezeit zeit_ms (1500 µs) - je kleiner, je unempfindlicher
23
  i = (PINB & (1<<PINB4));    // Ladezustand einlesen
24
  DDRB  |=  (1<<PB4);         // Portb.4 wieder auf Ausgang schalten
25
  PORTB &= ~(1<<PB4);         // Portb.4 auf Masse schalten
26
   
27
  return i;
28
}
29
int main(void) {
30
  DDRB  = 0b00011000;         // Pinb.3 und .4 auf 'Ausgang', Rest auf 'Eingang' schalten
31
  PORTB = 0b11100111;         // Pullups zuschalten, außer für Pinb.3 und .4
32
 
33
  while (1) {
34
    if ( led_abfrage(6) == 0) {          // LED durch Licht entladen?
35
      for (f = 0; f < 10 ; f++) {        // 10x blinken
36
        PORTB |=  (1<<PB3);               // PB3 auf Vcc schalten
37
        _delay_ms(32);                    // 32 ms Blitz
38
        PORTB &= ~(1<<PB3);               // PB3 auf GND schalten
39
        for (i = 0; i < 10 ; i++) 
40
          _delay_ms(32);      // ca. 320ms Pause (workaround wegen 8MHz Quarz)
41
      }
42
    }
43
  }
44
  return 0;
45
}

von Julian L. (julianl)


Lesenswert?

Wahnsinn, so schnell eine Antwort. Hut ab!

Vielen Dank, nun wird mir einiges klarer.

mfg
Julian

von Christoph (Gast)


Lesenswert?

Hallo,
ich hab eine ähnliches Problem.
Ich verwende AVR Studio 4.12.490  Service Pack 3 (WinAVR 20060421)
und bei mir wird die die selbe Warnung angezeigt. Der Fehler trat erst 
auf, als ich in mein Programm die stdlib.h eingefügt habe und diese für 
die Ausgabe einer Float-Variabel verwendet habe. Das Programm wird viel 
zu groß und passt gar nicht mehr auf den Atmega8 drauf.
1
 
2
#include <avr/delay.h>
3
#include <avr/io.h>
4
#include "definitions.h"
5
#include "stdlib.h"
6
.
7
.
8
.
9
void wert_send(void)
10
{
11
  unsigned short i;
12
  float a;
13
  char s[8];
14
  i=start_adc();
15
  a=i*0,0025;
16
  dtostrf(a,5,3,s);
17
  lcd_string(s);
18
}
19
20
21
22
void lcd_string(char *data)
23
{
24
    while(*data) {
25
        data_send(*data);
26
        data++;
27
    }
28
}

Ich hoffe, ihr könnt mir helfen.
Vielen Danke schonmal im Voraus.

von Karl H. (kbuchegg)


Lesenswert?

Christoph wrote:

> auf, als ich in mein Programm die stdlib.h eingefügt habe und diese für
> die Ausgabe einer Float-Variabel verwendet habe.

Da haben wir's doch schon.
Du ziehst dir die komplette Floating Point Library rein und die
braucht eben Platz.

-> Auf floating point verzichten und auf Fixkomma umsteigen.

von Christian R. (supachris)


Lesenswert?

Christoph wrote:
> Der Fehler trat erst
> auf, als ich in mein Programm die stdlib.h eingefügt habe und diese für
> die Ausgabe einer Float-Variabel verwendet habe. Das Programm wird viel
> zu groß und passt gar nicht mehr auf den Atmega8 drauf.

Tja, die Floating Point Lib ist nun mal so groß. Versuche, mit 
Integer-Arithmetik auszukommen...

von Christoph (Gast)


Lesenswert?

Hallo,
vielen Danke für die schnelle Antwort. Ich werde mich dann wohl 
demnächst mit den zwei genannten Methoden beschäftigen müssen. Nochmal 
vielen Dank.
Gruß Christoph

von Karl H. (kbuchegg)


Lesenswert?

In deinem Fall würde es sich anbieten, einfach die Berechnung * 10000
zu machen und dafür bei der Ausgabe an der 10000-er STelle das Komma
einzuschmuggeln
1
void wert_send(void)
2
{
3
  unsigned short i;
4
  int a;
5
  char s[10];
6
7
  i = start_adc();
8
  a = i * 25;
9
  sprintf( s, "%d.%04d", a / 10000, a % 10000 );
10
  lcd_string( s );
11
}

sprintf ist zwar teuer, weil es eine eierlegende Wollmilchsau
ist, aber wenn sich das vom Platz her noch ausgeht, warum nicht?
Wenn das immer noch zu gross ist, dann müsste man einen Ersatz
für sprintf schreiben.

von Christoph (Gast)


Lesenswert?

Hallo,
Sprintf hat recht gut funktioniert. Ich bin jetzt bei 6,22Kbyte. Das ist 
zwar noch recht groß, geht aber auf den Atmega drauf und reicht für den 
Zweck aus^^. Vielen, vielen Dank für die Hilfe, Karl Heinz.

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.