Forum: Compiler & IDEs Langes Programm: Fehlfunktion AVR ATmega32


von Frank G. (dg1sbg)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

mein kleines programm für meinen ATmega32 wurde nun doch etwas größer 
(siehe Datei anbei). Nach überschreiten einer für mich nicht fassbaren 
Größe, so scheint es, will das Ding nicht mehr. Soll heissen: Ich seh 
z.B. noch, dass das LCD initialisiert wird (clear screen), aber eine 
Ausgabe erfolgt schon nicht mehr...

Teste ich kleine Teile des Programms für sich, so funktionieren die 
einzelnen Teile wie gewünscht.

Ich habe einiges an Definitionen und Variablen-Vorbelegungen in der 
Datei controller.c ... Ich sehe allerdings in der Ausgabedatei 
psuctrl.lst nicht, welche Grenze ich überschritten hätte...

Umgebung hier: AVR-GCC 4.3.2, AVR libc 1.6.4, ATmega32 mit 8 MHz

Danke für Hinweise !!!!

Viele Grüße
   Frank

von egberto (Gast)


Lesenswert?

ohne überhaupt reingeschaut zu haben...klingt nach Pufferüberlauf(der 
sich erst ab einer gewissen Größe auswirkt) oder nach Stack Problem..

Viele Erfolg beim Suchen

egberto

von UBoot-Stocki (Gast)


Lesenswert?

Hi,

oder aber wie bei meinem Projekt, dass "der RAM" einfach voll ist. Du 
könntest jetzt tunen oder aber einfach auf einen Mega32 umsteigen ...

Gruß

Andreas

von UBoot-Stocki (Gast)


Lesenswert?

Ups - Mega644 meinte ich ...

von Stefan E. (sternst)


Lesenswert?

section             size
.text              19748
.data               1376
.bss                1387

Du benutzt mehr RAM, als du eigentlich hast.
Ein kurzer Blick in den Sourcecode offenbart jede Menge Strings, die 
unnötigerweise im RAM liegen.

von UBoot-Stocki (Gast)


Lesenswert?

Hi,

ein Beispiel für Strings im RAM:

Beitrag "Komfortable Rolladensteuerung V1.0"

Gruß

Andreas

von Frank G. (dg1sbg)


Lesenswert?

Hallo zusammen,

vielen Dank (!!!) für Eure Antworten - mal wieder klasse, was man hier 
an Support bekommt.

Aber:

Stefan Ernst wrote:
> section             size
> .text              19748
> .data               1376
> .bss                1387
>
> Du benutzt mehr RAM, als du eigentlich hast.

Hmm -

SRAM = .bss = 1387 bytes, und damit < 2 kb und damit i.O.
RAM  = .text + .data = 21124 bytes, und damit < 32 kb (ATmega32) und 
damit i.O.
?? Wo liegt denn mein Denk-/Rechenfehler ?

> Ein kurzer Blick in den Sourcecode offenbart jede Menge Strings, die
> unnötigerweise im RAM liegen.

Ok. Also alles PSTRs ...

Danke!! - Zurück zum Coding ...

Gruß,
   Frank

von Stefan E. (sternst)


Lesenswert?

Frank Goenninger wrote:

> SRAM = .bss = 1387 bytes, und damit < 2 kb und damit i.O.

SRAM = .bss + .data (+ Heap) + Stack

von Peter D. (peda)


Lesenswert?

Stefan Ernst wrote:
> .bss                1387

Also da ist noch reichlich Luft bis 2048 Byte, am SRAM kanns also nicht 
liegen.
Da müßte man schon richtige Schweinereien machen (Rekursive Funktionen), 
damit der Stack überquillt.

Du solltest vielleicht Dein Programm strukturieren (in kleinere 
zusammengehörende Objekte unterteilen) und kommentieren, dann kann man 
mal weiter sehen.
Es fehlen außerdem noch 2 Files, um es mal compilieren zu können.

Es ist zwar löblich, atomare Zugriffe zu beachten, aber Du scheinst es 
mir zu übertreiben.
Fast alles ist ja atomar, ich bin mir daher nicht sicher, ob dann auch 
die Interrupts oft genug zum Zuge kommen.

Vielleicht solltest Du die Interrupts etwas verschlanken und nicht allen 
Tod und Teufel darin machen (Du machst da was mit Funktionspointern 
rum).

Das Main würde bestimmt auch gerne einiges machen und darin hat man dann 
ne klare Ausführungsfolge (nichts unterbricht sich selber).
Das erleichtert auch das Verstehen ungemein.


Da Du viel mit I2C rummachst, würde ich nen I2C-Interrupt aufsetzen, der 
im Hintergrund die I2C-Sachen (PCF8574?) macht. Dazu legst Du quasi 
IO-Ports im SRAM an und der Interrupt updated die zyklisch.
D.h. alle Statemachines arbeiten direkt auf diesem Pseudo-IO SRAM.

Ich benutze diese Technik mit SPI IO-Erweiterungen (74HC165, 74HC595), 
dadurch wird das Programm sehr übersichtlich und klein (keine tausend 
Funktionsaufrufe, sondern direkte Variablenzugriffe).
Der AVG-GCC kann ja komfortabel Bitvariablen definieren.


Peter

von Stefan E. (sternst)


Lesenswert?

