ATtiny2313, gcc. unerklärliches Verhalten

OP #2373687
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
Angehängte Dateien:
Persönliche Seite #2373691
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.
OP #2373727
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
#2373746
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.
#2373911
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.
OP #2373966
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
OP #2374730
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
#2375294
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.
OP #2383259
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.
Persönliche Seite #2383479
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.

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