Hallo, ich habe gerade festgestellt, dass es mit dem Speicher zusammenhängen könnte, dass bei meinem Programm gerade gar nichts mehr ging. Und zwar wird bei meinem Display, das eigentlich wunderbar funktionierte, bei Hinzufügen von simplen Programmcode, der mit dem Display selber nichts zu tun hat, nur noch komische Zeichen raus. Ich benutze AVRStudio und bekomme beim Debuggen folgendes angezeigt: Program: 7612 bytes (46.5% Full) (.text + .data + .bootloader) Data: 764 bytes (74.6% Full) Die Grenze, bei der Mist rauskommt, liegt bei Data 70 %. Ich habe mal den Code, bei dem es beim ersten mal auftrat drinnen gelassen und dafür anderen ausgeklammert, und dann ging alles. Ich kann es mir nur erklären, dass der Speicher voll sein muss. Wieso aber fängt es schon bei 70% an nicht zu funktionieren? Bei 99% wäre es ja ok, wieso aber bei 70%?
In Data liegen nicht nur deine Variablen sondern dort ist (von oben nach unten belegend) der Stack angesiedelt. Je nach Verschachtelung und Interruptnutzung kommt da einiges zusammen. Oft sind (gerade bei Displayanwendungen) Konstanten (hier Festtexte) als Variablen definiert und belegen somit Platz im DATA. avr
Aha okay, na dass hier Variablen liegen wusste ich. Ich programmiere übrigens mit C, da ich mich mit dem inneren Aufbau eines µC (Speicherbelegung usw) nicht so gut auskenne. Also liege ich wohl richtig in der Annahme, dass der Speicher wahrscheinlich voll ist, obwohl 70% im data angezeigt wird?
> Also liege ich wohl richtig in der Annahme, dass der Speicher > wahrscheinlich voll ist, obwohl 70% im data angezeigt wird? Jein. 'voll' ja (genauer: ab da bemerkst Du den Überlauf), 'obwohl' nein (Stack braucht auch Platz, und der ist ebenso wie dynamisch angeforderter Speicher (malloc, new, ..) bei den 70% nicht erfasst). Mögliche Abhilfen: Daten in den Flash auslagern (genauer: nicht automatisch in den RAM einlesen lassen sondern nur manuell wenn sei benötigt werden), Speicherplatz sparen (Variablengröße, Rekursion, ..), oder eine größere Hardware anschaffen. Für ersteres gibts in der AVR-Libc <avr/pgmspace.h> [1], zweiteres ist eine Kunst und dritteres bleibt als letzte Option falls sonst nichts hilft. HTH [1] http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29
Jürgen Hems schrieb: > Aha okay, na dass hier Variablen liegen wusste ich. > Ich programmiere übrigens mit C, da ich mich mit dem inneren Aufbau > eines µC (Speicherbelegung usw) nicht so gut auskenne. > > Also liege ich wohl richtig in der Annahme, dass der Speicher > wahrscheinlich voll ist, obwohl 70% im data angezeigt wird? Ja. Der springende Punkt ist: Zur Laufzeit kommt da noch was dazu! Wenn Funktionen aufgerufen werden, muss irgendwo gespeichert werden, von wo sder Aufruf gekommen ist. -> braucht Platz im SRAM Wenn Funktionen lokale Variablen erzeugen, müssen die irgendwo hin -> braucht Platz im SRAM und so ist die Anzeige, wieviel Platz da noch übrig ist nur bedingt zu geniessen. Je nachdem wie das Programm konkret aussieht und wie es abgearbeitet wird, kann da zur Laufzeit noch etwas dazu kommen.
Ok vielen Dank für die Hilfe! Ich benötige vielleicht sowieso 2 UARTS, da steige ich vielleicht auf den ATmega64 um. Aber ich werde es erstmal mit dem Auslagern in den Flash probieren. Danke!
Dazu hätt ich noch ne frage: Was liegt denn alles im heap und was im stack? Ich mein, lokale variablen sind doch auch demmcompiler bekannt. Wo landen die? Naja ok, bei rekursiven aufrufen dann doch erst zur laufzeit :/ kann man grundsätzlich sagen, globale variablen und variablen der main sind bekannt und liegen auf dem heap? Wo kommt das malloc-zeugs hin? Sind so intressenfragen :) mfg
Karlo schrieb: > Dazu hätt ich noch ne frage: > Was liegt denn alles im heap und was im stack? > Ich mein, lokale variablen sind doch auch demmcompiler bekannt. Wo > landen die? Zuallererst mal: Ob Heap oder Stack ist einerlei. Alles muss im SRAM erzeugt werden. Das ist nun mal der einzige Speicher, der vorhanden ist, auf dem mit akzeptabler Geschwindigkeit wahlfrei gelesen und geschrieben werden kann. Der Stack wird benutzt um alles abzudecken, was das Programm zur Laufzeit benötigt um im Sinne von C abzulaufen. Der Heap ist Speicher, aus dem sich dein Programm durch Aufruf spezieller Funktionen (malloc, alloc, calloc) bedienen kann. > kann man grundsätzlich sagen, globale variablen und variablen der main > sind bekannt und liegen auf dem heap? Nein. gloable Variablen werden bei Beginn des Programms im SRAM erzeugt. Der SRAM ist eigentlich 3-geteilt +--------------------------+--------------------+--------------+ | alles was der Compiler | | | | zur Compiletime schon | Heap | Stack | | an Speicheranforderungen | | | | kennt | | | +--------------------------+--------------------+--------------+ | | +-------------------------- S R A M ---------------------------+ Heap und Stack wachsen zur Laufzeit aufeinander zu. Der Stack von oben nach unten (rechts nach links), der Heap genau anders rum. Alle globalen Variablen sind ja schon zur Compiletime bekannt und werden einfach an einem SRAM Ende gesammelt. Effektiv exisitieren sie einfach und der Speicher, der dann zur Laufzeit noch zur Verteilung da ist wird um diese Anzahl kleiner. Genau diese Anzahl (also das linke Feld) ist es, die dir AVR-Studio nach dem Build als Größe der Data Section angibt. > Wo kommt das malloc-zeugs hin? Heap
Jürgen Hems schrieb: > Ich benötige vielleicht sowieso 2 UARTS, da steige ich vielleicht auf > den ATmega64 um. Es gibt auch pinkompatible zum ATmega16 mit 2 UARTs: ATmega324: 2k SRAM ATmega644: 4k SRAM ATmega1284: 16k SRAM Peter
Hi >Es gibt auch pinkompatible zum ATmega16 mit 2 UARTs: >ATmega324: 2k SRAM >ATmega644: 4k SRAM >ATmega1284: 16k SRAM Zumindest beim ATMega644 ist Vorsicht geboten: ATMega644 : 1 UART ATMEGA644A/P/PA : 2 UART MfG Spess
spess53 schrieb: > Hi > >>Es gibt auch pinkompatible zum ATmega16 mit 2 UARTs: > >>ATmega324: 2k SRAM >>ATmega644: 4k SRAM >>ATmega1284: 16k SRAM > > Zumindest beim ATMega644 ist Vorsicht geboten: > > ATMega644 : 1 UART > ATMEGA644A/P/PA : 2 UART > > MfG Spess Hi! Ich habe mir gerade hier http://atmel.com/dyn/products/param_table.asp?family_id=607&OrderBy=part_no&Direction=ASC mal alle Typen verglichen, und übrig blieb wirklich nur der ATmega644 :-) Jetzt wollte ich hier fragen, ob man den einfach austauschen kann gegen den ATmega16. Aber die Antwort steht ja schon hier. Mit den zwei UARTs sollte kein Problem sein. Den UART, den ich jetzt beim ATmega16 verwende, da muss ich doch eifnach nur eine '0' mit hinzufügen. Für die Initialisierung also anstatt wie bisher:
1 | void init_USART(void) |
2 | {
|
3 | // Baudrate: 115200 Baud
|
4 | // CLK: 14.7456 MHz
|
5 | UCSRA = (1<<U2X); |
6 | UCSRB = (1<<TXEN) | (1<<RXEN); |
7 | UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0); |
8 | UBRRH = 0; |
9 | UBRRL = 15; |
10 | }
|
=>
1 | void init_USART(void) |
2 | {
|
3 | // Baudrate: 115200 Baud
|
4 | // CLK: 14.7456 MHz
|
5 | UCSR0A = (1<<U2X0); |
6 | UCSR0B = (1<<TXEN0) | (1<<RXEN0); |
7 | UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); |
8 | UBRRH0 = 0; |
9 | UBRRL0 = 15; |
10 | }
|
So in etwa müsste man dann generell das UART umändern. Aber ansonsten kann ich ihn wohl einfach austauschen ja?
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.