Forum: Compiler & IDEs Nur 8 KB in Atmega32 und nicht 32 KB


von Timo (Gast)


Lesenswert?

Hallo,
ich habe ein Problem mit einem Atmega32.
Obwohl auf diesen Mikrocontroller 32 KB Programmspeicher passen sollte, 
funktioniert meine Software nur bis zu folgender Größe der ELF Datei:

Größe: 7,95 KB (8.149 Bytes)
Größe auf Datenträger: 7,95 KB (8.149 Bytes)

Ich habe ein (unschönes) Beispielprogramm geschrieben. Es soll einfach 
dazu dienen 8 KB Programmgröße zu erreichen:


#define _AVR_ATmega32_

#include<avr/io.h>

#define F_OSC 8000000            /* oscillator-frequency in Hz */
#define UART_BAUD_RATE 9600
//#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) 
((F_OSC)/((UART_BAUD_RATE)*16l)-1)
#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC + 
(UART_BAUD_RATE)*8l) /((UART_BAUD_RATE)*16l)-1)
//Define für delay.h
# define F_CPU 8000000UL

#include<util/delay.h>
#include<functions.c> // Hauptsächlich Uartfunktionen
//#include<spi.h>
//#include<spi.c>
void uart_auswertung(char c);
void init_all(void);
int main(void);

void sleep(void)
{
 _delay_loop_2(1); //1 ms delay
 _delay_loop_2(1); //1 ms delay
 //_delay_loop_2(1) wird innerhalb dieser Funktion ca. 470 mal 
aufgerufen!
 ...
 ...
}

void uart_ausgabe(char c)
{
  uart_putc('E');delay();uart_putc('R');delay();uart_putc('R');delay();
  uart_putc('O');delay();uart_putc('R');delay();
}

void init_all(void)
{
  uart_init(); // UART initialisieren
}
int main(void)
{
  init_all();
  char temp_c;
  /*
  Entlosschleife; Warten auf UART-Empfang:
  */
  for(;;)
  {
    temp_c = uart_getc_wait();
    uart_auswertung(temp_c);
  }
}

Ich kontrolliere die Funktionalität des Programmes über eine einfache 
UART<->RS232 kommunikation.

Leider muss ich zugeben kein Makefile zu verwenden und nötige 
Anweisungen dem Compiler (avr-gcc.exe) als Parameter zu übergeben.

..\avr-gcc.exe" groesser.c -Os -o groesser.bin

Ich benutze Ponyprog2000 V207A(Atmega32 ist eingestellt)

Über Tips oder Ideen würde ich mich sehr freuen!

Gruß Timo

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Timo wrote:

> #define __AVR_ATmega32__

Schon in der ersten Zeile falsch.

Einen derartigen Makro darfst du nicht definieren, es sei denn, die
Dokumentation würde dich ausdrücklich dazu auffordern, das zu tun (wie
z. B. bei __STDIO_FDEVOPEN_COMPAT_12).

Dass du ihn definiert hast, lässt mich vermuten, dass du sowohl beim
Compilieren als auch beim Linken die Option -mmcu=atmega32 vergessen
hast.  Damit baust du (aus hysterischen Kompatibilitätsgründen) Code
für einen AT90S8515.  Das sollte dir dann auch erklären, warum das
Ergebnis auf 8 KiB Größe limitiert ist, aber da hängen noch mehr
Pferdefüße dran, wie z. B. einen falsche Interruptvektortabelle.

von Timo (Gast)


Lesenswert?

Ist mmcu=atmega32 vorhanden wie z.B.:

..\avr-gcc.exe" groesser.c -mmcu=atmega32 -Os -o groesser.bin

läst sich die Software nicht starten(keine RS232-Kommunikation)

Welche Definitionen/Einstellungen müsste ich sonst noch vornehmen?

von Karl H. (kbuchegg)


Lesenswert?

