Start up code is run just after microcontroller is reset and is executed before main program. As linker script, startup code usually is implemented as universal code for all same microcontroller type. So usually you don’t need to write one from scratch. Anyway it is good to know what happens there anyway.
As we said linker script has to go along with startup code. This means that it will initialize MCU automatically according to data defined in linker. Startup code initializes variables, copies defined variables from Flash to RAM, initializes stack and then gives resources to main program. You will find that startup codes usually are written in assembly language, but this can also be done in C which is easier to read and modify if necessary. First of all in linker script we have pointed entry point to startup with following command:
ENTRY(handler_reset)
So in startup code this will be first function called.
void handler_reset(void)
{
unsigned long *source;
unsigned long *destination;
// Copying data from Flash to RAM
source = &_data_flash;
for (destination = &_data_begin; destination < &_data_end;)
{
*(destination++) = *(source++);
}
// default zero to undefined variables
for (destination = &_bss_begin; destination < &_bss_end;)
{
*(destination++) = 0;
}
// starting main program
main();
}
extern unsigned long _data_flash;
extern unsigned long _data_begin;
extern unsigned long _data_end;
extern unsigned long _bss_begin;
extern unsigned long _bss_end;
extern unsigned long _stack_end;
Next step is that startup does is to allocate exception handler vector table. Due to ARM Cortex architecture the first address in vector table is used to store address of stack end. This is convenient and efficient way to define it.
__attribute__ ((section(".interrupt_vector")))
void (* const table_interrupt_vector[])(void) =
{
(void *) &_stack_end, // 0 - stack
handler_reset, // 1
handler_default, // 2
handler_default, // 3
handler_default, // 4
handler_default, // 5
handler_default, // 6
0, // 7
0, // 8
0, // 9
0, // 10
handler_default, // 11
handler_default, // 12
0, // 13
handler_default, // 14
handler_default, // 15
// peripherals
handler_default, // 0
handler_default, // 1
handler_default, // 2
handler_default, // 3
handler_default, // 4
-//-
handler_default, // 59
handler_default // 60
};
void handler_default(void)
{
while (1)
{
//loop
}
}
The post Programming STM32-Discovery using GNU tools: Startup code appeared first on Key to Smart.