mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR (ATmega644p): Wie Speicherbedarf prüfen ?


Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich schon wieder. Dank der Hilfe der Guten Geister Dieses Forums habe 
ich es geschafft, meinen ATMega644P zu programmieren. Ich bin von einem 
ATMega32 auf den 644P umgestiegen, weil ich mehr Speicher benötige. Nun 
zeigt sich aber, dass ich wahrscheinlich wieder in Speicherprobleme 
(Überlauf) reinlaufe.

Mit meinem Makefile (siehe Anhang) und
$ make clean && make all

Linking: psuctrl.elf
avr-gcc -mmcu=atmega644p -I. -gdwarf-2 -DF_CPU=8000000UL  -O2 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=controller.o -I/Users/frgo/gnc//avr/gaul -std=gnu99 -MD -MP -MF .dep/psuctrl.elf.d controller.o --output psuctrl.elf -Wl,-Map=psuctrl.map,--cref   /Users/frgo/gnc//avr/gaul/libgaul.a -Wl,-u,vfprintf -lprintf_flt  -lm

Creating load file for Flash: psuctrl.hex
avr-objcopy -O ihex -R .eeprom psuctrl.elf psuctrl.hex

Creating load file for EEPROM: psuctrl.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
  --change-section-lma .eeprom=0 -O ihex psuctrl.elf psuctrl.eep
avr-objcopy: --change-section-lma .eeprom=0x00000000 never used

Creating Extended Listing: psuctrl.lss
avr-objdump -h -S psuctrl.elf > psuctrl.lss

Creating Symbol Table: psuctrl.sym
avr-nm -n psuctrl.elf > psuctrl.sym

Size after:
psuctrl.elf  :
section                     size          addr
.data                         692   8388864
.text                      23942              0
.bss                         1124   8389556
.stab                        1632              0
.stabstr                      198              0
.debug_aranges           512             0
.debug_pubnames     4350             0
.debug_info             26417             0
.debug_abbrev           6897            0
.debug_line              22310            0
.debug_frame            3280            0
.debug_str                 5554            0
.debug_loc               14555            0
.debug_ranges           1912            0
Total                      113375

AVR Memory Usage:
-----------------
Device: atmega644p

Program:   24634 bytes
(.text + .data + .bootloader)

Data:       1816 bytes
(.data + .bss + .noinit)

-------- end --------

Das sieht für mich immer noch gut aus, denn der 644p hat 64k Flash und 
4k SRAM. Das ist alles noch weit von dem entfernt, was ich hier sehe. 
Dennoch bleibt mein Programm hängen - was ich schon vom ATMega32 kenne.

Wie kann ich sicher erkennen, dass ich keine Speicherschreiber habe ? 
Gibt es eine Magic Formula ?

Danke im Voraus für Hinweise!

Grüße
   Frank

