Langes Programm: Fehlfunktion AVR ATmega32

#1128432
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
Angehängte Dateien:
#1128501
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
#1129260
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
#1129383
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
#1129834
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
#1132027
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren