Forum: Mikrocontroller und Digitale Elektronik Array in AVR anlegen Array zu groß?


von David V. (vergossen)


Lesenswert?

Hallo zusammen!

Kann mir bitte jemand weiterhelfen bezüglich Arrays in AVR?
Ich programmieren einen ATMEGA128 mit 16MHZ getaktet.

Also ich habe mit AVR-Studio ein Array global definiert:
uint16_t volatile(ErgebnisMatrix[2000][2]);

Im weiteren Programmverlauf wird dieses mit den entsprechenden Werten 
gefüllt und über USART ausgegeben.
Das klappt auch ganz gut, sofern ich eine 200 als Zeilenanzahl 
hinschreibe uint16_t volatile(ErgebnisMatrix[200][2]).
Schreibe ich jedoch uint16_t volatile(ErgebnisMatrix[2000][2]) klappt es 
nicht mehr. Das programm hakt dann an dieser stelle.

Was ich mich nun frage:
1. Wo wird eigentlich so ein Array hingeschrieben ? Der ATMEGA hat doch, 
wenn ich mich richtig entsinne, was ein guter Freund und kollege mir 
erklärte und was auch im datenblatt steht einen SRAM-Speicher mit 4KB 
zur schnellen datenauslagerung, einen EEPROM als Dauerspeicher für daten 
und einen Wiederprogrammierbaren Flashspeicher mit 128KB, wo der 
Programmcode drin steht.

In welchen dieser Speicher legt der Compiler denn das Array ab? Und wie 
groß darf es überhaupt sein und wie kann man feststellen, wo es genau 
liegt? Den Debugger kann ich noch nicht bedienen.

Um hilfreiche Tipps wäre ich sehr dankbar.

Viele Grüße,

David

von Matthias (Gast)


Lesenswert?

Es liegt auf dem Stack. Der ist im SRAM.
Und falls du nachrechnest wirst du merken, dass 2000*2*2 eindeutig 
größer als 4096 ist.

von Matthias (Gast)


Lesenswert?

Korrektur: Stack war falsch, da die Variable ja global ist. Im SRAM 
liegt sie aber trotzdem.

von Εrnst B. (ernst)


Lesenswert?

Wenn du nix dazuschreibst, landet das Array im SRAM.
Mit den Keywords PROGMEM und EEMEM liesse sich das Array auch in den 
FLASH/EEPROM-Speicher verlagern.

Dein Array ist 2000*2*2==8000 Bytes groß, das passt nicht mehr in den 
SRAM
(2000 "Zeilen", 2 "Spalten", 2 Bytes pro uint16_t)

/Ernst

von David V. (vergossen)


Lesenswert?

Hallo Ernst!

Danke für die Erklärung.
Dann ist es wohl am besten, wenn ich den internen flashmemory benutze, 
weil der ja 128kB groß ist. Der SRAM und der EEPROM-Speicher sind ja 
beide nur 4kB groß und somit für meine 8kB zu klein.

Kannst du mir eine Beispielzeile machen, wie ich die Schlüsselwörter 
PROGMEM und EEMEM zu verwenden habe?

Viele Grüße,

David

von Hannes L. (hannes)


Lesenswert?

David V. wrote:
> Hallo Ernst!
>
> Danke für die Erklärung.
> Dann ist es wohl am besten, wenn ich den internen flashmemory benutze,
> weil der ja 128kB groß ist.

Du solltest Dich mal etwas mehr mit der Hardware vertraut machen 
(Datenblatt). Der Flash-Speicher ist für Programmcode und Konstanten 
geeignet, nicht aber für Variablen. Der Schreibzugriff auf Flash erfolgt 
nur vom Programmiergerät oder aus der Bootloader-Sektion.

> Der SRAM und der EEPROM-Speicher sind ja
> beide nur 4kB groß und somit für meine 8kB zu klein.

Wenn Du wirklich ein solch großes Variablen-Array brauchst, dann hast Du 
Dir mit dem Mega128 den falschen MC ausgesucht.

>
> Kannst du mir eine Beispielzeile machen, wie ich die Schlüsselwörter
> PROGMEM und EEMEM zu verwenden habe?

Ich könnte es Dir höchstens in ASM erklären, vermute aber, dass es Dir 
nicht helfen wird, also schade um die Zeit ist.

>
> Viele Grüße,
>
> David

...

von Hannes L. (hannes)


Lesenswert?