Peter Dannegger wrote:
>> .bss                1387
>
> Also da ist noch reichlich Luft bis 2048 Byte, am SRAM kanns also nicht
> liegen.

Du vergisst das .data-Segment. Das kommt noch dazu.

von Peter D. (peda)


Lesenswert?

Stefan Ernst wrote:
> Du vergisst das .data-Segment. Das kommt noch dazu.

Stimmt, hast recht.
Woher hast Du diese Angaben?

Ich laß mir das mit AVR-Size ausgeben, aber ich konnte es nicht 
compilieren (libgaul.a, gaul.h fehlt).

Die Konstanten hat er aber hübsch im Code versteckt, sah garnicht soviel 
aus.


Peter

von Stefan E. (sternst)


Lesenswert?

Ich habe das im Archiv vorhandene elf-File genommen.

von Frank G. (dg1sbg)


Lesenswert?

Peter Dannegger wrote:

> Du solltest vielleicht Dein Programm strukturieren (in kleinere
> zusammengehörende Objekte unterteilen) und kommentieren, dann kann man
> mal weiter sehen.

Ok. Kritik angekommen. ;-)

> Es ist zwar löblich, atomare Zugriffe zu beachten, aber Du scheinst es
> mir zu übertreiben.
> Fast alles ist ja atomar, ich bin mir daher nicht sicher, ob dann auch
> die Interrupts oft genug zum Zuge kommen.

> Vielleicht solltest Du die Interrupts etwas verschlanken und nicht allen
> Tod und Teufel darin machen (Du machst da was mit Funktionspointern
> rum).

Huch! Danke für den Rat, aber ich muss sagen, dass ich nicht den 
Eindruck hatte, dass da so viel drin passiert.

> Das Main würde bestimmt auch gerne einiges machen und darin hat man dann
> ne klare Ausführungsfolge (nichts unterbricht sich selber).
> Das erleichtert auch das Verstehen ungemein.

Mein MAIN macht die Hauptarbeit: Die Statusmaschinerie, die das ganze 
treibt. Aber ich bin nun dabei, noch mehr in MAIN zu verlagern.

> Da Du viel mit I2C rummachst, würde ich nen I2C-Interrupt aufsetzen, der
> im Hintergrund die I2C-Sachen (PCF8574?) macht. Dazu legst Du quasi
> IO-Ports im SRAM an und der Interrupt updated die zyklisch.
> D.h. alle Statemachines arbeiten direkt auf diesem Pseudo-IO SRAM.

Wäre schön, das machen zu können. Hardware ist aber vorgebenen, und ich 
muss damit leben (das Mini-Mega-Board aus Elektor). Trotzdem: Kann die 
Idee verwenden und werde alle I/Os auf Bits legen, die dann per Timer 
Interrupt an die Komponenten ausgegeben werden.

> Peter

Vielen Dank für die Hinweise !

Gruß,
  Frank

von Frank G. (dg1sbg)


Lesenswert?

So .... Nach Restrukturierung und neuem Ansatz zur I2C Nutzung über 
"Ports gespiegelt im SRAM" habe ich nun folgende Größen:
1
psuctrl.elf :
2
section                      size         addr
3
.text                      17232              0
4
.data                         316   8388704
5
.bss                         1432   8389020
6
....
7
Total                      89128

Funzen tut's aber immer noch nicht.... Sollte aber nun reichen, oder? 
Ich habe kein malloc o.ä. verwendet.

Ich habe folgendes Idiom verwendet:
1
   printf( strcpy_P( (char *) &acBuffer[0], PSTR( "Hello !" )));

Ist dies so ok ?

Soll ich den Source nochmals posten?

Danke für weitere Hilfe...

Frank

von Frank G. (dg1sbg)


Lesenswert?

Melde Vollzug. Musste noch weiter .bss reduzieren. Nun funkts wieder.
Das tut ja soooo gut - nach einer Woche debuggen und einem "Major 
Rewrite" ... ;-)

Viele Grüße

   Frank

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


Lesenswert?

Frank Goenninger wrote:

> Ich habe folgendes Idiom verwendet:
>
>
1
>    printf( strcpy_P( (char *) &acBuffer[0], PSTR( "Hello !" )));
2
>

Häh!?

Vielleicht beschreibst du ja mal, was du tun willst...

Du suchst nicht etwa einfach nur
1
printf_P(PSTR("Hello!"));

oder?

von Frank G. (dg1sbg)


Lesenswert?

Jörg Wunsch wrote:
> Frank Goenninger wrote:
>
>> Ich habe folgendes Idiom verwendet:
>>
>>
1
>>    printf( strcpy_P( (char *) &acBuffer[0], PSTR( "Hello !" )));
2
>>
>
> Häh!?

;-) Hallo Jörg!
>
> Vielleicht beschreibst du ja mal, was du tun willst...
>
> Du suchst nicht etwa einfach nur
>
>
1
> printf_P(PSTR("Hello!"));
2
>
>
> oder?

Nein. Ich wollte sichergehen, dass es keine elegantere Lösung gibt, um 
einen im PROGMEM befindlichen String in einen temporären Buffer zu 
kopieren und den Zeiger auf den Buffer an eine Funktion zu übergeben.

Aber printf_P hatte ich auch noch nicht genutzt. Danke für den Hinweis 
...

73, Frank DG1SBG

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.