Cortex-M3 - Programming STM32-Discovery using GNU tools Startup code
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:
1
|
ENTRY(handler_reset) |
So in startup code this will be first function called.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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(); } |
Startup code takes source and destination addresses from linker script as external variables:
1
2
3
4
5
6
|
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; |
These we defined when described sections. So the only thing left for startup code is take values from source addresses in Flash memory and copy them to destination addresses in RAM. Also variables stored in .bss section are defaulted to zero values. So no need to null them in source when used.
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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
__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 }; |
In linker script we defined that “.interrupt_vector” section is starting at 0×00000000 address so stack pointer is located at 0×00000000 address of Flash. Then goes reset handler which then copies variable data to RAM and nulls undefined variables and then it is over with startup code and all resources are alocated to main() routine.
1
2
3
4
5
6
7
|
void handler_default( void ) { while (1) { //loop } } |
handler default routine simply handles unexpected interrupts and puts MCU to endless loop. This is very simplified version of linker script and startup code. Ir explains thing pretty well I guess. For starters probably it is best to find working example of Arm Cortex M3 GCC code copy linker script and startup code as they are and focus on software writing. Barely you’ll need to change these soon.
hi,
i am new to embeddeds system and i was trying since one month to make a linker script and startup file for Arm7tdmi – TMS470R1B1M chip, to be compiled under GNU GCC ARM Non-EABI tool chain in code-sourcery lite version.
I would be great help if you provide the startup and linker file for above which can work with interrupts also.
If you can’t, it would be a great help if you just provide what changes has to be made to the linker and startup files explained by you on this webpage.
Thanks.