Forum: Compiler & IDEs ATtiny2313, gcc. unerklärliches Verhalten


von Andreas B. (bitverdreher)


Angehängte Dateien:

Lesenswert?

Hallo,
nach langer Zeit komme ich mal wieder zum programmieren. Dies soll eine 
IR-Steuerung füer 4 LED stripes darstellen.
Ich habe das Problem, dass dieses Programm manchmal funktioniert und 
manchmal nicht.
Diese Programm funktioniert so (erst einmal einfaches dimmen nur für 
einen Kanal).
Kommentiere ich jedoch z.B. die Zeile 251 aus ( UsartPuts ("\n");) dann 
läuft das Programm nicht mehr.
Derlei Effekte habe ich hier die ganze Zeit schon, komme aber nicht 
darauf, woran das liegt. Sram sollte ja eigentlich reichen. (-> led.sym)
Irgendwie stehe ich momentan auf der Leitung...

Gruß
Andreas

von Christoph B. (christophbudelmann) Benutzerseite


Lesenswert?

Andreas B. schrieb:
> Sram sollte ja eigentlich reichen. (-> led.sym)
> Irgendwie stehe ich momentan auf der Leitung...

Ohne deinen Code im Detail angeschaut zu haben:

UsartPuts("Brown-Out Reset");

Packe diese ganzen Strings mal in den Flash. Die mehreren Zeilen 
Textausgabe aus dem RAM raus sind für den Attiny2313 eigentlich schon zu 
viel.

von Ggast (Gast)


Lesenswert?

Vielleicht ist der Stack voll?

von Andreas B. (bitverdreher)


Lesenswert?

Christoph Budelmann schrieb:
> Andreas B. schrieb:
>> Sram sollte ja eigentlich reichen. (-> led.sym)
>> Irgendwie stehe ich momentan auf der Leitung...
>
> Ohne deinen Code im Detail angeschaut zu haben:
>
> UsartPuts("Brown-Out Reset");
>
> Packe diese ganzen Strings mal in den Flash. Die mehreren Zeilen
> Textausgabe aus dem RAM raus sind für den Attiny2313 eigentlich schon zu
> viel.

Dieser String steht doch so im Flash oder täusche ich mich da? Wenn ich 
das weglasse, wird der flashverbrauch kleiner.

Gruß
Andreas

von Andreas B. (bitverdreher)


Lesenswert?

Ggast schrieb:
> Vielleicht ist der Stack voll?

Ja, so etwas vermute ich auch. Aber wie stelle ich das fest?

Gruß
Andreas

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


Lesenswert?

Andreas B. schrieb:
> Dieser String steht doch so im Flash oder täusche ich mich da?

Du täuschst dich.  Im Moment verbraucht er SRAM und Flash (letzteres
für die Initialisierungswerte des RAM).

von Roland H. (batchman)


Lesenswert?

Die Strings für usart_puts belegen schon ca. 70 Byte,
dazu kommen die "Pseudo lokalen" Variablen am Anfang von main(). Das 
sind nochmals mehr als 30 Byte - statisch belegt. Das ist für die 125 
Byte des 2313 zu viel.

-> konsequent PROGMEM für Strings
-> Die lokalen Variablen von main() global machen, dann siehst Du den 
statischen RAM-Verbrauch mit avr-size. Wobei dort nur die globalen 
Variablen gezählt werden, der Stack benötigt auch noch Platz.

von Andreas B. (bitverdreher)


Lesenswert?

Jörg Wunsch schrieb:
> Andreas B. schrieb:
>> Dieser String steht doch so im Flash oder täusche ich mich da?
>
> Du täuschst dich.  Im Moment verbraucht er SRAM und Flash (letzteres
> für die Initialisierungswerte des RAM).

OK, Danke! Gut zu wissen. Dann schiebe ich dies erst einmal ins Flash.

Gruß
Andreas

von Stefan K. (stefan1971)


Lesenswert?

Unerklärliches Verhalten hatte ich neulich, weil im AVR Studio unter 
(Project > Configuration Options > Memory Settings) der Haken bei (Stack 
Settings > Specify Initial Stack Address) gesetzt war.

Zum Verrücktwerden:
Kleinste Änderungen im Quellcode "schalteten" wirr zwischen 
"funktioniert fast wie's soll" und "Programm ist tot" hin und her.

von Andreas B. (bitverdreher)


Lesenswert?

Hallo,
nochmals Danke an die Helfer.
Nachdem ich mal alle Strings in den Flash verschoben habe, funktioniert 
alles.
Mein Denkfehelr war, dass die Konstanten im Programm dann nochmals in 
das RAM kopiert werden.
Warum das so ist, würde mich aber auch mal interessieren. Sinn macht das 
ja eigentlich nicht.

