Statico implica che la variabile sia isolata da quel file / funzione / area di codice. Il luogo in cui è definito è visibile solo lì e quando viene utilizzato su non globali trasforma essenzialmente quella variabile in una globale dal punto di vista dell'archiviazione. Una variabile locale con una definizione statica significa che non voglio perdere quel valore da una chiamata di questa funzione a un'altra, quindi deve essere memorizzata globalmente per quella funzione, normalmente una variabile locale è sullo stack in modo che la funzione possa essere ri- entrant (una nuova copia delle variabili locali per ogni voce nella funzione). Quindi le variabili globali statiche sono comunque globali, le variabili locali statiche sono locali ma memorizzate insieme alle globali. In quello che viene spesso chiamato .data ma le toolchain possono avere nomi diversi. Questa è fondamentalmente la ram / memoria (lettura / scrittura) in cui sono archiviate le altre variabili globali o in cui vengono inizializzate le variabili quando definite
int x = 7;
vengono memorizzati. Le variabili globali o le variabili locali statiche che non vengono inizializzate quando definite
int y;
si trovano in quello che viene spesso chiamato .bss. Questo è un altro pezzo di memoria di lettura / scrittura, ma questa memoria prima di avviare main () viene azzerata per te in modo che per le specifiche o per assunzione quelle variabili siano zero all'avvio del programma.
const è un modo di dire che lo dichiaro come una variabile di sola lettura, non ho intenzione di memorizzarlo solo leggendo da esso. Quindi il compilatore può scegliere (in realtà è il programmatore poiché alla fine determina ciò che fa il linker, spesso lasciando che lo script del linker predefinito venga utilizzato e non assumendo quel lavoro) se va a flash o ram, può andare in qualsiasi posto e funzionare bene.
Per microcontrollori e altri luoghi in cui è necessario avviare e avviare l'esecuzione da una memoria non volatile (flash / rom / ecc.). Prima di tutto il programma stesso deve essere memorizzato in qualcosa di non volatile. Successivamente le cose .data, le cose che hai inizializzato nel tuo codice durante la definizione della variabile, cose che possono essere determinate in fase di compilazione. deve anche trovarsi in una memoria non volatile, ma alla fine i dati vengono letti / scritti, quindi il codice di bootstrap che viene eseguito prima che venga chiamato main (), fa il lavoro di copiare i blocchi .data nella memoria di lettura / scrittura. Il codice .bss o le variabili locali globali o statiche che non sono inizializzate e si presume siano zero quando si avvia, quelle non hanno bisogno di memoria non volatile, solo la posizione e quanto ne ha, e da questo il bootstrap può azzerare quella lettura / scrivere la memoria.
Ci sono ragioni per cui comunichiamo usando termini come .text, .data, .bss, .rodata, ecc. Perché vediamo che gli strumenti posizionano gli elementi del nostro programma in quei posti e poi noi può vedere dove devono vivere quei luoghi nella memoria non volatile e quindi durante il runtime se è diverso. .testo sebbene sciocco, è il nostro programma, il codice macchina e altri dati associati. .data sono variabili del nostro programma che vengono inizializzate prima di iniziare a essere diverse da zero, quindi devono essere archiviate in una memoria non volatile e quindi spostate in lettura / scrittura prima di utilizzarle. .bss sono variabili del nostro programma che si presume siano zero quando iniziamo, quindi la quantità e la posizione devono essere memorizzate in non volatile e il boostrap può eseguire l'azzeramento (o talvolta sono semplicemente memorizzate come un gruppo di zeri in anche il flash / rom). .rodata a volte è separato è il const a volte i const si trovano in .text, .text e .rodata sono considerati di sola lettura quindi possono rimanere in flash se il tuo prodotto è in grado di gestirlo (i flash più recenti hanno problemi di lettura-disturbo quindi fuori dal flash su un microcontrollore non lo vuoi necessariamente fare, devi stare attento) o possono anche essere copiati su ram.
Poi ci sono i termini heap e stack, che spesso dopo il programma, se necessario, .bss e .data consumano una certa quantità di ram, spesso dagli indirizzi inferiori in su. poi il resto di quella ram viene diviso in heap e stack, a volte senza una linea continua tra di loro, programmi mal funzionanti possono avere l'heap e lo stack in collisione causando un crash. lo stack è spesso dall'alto verso il basso e l'heap è spesso dal basso verso l'alto, ma queste non sono regole rigide e veloci.
Dove sono queste sul tuo tabellone? beh, dipende sia dal chip che dalla scheda per quanto riguarda le opzioni, quindi alla fine spetta a te il programmatore decidere mentre controlli il processo di compilazione e collegamento. La maggior parte delle persone riceve un esempio o una toolchain che conosce il tuo sistema e lasci le impostazioni predefinite. Ma sei assolutamente responsabile. Affinché un microcontrollore si avvii devi avere un modo per farlo, di solito è un chip flash on o off a seconda del mcu, e le cose non volatili sopra menzionate devono essere memorizzate lì o in qualche altro posto non volatile . Allo stesso modo hai un po 'di RAM, devi dividerlo con le cose di lettura / scrittura di cui hai bisogno, inclusi stack e heap se sei abbastanza coraggioso da usarlo in un tale sistema (non saggio). Alcuni processori lo stack fa parte del design e non devi preoccuparti, altri lo fai. Se hai più di queste cose, ram non volatile o di lettura / scrittura, allora puoi scegliere e scegliere dove mettere le cose.
se usi una toolchain di qualcuno, o hai accesso a diversi lì non c'è motivo di presumere che faranno la stessa cosa con il tuo programma con il loro script di collegamento predefinito. di solito le toolchain forniscono file di mappe o altri modi per vedere dove hanno posizionato le cose per te.
è certamente possibile avere un sistema basato su microcontrollore senza flash, ogni sentire di un mouse o di una tastiera? Alcuni dei insieme a molti altri prodotti possono funzionare senza queste cose. Alcuni potrebbero ad esempio avere nella logica del chip per gestire l'enumerazione usb, quindi il driver del sistema operativo per quel prodotto contiene il firmware, scarica il firmware nella ram sul dispositivo e avvia il processore e forse enumera nuovamente l'USB così che ora è un topo o qualsiasi altra cosa. non tutti lo fanno ma a volte è fatto. Allo stesso modo potresti avere qualche altro design in cui qualche altro hardware o soluzione scarica il programma nel chip / ram prima di avviare il processore in modo efficace, facendo sembrare che il processore non abbia flash. Ma hai ancora gli stessi concetti .text, .data, .bss e il programma che esegui, sia esso solo ram, era ancora compilato in programma, zero dati di inizializzazione e dati di inizializzazione diversi da zero e al linker doveva essere detto dove posiziona queste cose nel binario e aggiorna il codice per sapere dove il linker ha posizionato le variabili che deve usare.