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
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.
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
Ggast schrieb: > Vielleicht ist der Stack voll? Ja, so etwas vermute ich auch. Aber wie stelle ich das fest? Gruß Andreas
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).
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.
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
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.
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
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
@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
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.