Când să utilizați PROGMEM? (Arduino, Utilizarea Memoriei, Memorie)

Praveen Singh Yadav a intrebat.

Cred că PROGMEM este utilizat pentru a stoca date mari (de exemplu, șiruri de caractere) care nu se schimbă. Astfel, el eliberează SRAM.

în Referința Ardunio se menționează că.

„Utilizarea PROGMEM este, de asemenea, o procedură în doi pași. După introducerea datelor în memoria Flash, este nevoie de metode speciale (funcții), definite și în biblioteca pgmspace.h, pentru a citi datele din memoria de program înapoi în SRAM, astfel încât să putem face ceva util cu ele.”

Dacă trebuie să încarc datele în SRAM înainte de a le utiliza, atunci cum este mai eficient decât să le stropesc direct în SRAM prin definirea vaiable în mod normal

Comentarii

  • … Pentru că nu rămâne în SRAM… –  > Por Ignacio Vazquez-Abrams.
3 răspunsuri
Majenko

Să zicem că aveți un șir de 1000 de caractere în Flash și doriți să îl imprimați pe Serial. Da, trebuie să îl încărcați în RAM pentru a trece acele date în jurul locului pentru imprimare. Dar, trebuie să puneți toate toate datele în RAM deodată? Nu. Aveți nevoie doar de un singur caracter la un moment dat. Deci, în loc să luați 1000 de caractere și să alocați 1000 de octeți de RAM și să copiați tot în RAM, apoi să le imprimați, trebuie doar să alocați 1 octet de RAM*, să copiați fiecare caracter pe rând și să le imprimați.

Deoarece nu puteți citi decât câte un singur caracter pe rând din flash, oricum nu există niciun avantaj în a citi întregul lot.


*De fapt, din cauza optimizărilor compilatorului, probabil că acest lucru nici măcar nu atinge memoria RAM și rămâne doar într-un registru al procesorului.

Juraj

Dacă aveți un c-string constant (char array) în codul dvs. fără macro F sau progmem, atunci șirul este copiat în RAM la început și rămâne acolo.

Dacă într-o funcție folosiți macroul F sau creați un buffer char de o anumită dimensiune și copiați șirul progmem în buffer, la întoarcerea funcției variabilele sunt șterse din stivă și memoria este eliberată.

În cazul unui array mare, dacă îl puneți în progmem și apoi, în cod, când trebuie să căutați o valoare în acel array, trebuie să copiați în RAM doar un singur element al array-ului, nu întregul array.

Julian Goldsmith

După cum a spus Majenko, nu trebuie să puneți în RAM tot ce aveți în memoria flash deodată. Puteți muta elementele în SRAM după cum este necesar și puteți reutiliza memoria după ce ați terminat.

Cu toate acestea, nu sunteți limitat la mutarea unui octet la un moment dat. Există funcții definite în avr/pgmspace.h care se pot ocupa de mutarea datelor în locul dumneavoastră.

De exemplu, ați putea face ceva de genul:

const struct mystruct_s my_value PROGMEM = { value = 1234 };

// ...

struct mystruct_s working_copy;
memcpy_P(&working_copy, &my_value, sizeof(struct mystruct_s));
int foo = working_copy.value / 2;