Timo wrote:
> Ist mmcu=atmega32 vorhanden wie z.B.:
>
> ..\avr-gcc.exe" groesser.c -mmcu=atmega32 -Os -o groesser.bin
>
> läst sich die Software nicht starten(keine RS232-Kommunikation)
>
> Welche Definitionen/Einstellungen müsste ich sonst noch vornehmen?

Wenn UART Kommunikation nicht stimmt, dann hat das in praktisch
100% aller Fälle folgende Ursachen
* Quarzfrequenz stimmt nicht
* Quarzfrequenz stimmt nicht
* interner Oszi wird benutzt anstatt externem Quarz
* Quarzfrequenz stimmt nicht
* Umrechnungsformel ist fehlerhaft

In diesem Licht: Was'n das
1
#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC + (UART_BAUD_RATE)*8l) /((UART_BAUD_RATE)*16l)-1)
für eine Berechnung?

von Rolf Magnus (Gast)


Lesenswert?

> //_delay_loop_2(1) wird innerhalb dieser Funktion ca. 470 mal

Du hast eine Funktion geschrieben, in der du 470 mal hintereinander 
_delay_loop_2 so aufrufst, daß es eine Warteschleife mit jeweils einem 
einzelnen Durchgang ausführt? Wozu das?

von Henning S. (xtsi)


Lesenswert?

> Du hast eine Funktion geschrieben, in der du 470 mal hintereinander
> _delay_loop_2 so aufrufst, daß es eine Warteschleife mit jeweils einem
> einzelnen Durchgang ausführt? Wozu das?

Hat er doch geschrieben:

> Ich habe ein (unschönes) Beispielprogramm geschrieben. Es soll einfach
> dazu dienen 8 KB Programmgröße zu erreichen:
>

Einfach Platz verbraten...

von Karl H. (kbuchegg)


Lesenswert?

Rolf Magnus wrote:
>> //_delay_loop_2(1) wird innerhalb dieser Funktion ca. 470 mal
>
> Du hast eine Funktion geschrieben, in der du 470 mal hintereinander
> _delay_loop_2 so aufrufst, daß es eine Warteschleife mit jeweils einem
> einzelnen Durchgang ausführt? Wozu das?


Sagte er doch:
Um das Flash zu Testzwecken voll zu kriegen.

von Timo (Gast)


Lesenswert?

Ich habe eine Software welche über 8 KB groß wird.
Ich rufe über 400 mal die gleiche Funktion auf um auf 8 KB Programmgröße 
zu kommen.
Programmiere ich den Atmega32 mit <8 KB läuft die Kommunikation über 
RS232 fehlerfrei.

Erst ab einer Programmgröße von >= 8 KB (nur hinzufügen von z.B. 
vielen,vielen Sleep-Funktionen läuft die Software nicht mehr.

Nur dies ist mein Problem. Mit den RS232-Einstellungen ist alles ok.

von Εrnst B. (ernst)


Lesenswert?

Also, Timo,
Hast du jetzt schonmal ausprobiert, dem Compiler auch mitzuteilen, 
welchen µC du hast?

> #define __AVR_ATmega32__
Rauslöschen

und beim Compiler/Linker Aufruf -mmcu=atmega32 angegeben?

Wenn du das nicht machst, funktioniert deine UART-Kommunikation bis zu 
einer Programgröße von 8KB und darüber hinaus nicht mehr :).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Timo wrote:

> Ist mmcu=atmega32 vorhanden wie z.B.:
>
> ..\avr-gcc.exe" groesser.c -mmcu=atmega32 -Os -o groesser.bin
>
> läst sich die Software nicht starten(keine RS232-Kommunikation)

Ach, und deine ,,Abhilfe'' ist es, -mmcu=atmega32 dann wegzulassen?

"Meine Öldruckkontrollampe leuchtet, was soll ich tun?"

"Die Lampe ausbauen."

Ungefähr so kommst du mir vor...

Du wirst nicht drumherum kommen, deine reale Applikation zu
debuggen.  Stichworte: Oszilloskop (für die RS-232-Leitung),
JTAG (ein einfacher Clone genügt für den ATmega32, aber ein
AVR Dragon würde es auch tun), ...  Genau das, an dem ein
Mikrocontroller halt beginnt, Arbeit zu werden.

