ich habe es nun geschafft, vom 8-Bit auf einen 32-Bit Controller, den rp2040 zu wechseln. Leider ist der Umstieg nicht ganz einfach für mich, da mir einiges noch nicht ganz klar ist.
Beim ATMEL Arduino habe ich, um Speicherplatz (RAM) zu sparen Arrays ab einer Größe gerne mit PROGMEM definiert und über einen Pointer wieder zurück ins RAM geladen. Beim rp2040 ist ja mit den 264kB über das 32-Fache des RAM Speichers vorhanden als beim Mega2560.
Wie wird z.B. ein Array mit: uint8_t test[50];
abgelegt? Werden hierfür 50 * 32-Bit = 200 Byte RAM benötigt, oder kann der Speicher trotz der 32 Bit Architektur in 1 Byte Schritten gelesen werden?
In der Beschreibung des rp2040 steht: >> 2.6.2. SRAM ...There are no restrictions on what is stored in each bank: processor code, data buffers, or a mixture.<< Gilt das auch für den FLASH Speicher? Hier ist zu lesen, das sich das Externe FLASH über die Schnittstelle wie ein Interner Speicher verhält. Was macht der Compiler daraus?
Ist es bei diesen Rechnern noch notwendig, den Umweg über PROGMEM zu gehen oder langt das, einfach ein const uint8_t test[50] = {1,2,3,4,...
zu definieren. Durch das const liegt das Array halt im Flash, anstatt im SRAM und wird auch daraus gelesen.
In diesem Zusammenhang ist wahrscheinlich auch das F Makro bei
Serial.print(F("xxx");
nicht mehr notwendig, oder?
Sind alle die 32-Bit Controller alle ähnlich aufgebaut, oder muss ich hier z.b. bei einem weiteren Umstieg von rp2040 auf Arduino DUE oder die MKR Serie wieder alles überdenken???
Fragen über Fragen. Vielleicht kann mir jemand die eine oder andere beantworten.
Gibt 10,20,und 40 aus.
Das ist die Anzahl der belegten RAM Bytes. Es werden doch aber beim 32 Bit System auch immer 4 Byte gleichzeitig aus dem RAM/FLASH gelesen. Ich wollte wissen, ob da zwischen drin beim uint_8 immer 3 Füllbytes eingebaut werden müssen oder ob der ganze Speicher sich in 1 Byte Schritten auslesen lässt.
Ob er einen Unterschied macht, ob aus dem FLASH oder aus dem RAM gelesen werden muß. Beim AVR Arduino ist das lesen aus dem FLASH anders aufgebaut. Ist das bei den Systemen ähnlich?
In der Datei: pgmspace.h
steht nur: #define PROGMEM
Besten Dank für die Erklärung - ich denke ich habe es verstanden. Das ganze mit dem PROGMEM ist wirklich nur bei den AVR's erforderlch, da bei diesen der FLASH in einem anderen Speicher Segment liegt.
In der rp2040 Definition ist das dann nur noch eine Definition, um ältere Programme nicht in einen Fehler laufen zu lassen. So weit habe ich dann auch nicht gedacht...
Ich gehe jetzt davon aus, das die Definition der Varialbe test
Tipp:
Bevor du deiner Fantasie freien Auslauf gewährst, lass dir doch mal die Adresse ausgeben. Die sagt dir ganz klar, in welchem Bereich die Variable wohnt.
Wenn ich nun in der Arduino Referenz bei Referenzoperator / Dereferenzoperator nachschlage und das Beispiel Programm nehme um mir die Adresse(anstatt dem Wert) einer Variablen anzeigen zu lassen, macht der Compiler mir einen Strich durch die Rechnung.
uint8_t test = 5;
const uint8_t test1 = 7;
uint32_t a, b;
a = &test;
b = &test1;
Serial1.println (a,HEX);
Serial1.println (b,HEX);
error: invalid conversion from 'uint8_t*' {aka 'unsigned char*'} to 'uint32_t' {aka 'long unsigned int'} [-fpermissive]
154 | a = &test;
| ^~~~~
| |
| uint8_t* {aka unsigned char*}
Leider habe ich bisher immer versucht, um Pointer und Referenzen einen großen Bogen zu machen...
Da der RAM Bereich im rp2040 bei 0x20000000 anfängt und 2 weitere Blöcke bei 0x20040000 und 0x20041000 beginnen, ist somit bewiesen, das auch mit einer "const" Anweisung eine Variable im RAM Bereich angelegt wird - Ist hier nicht weiter tragisch, da ja genug RAM vorhanden ist. Es hat mich halt nur mal interessiert wie das denn wirklich läuft.
Auch ein weiterer Test mit der Definition der Variablen als uint16_t hat gezeigt, das wirklich nur so viele Bytes reserviert werden, wie notwendig sind.
Vielen Dank nochmals für die ganzen Hinweise. Das hat mir wirklich sehr geholfen und hat nebenbei noch sehr viel Spaß gemacht. Das letzte mal auf der Adress-Ebene war ich, als ich die AVR's noch in ASM programmiert habe.
Viele Grüße und noch ein schönes Wochenende,
Horst
Die Wirklichkeit, oder Realität, ist meistens viel komplexer, als man das als Einzelperson wissen und wahrnehmen kann.
Es macht auch übrigens keinen Sinn, auf Fragen, eine einfache Antwort zu erwarten, z.B. Ja/Nein Antworten, wenn sich dahinter ganze Universen befinden. Millionen von Details.
Mantra:
Einfache Antworten/Annahmen sind falsch.
Immer.(auch diese)
Siehe:
Keinesfalls ist das damit bewiesen.
Es zeigt nur, dass die readonly Variable im Ram angelegt wird, wenn man einen Pointer darauf nutzt, bzw. ihre Adresse herausfinden will. Dann muss sie im Ram angelegt werden.
Ich behaupte:
Im Normalfall (wenn möglich) wird der Compiler sie so behandeln, wie er auch constexpr byte test = 4;
behandelt.
Sie belegt dann weder Flash noch Ram.
Sondern wird als Literal in den generierten Code eingeflochten
Mit modernen Variablen, ist das schon etwas Quantenmechanisches....
Über das, wie die Variable wirklich behandelt wird, wie und wo sie steckt, darüber wird entschieden, wenn ein Beobachter das untersucht/verwendet.