Autor: Michael M. (technikus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider läßt sich aus der Ausgabe von .data + .bss + .noinit der 
wirkliche SRAM-Bedarf zur Laufzeit nicht ermitteln. Denn zur Laufzeit 
kostet jede aufgerufene Funktion Platz auf dem Stack (lokale 
Variablen!). Am besten mal den wahren Speicherverbrauch zur Laufzeit 
bestimmen. Eine brauchbare Methode dazu findest Du hier:
http://www.rn-wissen.de/index.php/Speicherverbrauc...

Es kann natürlich leicht sein, daß Dein Code eigentlich mit dem SRAM 
auskommen müßte, Du aber irgendwo ein Speicherleck hast, z.B. schreiben 
über die Array-Grenzen hinaus. Das mußt Du natürlich ausschließen.

Servus
Michael

Autor: Hubert G. (hubertg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für welchen Kontroller wurde der Code denn ursprünglich geschrieben?
Wie sind die LCD- und sonstige Ausgabetexte gespeichert.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch wenn lokale Variable SRAM benötigen, sind da zunächst mal noch über 
2k frei. Da passt schon eine Menge rein.

Hast du große Arrays lokal angelegt? Nutzt du malloc, oder rekursive 
Funktionsaufrufe?

Wenn nicht, ist das sehr wahrscheinlich kein Speicherplatzproblem.

Oliver

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael M. schrieb:
> Leider läßt sich aus der Ausgabe von .data + .bss + .noinit der
> wirkliche SRAM-Bedarf zur Laufzeit nicht ermitteln. Denn zur Laufzeit
> kostet jede aufgerufene Funktion Platz auf dem Stack (lokale
> Variablen!). Am besten mal den wahren Speicherverbrauch zur Laufzeit
> bestimmen. Eine brauchbare Methode dazu findest Du hier:
> http://www.rn-wissen.de/index.php/Speicherverbrauc...

Danke für den Link !!

>
> Es kann natürlich leicht sein, daß Dein Code eigentlich mit dem SRAM
> auskommen müßte, Du aber irgendwo ein Speicherleck hast, z.B. schreiben
> über die Array-Grenzen hinaus. Das mußt Du natürlich ausschließen.

Yep, ist klar. Da der Code (bis auf eine neue Funktion, die das 
Speicher-Fass beim ATMega32 zum Überlaufen brachte) auf dem ATMega32 
läuft, habe ich bisher nicht in dieser Richtung gesucht....

> Servus
> Michael

Cheers
  Frank

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hubert G. schrieb:
> Für welchen Kontroller wurde der Code denn ursprünglich geschrieben?
> Wie sind die LCD- und sonstige Ausgabetexte gespeichert.

Für den ATMega32.

Als PSTRs. Überwiegend (zu ca. 90%). Mehr geht nicht - denn die 
restlichen Strings sind Format-Strings.

Gruß,
  Frank

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:
> Auch wenn lokale Variable SRAM benötigen, sind da zunächst mal noch über
> 2k frei. Da passt schon eine Menge rein.
>
> Hast du große Arrays lokal angelegt?

Nein.

> Nutzt du malloc,

Nein.

> oder rekursive Funktionsaufrufe?

Nein.

> Wenn nicht, ist das sehr wahrscheinlich kein Speicherplatzproblem.

Vermute ich inzwischen auch. Sieht nach UART Problem aus, weiss aber 
nicht wieso. Denn: DAS LIEF ALLES SCHON MAL AUF EINEM ATMEGA32 ... 
Schnief!

> Oliver

Frank

Autor: Hubert G. (hubertg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann würde ich das mal mit dem Code probieren der auf dem Mega32 lief, 
der hat nur halb so viel SRAM.
Wenn das läuft dann die neue Funktion einfügen. Dann hast du zumindest 
einen Anhaltspunkt zum suchen.

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hubert G. schrieb:
> Dann würde ich das mal mit dem Code probieren der auf dem Mega32 lief,
> der hat nur halb so viel SRAM.
> Wenn das läuft dann die neue Funktion einfügen. Dann hast du zumindest
> einen Anhaltspunkt zum suchen.

Jau. gelesen, getan. Alles läuft, bis auf UART. Sobald ich den UART (ich 
nutze die Lib von Peter Fleury) dazunehme, per Aufruf:

In darc.h:
#if !defined( DARC_BAUDRATE )
#define DARC_BAUDRATE                  38400 
#endif

In main():
...
darc_init( DARC_BAUDRATE ); // Enable communication link "DARC" using USART0
...
}

In darc.c:
rc_t darc_init( unsigned long nBaudrate )
{
  // Initialize UART of the controller board (uses Peter Fleury's
  // UART Library).

  uart_init( UART_BAUD_SELECT( nBaudrate, F_CPU ));

  // Set streams

  stdout = (FILE *) &darc_stdio;
  // stdin  = (FILE *) &darc_stdio;

  _darc_stream = (FILE *) &darc_stdio;
   
  // Init buffers
 
  darc_clear_receive_buffer();
  darc_clear_send_buffer();
    
  // Save init status
 
  bDARCIsInitialized  = TRUE;
  bDARCCommandAvailable = FALSE;
    
  // Done.

  return RC_OK;
}


uart_init() ist in Peter's Lib definiert als:

#if defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__)
 /* ATmega with two USART */
 #define ATMEGA_USART0
 #define ATMEGA_USART1
 #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
 #define UART1_RECEIVE_INTERRUPT   SIG_USART1_RECV
 #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
 #define UART1_TRANSMIT_INTERRUPT  SIG_USART1_DATA
 #define UART0_STATUS   UCSR0A
 #define UART0_CONTROL  UCSR0B
 #define UART0_DATA     UDR0
 #define UART0_UDRIE    UDRIE0
 #define UART1_STATUS   UCSR1A
 #define UART1_CONTROL  UCSR1B
 #define UART1_DATA     UDR1
 #define UART1_UDRIE    UDRIE1
#endif

/*************************************************************************
Function: uart_init()
Purpose:  initialize UART and set baudrate
Input:    baudrate using macro UART_BAUD_SELECT()
Returns:  none
**************************************************************************/
void uart_init(unsigned int baudrate)
{
    UART_TxHead = 0;
    UART_TxTail = 0;
    UART_RxHead = 0;
    UART_RxTail = 0;
    
#if defined( AT90_UART )
    /* set baud rate */
    UBRR = (unsigned char)baudrate; 

    /* enable UART receiver and transmmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);

#elif defined (ATMEGA_USART)
    /* Set baud rate */
    if ( baudrate & 0x8000 )
    {
       UART0_STATUS = (1<<U2X);  //Enable 2x speed 
       baudrate &= ~0x8000;
    }
    UBRRH = (unsigned char)(baudrate>>8);
    UBRRL = (unsigned char) baudrate;
   
    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
    
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
    #ifdef URSEL
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
    #else
    UCSRC = (3<<UCSZ0);
    #endif 
    
#elif defined (ATMEGA_USART0 )
    /* Set baud rate */
    if ( baudrate & 0x8000 ) 
    {
       UART0_STATUS = (1<<U2X0);  //Enable 2x speed 
       baudrate &= ~0x8000;
     }
    UBRR0H = (unsigned char)(baudrate>>8);
    UBRR0L = (unsigned char) baudrate;

    /* Enable USART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
    
    /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
    #ifdef URSEL0
    UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
    #else
    UCSR0C = (3<<UCSZ00);
    #endif 

#elif defined ( ATMEGA_UART )
    /* set baud rate */
    if ( baudrate & 0x8000 ) 
    {
      UART0_STATUS = (1<<U2X);  //Enable 2x speed 
      baudrate &= ~0x8000;
    }
    UBRRHI = (unsigned char)(baudrate>>8);
    UBRR   = (unsigned char) baudrate;

    /* Enable UART receiver and transmitter and receive complete interrupt */
    UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);

#endif

}/* uart_init */

Ich habe keine Hinweise in Sachen USART für die Portierung von ATMega32 
auf ATMega644P gefunden ...

Gruß,
  Frank

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich habe keine Hinweise in Sachen USART für die Portierung von ATMega32
>auf ATMega644P gefunden ...

Da gibt es schon Unterschiede, aber die lib handelt das (hoffentlich 
richtig).

Da hilft alles nichts, da ist jetzt intelligentes debugging angesagt.

Oliver

Autor: Frank Goenninger (dg1sbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver schrieb:

> Da hilft alles nichts, da ist jetzt intelligentes debugging angesagt.

;-) Yep - das ist wohl wahr. Und hält mich schon ein paar Stunden auf 
Trab...

Danke nochmals.

Grüße
  Frank

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.