Ach, wart' mal...  Was ist "groesser.bin" in obigem Kommando?
Da sollte "groesser.o" stehen.

Mir schwant was... versuchst du etwa, den verschieblichen Objektcode
ohne zu Linken zu benutzen?

von Timo (Gast)


Lesenswert?

Arbeitsschritte:
1.: Über PN avr-gcc.exe -bla -bla ... starten
2.: PonyProg öffnen und Atmega beschreiben

3.: Ich linke wohl nichts s.o. ein Tip wäre hilfreicher als sich über 
meine Versuche lustig zu machen -> DANKE!

Starte ich mit avr.gcc mit: ../avr-gcc.exe -mmcu=atmega32 -groesser.c 
-Os - groesser.o
Läuft die Software nicht.

benutze ich -mmcu=atmega32 nicht und definiere den Mikrocontroller in 
der Software, läuft die UART(allerdings nur bis 8 kB)

Hat jemand einen möglichst einfachen Tip?

von MNR (Gast)


Lesenswert?

>Hat jemand einen möglichst einfachen Tip?

Makefile benutzen.

von Peter S. (psavr)


Lesenswert?

>Hat jemand einen möglichst einfachen Tip?

Ja: Verwende AvrStudio zusammen mit WinAVR! AvrStudio generiert das 
Makefile automatisch, wenn auch nicht immer ein mustergültiges Makefile, 
aber für den Anfang tut es alleweil.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Man kann das Makefile auch über Mfile generieren lassen, das sollte
prima zu PN2 passen.

Ich mache mich nicht lustig, sondern schüttele nur den Kopf.
Trial&error war noch nie 'ne gute Methode.  Es ist erstaunlich,
dass du überhaupt so weit gekommen bist.

Mit der Hand, ohne Makefile:
1
avr-gcc -mmcu=atmega32 -g -Os -c groesser.c
2
avr-gcc -mmcu=atmega32 -o groesser.elf groesser.o -lm
3
avr-objcopy -O ihex -j .text -j .data groesser.elf groesser.hex

Leider hast du nur Fragmente zitiert und einiges weggelassen,
offenbar bekommst du ja ein Hexfile irgendwoher -- daher kann
ich nur meine Kristallkugel fragen, was du weggelassen hast und
was du wirklich nicht machst.  Da ist es schwer, gute Ratschläge
zu geben.

Wenn avr-gcc über WinAVR installiert ist, sollte es sich ordentlich
im ${PATH} befinden, und man muss es nicht mit ../ aufrufen.

von ydear (Gast)


Lesenswert?

Er linkt schon, er ruft gcc nicht mit der Option -c auf, dann compilt 
und linkt gcc automatisch nacheinander.

Soweit ich (auch Anfänger) das beurteilen kann, vergisst du "nur" 
mmcu=µCTYP. Damit gcc dieses auch an den Linker weiterleitet muss zudem 
-Wa (oder war es -Wl? sry, weiss es nicht mehr genau, ich compile und 
linke auch getrennt in meinem makefile) angegeben werden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

ydear wrote:

> Er linkt schon, er ruft gcc nicht mit der Option -c auf, dann compilt
> und linkt gcc automatisch nacheinander.

Ja, stimmt.  Das erklärt zumindest, warum es einigermaßen gegangen
ist.

> Soweit ich (auch Anfänger) das beurteilen kann, vergisst du "nur"
> mmcu=µCTYP. Damit gcc dieses auch an den Linker weiterleitet muss zudem
> -Wa (oder war es -Wl?

-Wl, aber das ist nicht nötig.  Wenn man dem Compiler einmal -mmcu
mitgibt, weiß er dann, was er dem Linker sagen muss.

von Timo (Gast)


Lesenswert?

Ich habe mich in das Thema Makefile eingearbeitet und die Software läuft 
jetzt ohne probleme.
War doch alles viel einfacher als ich dachte.

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.