Alocarea variabilelor în embedded C
În primul rând durata de stocare determină timpul de viata al unui obiect, în cazul nostru a variabilelor. Un obiect există, are o adresă constantă şi reţine ultima valoare stocată de-a lungul vieţii.
Există 3 tipuri de durate de stocare:
- Static
- automatic
- Alocate dinamic
Variabile
1. Variabilele "statice"
Un obiect are o durata statică "static" de alocare dacă:
- Identificatorul este declarat cu linkage extern sau intern
- Identificatorul este declarat folosind cuvântul cheie "static"
Acest tip de obiect are durata de viaţă a întregului program şi este iniţializat doar o singură dată la începutul rulării programului.
2. Automatic
Un obiect a cărui identificator nu are linkage și fără cuvântul cheie static are durata de stocare automatic. De exemplu o variabila declarata în interiorul unei funcţii folosind cuvântul cheie auto se va considera locală şi nu va fi vizibilă în alte funcţii din interiorul modulului.
Durata de viaţă a acestor variabile este limitată pe durata execuţiei funcţiei. Pentru aceste variabile compilatorul de obicei nu va aloca memorie ci va "optimiza" aceste variabile şi se vor folosi regiştrii pentru procesarea lor.
/*variabile globale*/
unsigned char a=2;
unsigned char b=3;
void f (void)
{
/* variabile locale*/
auto int a=1;
auto int b=2;
}
void f2()
{
/* variabila locala */
int c;
/* rezultatul va fi c = 5 */
c = a + b;
}
3. Alocate (memorie dinamică) Variabilele alocate dinamic au durată de viaţă variabilă. Se alocă de către programator folosind funcţia malloc în memoria dinamică (heap memory). Proprietate de bază a acestui tip de memorie este că are o dimensiune infinită. De fapt nu există acest tip de memorie. Acest tip de memorie a fost inventat în sistemele de operare moderne care dispun de spaţii de memorie foarte mare care pot fi considerate "infine". Într-un mediul embedded şi mai ales în sistemele safety-critical acest tip de alocare nu este permisă. Motivul este lesne de înţeles : memoria dinamică este prin definiţie nedeterministă şi nu prea se împacă cu , de exemplu un microcontroler pe 16 biți cu spaţiu de adresare de 65536 adrese , cu o memorie de program (flash) de câţiva kilo octeţi, cu o memorie RAM limitată şi eventual cu un spţiu de stocare EEPROM de 32 KB.
În embedded se aplică regula de mai jos:
MISRA-C:2004, Rule 20.4: Dynamic heap memory allocation shall not be used.
Chiar şi în sistemele cu suficientă memorie este recomandat să se utilizeze cu mare atenţie acest tip de alocare pentru că este nedeterminist. (e ca vinul roşu, e bun dar în cantităţi mici :) )
Durata de stocare și linkage-ul
Obiectele sau variabilele definite în interiorul funcţiilor care nu sunt declarate folosind cuvântul cheie static, nu au linkage şi nici durată de stocare statică. Obiectele care nu au linkage și care au durata statica de stocare mențin ultima valoare între două apeluri de funcție. Inițializarea acestor variabile nu este dinamică, dacă aceste variabile sunt inițializate folosind o instrucțiune și nu o expresie de inițializare atunci asignarea este executata de fiecare data când se apelează funcția.
static int a; /* Linkage intern in modul,
* durata statica de stocare
* (variabila globala in modul) */
int b; /* linkage extern,
* durata statica de stocare
* (variabila globala pentru toate
* fisierele din proiect) */
void func (void)
{
int c; /* nu are linkage , are durata auto de stocare (locala) */
static int d; /* nu are linkage, are durata statica de stocare */
static int e = 2+1; /* ... cu initializare,
* aceasta initializare
* se va face de fiecare
* data cand se apeleaza functia */
}