Nachtrag:
Es gibt die Möglichkeit, externes SRAM an den Mega128 anzuschließen. 
Dies blockiert aber mindestens 19 Portpins. Bei http://www.alvidi.de/ 
gibt's gelegentlich fertige Modulplatinen mit Mega128, 128 kiB SRAM 
(Incl. Latch), 2 UART und Anschlüssen für ISP und JTAG. Und das zu einem 
fairen Preis.

...

von David V. (vergossen)


Lesenswert?

Ernst Bachmann wrote:
> Wenn du nix dazuschreibst, landet das Array im SRAM.
> Mit den Keywords PROGMEM und EEMEM liesse sich das Array auch in den
> FLASH/EEPROM-Speicher verlagern.

JA und wie das genau funktioniert wüsste ich gern. Demnach funktioniert 
das also doch, dass man Dinge in den Flash verschieben kann. Hannes 
meinte ja das würde nicht funktionieren. Mir ist auch klar, dass der 
Flash eigentlich nur über ein Programmiergerät oder aus der 
Bootloader-Sektion les- und beschreibbar ist. Aber ich habe dich Ernst 
so verstanden alsob mal in Ausnahmefällen auch den Flash zum Auslagern 
von Daten missbrauchen kann.

KAnnst du mir mal eine Beispielzeile geben, wie man das macht mit dem 
Verschieben in den Flash?

> Dein Array ist 2000*2*2==8000 Bytes groß, das passt nicht mehr in den
> SRAM
> (2000 "Zeilen", 2 "Spalten", 2 Bytes pro uint16_t)
>
> /Ernst
Das sehe ich ein.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Du kannst den FLASH nur für KONSTANTE Daten "mißbrauchen" (wobei ich 
finde, dass das kein mißbrauch ist!)

von Ralph (Gast)


Lesenswert?

Denk erstmal darüber nach, ob du wirklich 8000 Byte Datenarray 
benötigst.
Und falls das wirklich der Fall ist, dann such dir einen µC mit minimum 
12 K RAM, alles andere ist verschwendete Zeit, Arbeit und es wird nur 
mit gewaltigem Aufwand etwas (eventuell) sinnvolles rauskommen.

Grundsätzlich gilt:
1. festlegen WAS der µC machen soll
2. festlegen WIE der µC (1) erfüllen soll
3. aus (1) und (2) bestimmen was der µC an Ram, Rom, Takt, Ports,...... 
benötigt
4. den passenden µC aussuchen


Wer mit (4)anfängt wird sich fast jedesmal große Probleme einhandeln.

von Falk B. (falk)


Lesenswert?

@ David V. (vergossen)

>JA und wie das genau funktioniert wüsste ich gern. Demnach funktioniert

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29

>das also doch, dass man Dinge in den Flash verschieben kann. Hannes

Man kann sie dort ablegen.

>meinte ja das würde nicht funktionieren. Mir ist auch klar, dass der
>Flash eigentlich nur über ein Programmiergerät oder aus der
>Bootloader-Sektion les- und beschreibbar ist. Aber ich habe dich Ernst
>so verstanden alsob mal in Ausnahmefällen auch den Flash zum Auslagern
>von Daten missbrauchen kann.

Man kann KONSTANTE Daten im FLASH speichern. Die sind dann nur lesbar, 
nicht beschreibbar.

MfG
Falk

von Hannes L. (hannes)


Lesenswert?

Ich möchte mal an den ersten Beitrag erinnern. Die Aussage

> Im weiteren Programmverlauf wird dieses mit den entsprechenden Werten
> gefüllt und über USART ausgegeben.

suggeriert mir, dass das Array keine Konstanten (die zur Entwurfszeit 
bereits im Wert feststehen) aufnehmen soll, sondern Variablen (deren 
Werte erst zur Laufzeit bekannt werden). Darauf bezog sich mein "Geht 
nicht".

Klar muss erstmal geprüft werden, ab wirklich so viele (veränderliche) 
Daten gespeichert werden müssen, oder ob nicht ein Teil der zu 
versendeten Daten als Konstanten gehandhabt werden können.

Sind die vielen (variablen) Daten wirklich nötig, dann muss ein 
Controller mit mehr RAM her, z.B. das oben genannte Modul mit Mega128 
und 128 kiB SRAM. Will man das nicht, muss man die Aufgabestellung so 
abändern, dass der tatsächlich vorhandene RAM reicht.

...

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.