Inicialització del sistema i del llenguatge C

És la funció main() realment la primera funció que s’executa quan comença l’execució? Qui implementa les funcions malloc()/free()? Avui toca aprendre sobre els interiors del runtime de C i com s’inicialitza tot el sistema

Abans no comenci l’execució del nostre programa s’executen tot de funcions per preparar tant el microcontrolador com l’entorn d’execució de C.

Comencem per l’inici: quan el microcontrolador surt de l’estat de reset, el que fa és anar a executar el ResetHandler que està a l’adreça per defecte del Program Counter (registre pc).

Aquesta funció la trobem definida al fitxer startup_gcc_efm32tg.s al directori CMSIS del projecte i aquest handler tant sols crida la funció SystemInit().

Reset_Handler de EFM32

Podem dir-li al debugger que s’aturi en aquesta funció canviant-li la configuració i dient-li que s’aturi a la funció que vulguem, en aquest cas hi podem escriure Reset_Handler. Per defecte veurem que està configurat per que s’aturi a la funció main().

Configuració del Debug

Aquesta funció està definida pel fabricant i la trobem al fitxer system_efm32tg.c al mateix directori. En el cas dels Cortex-M el que fa és modificar el registre VTOR de la CPU per a que apunti a la taula de vectors d’interrupció definits al fitxer startup_gcc_efm32tg.s.

A continuació segueix executant-se el Reset Handler, i el primer que fa és copiar la secció .data a la RAM. Això què vol dir? Doncs que les variables que s’han inicialitzat amb algun valor inicial al nostre codi s’han emmagatzemat al fitxer binari a continuació del codi (secció .text). Abans de començar a funcionar el codi, cal copiar aquestes variables a la memòria RAM, que és la secció .data. Així, quan aquesta part de la inicialització acaba, tenim les variables a la memòria RAM amb els seus valors inicials.

Còpia de la secció .bss a la memòria RAM

Un acabada aquesta còpia, es crida a la funció _start() de la biblioteca que estiguem fent servir. En el cas de EFM32 la biblioteca és la Nano C library. Aquesta biblioteca implementa les llibreries estàndard de C (stdlib, string, memory, etc.) i li cal una inicialització que es troba al fitxer crt0.S (situada a newlib/libc/sys/arm/crt0.S).

Inicialització del registre d’stack (Stack Pointer)

El que es fa aquí és inicialitzar el punter de l’stack a l’adreça que s’indiqui al fitxer del linker i posar a zero tota la memòria de la secció .bbs.

Inicialització de la secció .bss

A continuació es crida la funció __libc_init_array() (situada a newlib/libc/misc/init.c) que va cridant funcions d’inicialització de la pròpia biblioteca (i constructors estàtics si treballem en C++).

Finalment, la funció _start() crida a la funció main() del nostre programa i ja comença a executar-se el nostre codi.

Crida a la funció _init() i funció main()

Com veieu, no és trivial engegar un microcontrolador i tenir l’entorn del llenguatge C preparat, però per sort tenim aquestes biblioteques i els fitxers que ens donen els fabricants per fer-ho sense que ens n’haguem de preocupar.

Deixa un comentari

Fill in your details below or click an icon to log in:

WordPress.com Logo

Esteu comentant fent servir el compte WordPress.com. Log Out /  Canvia )

Google photo

Esteu comentant fent servir el compte Google. Log Out /  Canvia )

Twitter picture

Esteu comentant fent servir el compte Twitter. Log Out /  Canvia )

Facebook photo

Esteu comentant fent servir el compte Facebook. Log Out /  Canvia )

S'està connectant a %s

Aquest lloc utilitza Akismet per reduir els comentaris brossa. Apreneu com es processen les dades dels comentaris.