Forum: Mikrocontroller und Digitale Elektronik avr dude Programm zu groß? Eclipse GCC


von Chris T. (chris0086)


Lesenswert?

Hallo Leute, habe ein kleines Programm geschrieben.
Arbeite mit eclipse und GCC Plugin und avr dude.
Beim kompilieren erhalte ich dann folgende Meldung:
**** Build of configuration Release for project lcd ****

make all
Invoking: Print Size
avr-size --format=avr --mcu=atmega32 lcd.elf
AVR Memory Usage
----------------
Device: atmega32

Program:    2500 bytes (7.6% Full)
(.text + .data + .bootloader)

Data:       3155 bytes (154.1% Full)
(.data + .bss + .noinit)

EEPROM:        2 bytes (0.2% Full)
(.eeprom)


Finished building: sizedummy

Wenn ich das Progrsmm dann in den Controller lade funktioniert trotzdem 
alles. Aber warum ist data so groß und kann das Probleme bereiten?
Hier mal mein Programm: (Manches ist ein wenig umständlich)
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/pgmspace.h>
5
#include <util/crc16.h>
6
#include <avr/eeprom.h>
7
#include "uart.h"
8
#include "lib_crc.h"
9
#include <util/delay.h>
10
11
/* define CPU frequency in Mhz here if not defined in Makefile */
12
#ifndef F_CPU
13
#define F_CPU 8000000UL
14
#endif
15
16
//WR Adresse
17
#define WR_ADR 0x01 ;
18
/* 9600 baud */
19
#define UART_BAUD_RATE      9600
20
21
uint8_t count =0;
22
uint8_t timerdelay = 10;
23
volatile uint8_t t_overflow = 0;
24
uint16_t e_p_therme EEMEM ;
25
void entprellung( volatile uint8_t *port, uint8_t maske ) {
26
  uint8_t   port_puffer;
27
  uint8_t   entprellungs_puffer;
28
29
  for( entprellungs_puffer=0 ; entprellungs_puffer!=0xff ; ) {
30
    entprellungs_puffer<<=1;
31
    port_puffer = *port;
32
    _delay_us(150);
33
    if( (*port & maske) == (port_puffer & maske) )
34
      entprellungs_puffer |= 0x01;
35
  }
36
}
37
38
ISR (TIMER1_OVF_vect)
39
{  if(count==timerdelay)
40
  {
41
    //PORTD ^= (1<<PD3); //Toggeln
42
    count=0;
43
    t_overflow = 1;
44
    TIMSK &= ~(1<<TOIE1);
45
  }
46
  count++;
47
}
48
49
ISR (INT0_vect)
50
{
51
  entprellung( &PIND, (1<<PIND2) ); // ggf. Prellen abwarten
52
    if( PIND & (1<<PIND2) )           // dann stabilen Wert einlesen
53
    {
54
      PORTD ^= (1<<PD3); //Toggeln
55
56
      //key_pressed =1; // Taste wurde gedrückt
57
58
    }
59
    else
60
    {
61
62
      // mach was anderes
63
    }
64
65
}
66
67
68
69
uint16_t CRC_ausgeben(uint8_t *werte,uint8_t j)
70
{
71
uint8_t i;
72
uint16_t CRC_r = 0x0000;
73
unsigned short crc =0xFFFF;
74
75
  for(i=0;i<j; i++)
76
       {
77
         if(i==0)
78
         CRC_r=update_crc_16(crc,werte[i]);
79
         else
80
           CRC_r=update_crc_16(CRC_r,werte[i]);
81
       }
82
  return CRC_r;
83
}
84
85
void USART_Transmit( char data )
86
{
87
  /* Wait for empty transmit buffer */
88
  while ( !( UCSRA & (1<<UDRE)) )
89
    ;
90
  /* Put data into buffer, sends the data */
91
  UDR = data;
92
}
93
94
void USART_SendS(uint8_t *werte, uint8_t rep)
95
{
96
  uint8_t i;
97
  for(i=0;i<rep;i++)
98
  {
99
    USART_Transmit(werte[i]);
100
  }
101
}
102
103
int main(void)
104
 {
105
106
     uint8_t sendstring[8];
107
     uint8_t i;
108
109
     uint16_t CRC_VAL;
110
     uint16_t std_value = 0xFFFF ;
111
     uint8_t c;
112
     uint8_t wr_typ = 0;
113
     uint16_t p_therme;
114
//Initialisierung
115
     //USART initialisieren
116
     uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
117
118
     //interrupt an Pin INT0 konfigurieren
119
     DDRD &= ~(1<< DDD2); //Eingang
120
     PORTD |= (1<< PD2);
121
     GICR |= (1<<INT0);
122
     sei();
123
124
     //PIN 3 Port D auf Ausgang
125
     DDRD |= (1<<DDD3);
126
     PORTD |= (1<<PD3); //Einschalten
127
128
     // 16-bit Timer aktivieren Überlauf alle 8,388 Sekunden
129
     TCCR1B |= (1<<CS12)| (1<<CS10);
130
     TIMSK |= (1<<TOIE1);
131
//Programmstart
132
     timerdelay = 0; // 4 = ca. 30 Sekunden warten bis WR bereit
133
134
     sendstring[0]=0x02;
135
     sendstring[1]=0x04;
136
     sendstring[2]=0x00;
137
     sendstring[3]=0x00;
138
     sendstring[4]=0x00;
139
     sendstring[5]=0x02;
140
     /*
141
      * Transmit single character to UART
142
      */
143
     USART_Transmit('\r');
144
145
146
     CRC_VAL = CRC_ausgeben( sendstring,6);
147
148
     i = CRC_VAL; //Low Byte
149
     USART_Transmit(i);
150
     i = CRC_VAL >> 8; //High Byte
151
     USART_Transmit(i);
152
153
     USART_Transmit('\r');
154
155
156
157
158
159
     while(1)
160
     {
161
       if((t_overflow ==1) & (wr_typ == 0))
162
              {
163
              //Thermenleistung aus EEPROM
164
               eeprom_busy_wait();
165
               CRC_VAL = eeprom_read_word(&e_p_therme);
166
                if(std_value == CRC_VAL)
167
                {
168
                 eeprom_busy_wait();
169
                 eeprom_write_word(&e_p_therme, 0x4E20);
170
                }
171
               eeprom_busy_wait();
172
               p_therme = eeprom_read_word(&e_p_therme);
173
               USART_Transmit(p_therme); //Low Byte
174
               USART_Transmit(p_therme>>8); //High Byte
175
               //PORTD ^= (1<<PD3); //Toggeln
176
             //WR-Typ auslesen
177
                sendstring[0]=WR_ADR;
178
                sendstring[1]=0x03; //Holding register
179
                sendstring[2]=0x00;
180
                sendstring[3]=0x00;
181
                sendstring[4]=0x00;
182
                sendstring[5]=0x01;
183
                CRC_VAL = CRC_ausgeben( sendstring,6);
184
                sendstring[6]=CRC_VAL;
185
                sendstring[7]=CRC_VAL>>8;
186
                USART_SendS(sendstring,8);
187
                wr_typ = 1;
188
              }
189
190
     }
191
192
193
 }