@Stefan K.
ich programmere mit gcc und Kate als Editor unter Linux. Was AVR Studio 
da macht, ist mir nicht so ganz klar. Überschreibt das die Werte, die 
durch die Librarys für den jeweiligen Prozessor vorgegeben werden?

Gruß
Andreas

von Andreas B. (bitverdreher)


Lesenswert?

Andreas B. schrieb:

> Mein Denkfehelr war, dass die Konstanten im Programm dann nochmals in
> das RAM kopiert werden.

kleine Korrektur:
 Mein Denkfehler war, dass ich nicht davon ausging, dass die Konstanten 
im Programm (=Flash) dann nochmals in das RAM kopiert werden.

Trotzdem würde mich mal interessieren, warum der Compiler das so macht. 
Das hat vermutlich mit der Havard Architektur des AVR zu tun.
Ich muß mich mal da bei Gelegenheit reinlesen.....

Gruß
Andreas

von Stefan K. (stefan1971)


Lesenswert?

@Andreas B:
Ja, über den genannten Dialog im AVRStudio kann man einen anderen Wert 
vorgegeben. Über die Library wird die Stackadresse ja normalerweise auf 
den Wert RAMEND (= RAMSTART + RAMSIZE - 1) gesetzt.

Grüße, Stefan

von Karl H. (kbuchegg)


Lesenswert?

Andreas B. schrieb:

> Mein Denkfehelr war, dass die Konstanten im Programm dann nochmals in
> das RAM kopiert werden.
> Warum das so ist, würde mich aber auch mal interessieren. Sinn macht das
> ja eigentlich nicht.

Weil eine Funktion wie UartPuts nicht wissen kann, ob du sie so benutzt

   UartPuts( "Hallo Welt 5" );

oder so

   char Buffer[20];

   sprintf( Buffer, "Hallo Welt %d", i );
   UartPuts( Buffer );

Daher schreibt man sich oft Spezialversionen und richtet sich Makros so 
ein, dass zb bei

  UartPuts_P( "Halle Welt 5" );

sowohl eine Spezialversion für UartPuts aufgerufen wird, die den String 
aus dem Flash holt und die gleichzeitig den String selber im Flash 
lässt.

von Andreas B. (bitverdreher)


Lesenswert?

das leuchtet mir insofern ein, als daß jeder string beim Aufruf von 
UartPuts vorher in das RAM kopiert werden muß.
Was mir aber nicht klar ist, warum alle strings, die im Programm 
verwendet werden (so verstehe ich die vorherigen Postings), im RAM 
vorliegen.

Gruß
Andreas

PS: sorry für die späte Antwort. Ich war diese Woche ziemlich busy.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andreas B. schrieb:
> Was mir aber nicht klar ist, warum alle strings, die im Programm
> verwendet werden (so verstehe ich die vorherigen Postings), im RAM
> vorliegen.

Nimm folgende Funktion:
1
void do_it (char *pc);
Wie sollte innerhalb dieser Funktion via pc zugegriffen werden? Per 
LD/ST oder per LPM?

Man weiß es nicht.

Alternativ wäre denkbar, in jedem Pointer mitzuführen, wo er hinzeigt 
und damit den Adressraum zu linearisieren. Wenn man aber über die 
Konsequenz bezüglich Laufzeit und erzeugtem Code nachdenkt, kommt man 
ganz schnell zu dem Schluss, daß man sowas nicht haben will. Und 
Laufzeitfehler abzufangen, weil ins Flash geschrieben wird, und diese zu 
behandeln, ist wesentlich unangenehmer als eine Warnung oder einen 
Fehler zur Compilerzeit zu bekommen und das zu richten.

Das Problem ist, daß Ablage und Zugriff immer zusammenpassen müssen, 
entweder über PROGMEM und entsprechende pgm_read_*-Makros, oder indem 
man einen Adress-Qualifier verwendet, wie er in einer 
Konzeptimplementierung von avr-gcc 4.7 verfügbar ist.

Daten werden in unterschiedlichen Sections abgelegt: 
Null-initialisierte Daten in .bss, initialisierte Daten in .data und 
read-only Daten in .rodata (ab avr-gcc 4.7) oder in .data (bis 
avr-gcc 4.6).

Aus den beschriebenen Gründen muss .rodata jedoch ebenfalls im RAM 
liegen, und erst durch ein Attribut wie progmem oder ein 
Adress-Qualifier wie __pgm werden Daten nach .progmem gelegt und landen 
damit im Flash.

von Andreas B. (bitverdreher)


Lesenswert?

Also stimmt meine Vermutung, daß das Problem durch die unterschiedlichen 
Adressräume entsteht (Havard Architektur).
Vielleicht sollte ich doch wieder mal in Assembler programmieren. Das 
letzte mal war es 20 Jahre her mit einem 6502 ;-)

Danke nochmal!

Gruß
Andreas

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.