von marixstorm (Gast)


Lesenswert?

Der Programmspeicher reicht zwar, aber deine Firmware benötigt mehr RAM 
als der arme MCU hat:

>Data:       3155 bytes (154.1% Full)
>(.data + .bss + .noinit)

Vermutlich hast du zu viele (static) Variablen angelegt/in Verwendung.
Dein Programm läuft daher nur auf den ersten Blick korrekt, aber die 
Wahrscheinlichkeit das Inkonsistenzen auftreten ist enorm, da 
verschiedene Varibalen auf die gleiche Speicheradresse fallen und sich 
daher gegenseitig überschreiben (Schubfachschluss). (Auch Stack zaehlt 
dazu).

MfG

von Chris T. (chris0086)


Lesenswert?

Da oben gepostete war der ganze Code.
Ich persönlich finde du Variablnanzahl überschaubar oder was meinen die 
Experten?

von Walter S. (avatar)


Lesenswert?

Chris tian schrieb:
> Da oben gepostete war der ganze Code.

da du jede Menge h-files includest ist das wohl nicht der ganze Code.
Vielleicht braucht da auch jemand anders viel statische Variablen

von holger (Gast)


Lesenswert?

>Da oben gepostete war der ganze Code.

Nö, ist er nicht.

make.exe
main.c:7:18: error: uart.h: No such file or directory
main.c:8:21: error: lib_crc.h: No such file or directory
main.c: In function 'CRC_ausgeben':
main.c:78: warning: implicit declaration of function 'update_crc_16'
main.c: In function 'main':
main.c:116: warning: implicit declaration of function 'uart_init'
main.c:116: warning: implicit declaration of function 'UART_BAUD_SELECT'
main.c:111: warning: unused variable 'c'
MAKE.EXE: *** [main.o] Error 1

von Chris T. (chris0086)


Angehängte Dateien:

Lesenswert?

Sorry, hab nicht auf die benutzerdefinieten Libs geschaut, wobei ich da 
auch nichts verändert hab und das fertige Libs sind.

von Georg G. (df2au)


Lesenswert?

Meine Glaskugel sagt, dass in der uart.h die Buffergrößen für Eingabe 
und Ausgabe etwas großzügig bemessen sind.

von Oliver (Gast)


Lesenswert?

Beim Compilieren wird ein map-File erzeugt, in dem alle Objekte mit 
Größe aufgelistet sind. Da werden sie geholfen...

Oliver

von Chris T. (chris0086)


Angehängte Dateien:

Lesenswert?

Die Datei ist die angehängte Datei für folgende konfiguration:
1
//#include <stdlib.h>
2
#include <avr/io.h>
3
//#include <avr/interrupt.h>
4
//#include <avr/pgmspace.h>
5
//#include <util/crc16.h>
6
//#include <avr/eeprom.h>
7
//#include "uart.h"
8
//#include "lib_crc.h"
9
//#include <util/delay.h>
10
.
11
.
12
.

Also schon fast alle Libs auskommentiert und trotzdem bleibts bei der 
größe...

von Karl H. (kbuchegg)


Lesenswert?

CRC Routinen

static unsigned short   crc_tab16[256];
static unsigned long    crc_tab32[256];
static unsigned short   crc_tabccitt[256];
static unsigned short   crc_tabdnp[256];
static unsigned short   crc_tabkermit[256];


das sind schon mal 2.0 KB

von Peter II (Gast)


Lesenswert?

Chris tian schrieb:
> Also schon fast alle Libs auskommentiert und trotzdem bleibts bei der
> größe...

die libs sind aber drozdem drin:

Map:
    .bss           0x00800062      0xc0a ./lib_crc.o


und hier ist es:

static unsigned short   crc_tab16[256];
static unsigned long    crc_tab32[256];
static unsigned short   crc_tabccitt[256];
static unsigned short   crc_tabdnp[256];
static unsigned short   crc_tabkermit[256];

von Karl H. (kbuchegg)


Lesenswert?

Diese CRC-Routinen sind super ..... für einen PC.
Für einen kleinen AVR mit 2k SRAM sind sie scheisse.

Man könnte sie umbauen, so dass die Tabellen vorgerechnet werden (zb auf 
einem PC) und dann ins Flash ausgelagert werden.

von Conny G. (conny_g)


Lesenswert?

Wahnsinn, wer macht denn so eine Library für die armen kleinen Atmels 
:-)

von Chris T. (chris0086)


Lesenswert?

Danke für eure Hilfe hab jetzt alle CRC Routinen bis auf dei 16er 
gelöscht, dann komm ich jetzt auf 25,8% das ist doch schonmal was.
Danke für die Mühe!

von Karl H. (kbuchegg)


Lesenswert?

Konrad G. schrieb:
> Wahnsinn, wer macht denn so eine Library für die armen kleinen Atmels
> :-)

Falsche Frage.
richtige Frage: Wer sieht sich Routinen, die er im Internet findet nicht 
genauer an?

von Peter II (Gast)


Lesenswert?

Chris tian schrieb:
> Danke für eure Hilfe hab jetzt alle CRC Routinen bis auf dei 16er
> gelöscht, dann komm ich jetzt auf 25,8% das ist doch schonmal was.
> Danke für die Mühe!

es gibt in der AVR lib schon eine fertig CRC routine, warum nutzt du 
diese nicht?

von Georg G. (df2au)


Lesenswert?

Karl Heinz Buchegger schrieb:
> CRC Routinen

das gibt es aber deutlich preiswerter in der GNU Version...

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.