mspgcc: A port of the GNU tools to the Texas Instruments MSP430 microcontrollers | ||
---|---|---|
<<< Previous | MSP430 specific extensions to the GNU toolchain | Next >>> |
The standard library includes a start-up module that prepares the environment for running applications written in C. Several versions of the start-up script are available because each processor has different set-up requirements. The msp430-gcc compiler selects the appropriate module based on the processor specified in the command line options.
The start-up module is responsible for the following tasks
Providing a default vector table.
Providing default interrupt handlers.
Initializing the watchdog timer.
Initializing the .data segment.
Zeroing the .bss segment.
Jumping to main(). (A jump is used, rather than a call, to save space on the stack. main() is not expected to return.)
Look at the disassembled code produced by
$ msp430-objdump -DS a.out |
a.out: file format elf32-msp430
Disassembly of section .text:
0000fc00 <_reset_vector__>:
fc00: b2 40 80 5a mov #23168, &0x0120 ; #0x5a80
fc04: 20 01
fc06: 3f 40 50 fc mov #-944, r15 ; #0xfc50
fc0a: 3e 40 00 02 mov #512, r14 ; #0x0200
fc0e: 3d 40 00 02 mov #512, r13 ; #0x0200
fc12: 0d 9e cmp r14, r13
fc14: 06 24 jz $+14 ; abs dst addr 0xfc22
fc16: 1d 53 inc r13
fc18: fe 4f 00 00 mov.b @r15+, 0(r14)
fc1c: 1e 53 inc r14
fc1e: 0f 9d cmp r13, r15
fc20: fb 2b jnc $-8 ; abs dst addr 0xfc18
fc22: 3f 40 00 02 mov #512, r15 ; #0x0200
fc26: 3d 40 00 02 mov #512, r13 ; #0x0200
fc2a: 0d 9f cmp r15, r13
fc2c: 06 24 jz $+14 ; abs dst addr 0xfc3a
fc2e: 1d 53 inc r13
fc30: cf 43 00 00 mov.b #0, 0(r15) ; subst r3 with As==00
fc34: 1f 53 inc r15
fc36: 0f 9d cmp r13, r15
fc38: fb 2b jnc $-8 ; abs dst addr 0xfc30
fc3a: 30 40 44 fc br #0xfc44
0000fc3e <_unexpected_1_>:
fc3e: 30 40 42 fc br #0xfc42
0000fc42 <_unexpected_>:
fc42: 00 13 reti
0000fc44 <main>:
fc44: 31 40 80 02 mov #640, SP ; #0x0280
fc48: 30 40 4c fc br #0xfc4c
0000fc4c <__stop_progExec__>:
fc4c: 02 43 clr SR
fc4e: fe 3f jmp $-2 ; abs dst addr 0xfc4c
Disassembly of section .data:
Disassembly of section .vectors:
0000ffe0 <InterruptVectors>:
ffe0: 3e fc interrupt service routine at 0xfc3e
ffe2: 3e fc interrupt service routine at 0xfc3e
ffe4: 3e fc interrupt service routine at 0xfc3e
ffe6: 3e fc interrupt service routine at 0xfc3e
ffe8: 3e fc interrupt service routine at 0xfc3e
ffea: 3e fc interrupt service routine at 0xfc3e
ffec: 3e fc interrupt service routine at 0xfc3e
ffee: 3e fc interrupt service routine at 0xfc3e
fff0: 3e fc interrupt service routine at 0xfc3e
fff2: 3e fc interrupt service routine at 0xfc3e
fff4: 3e fc interrupt service routine at 0xfc3e
fff6: 3e fc interrupt service routine at 0xfc3e
fff8: 3e fc interrupt service routine at 0xfc3e
fffa: 3e fc interrupt service routine at 0xfc3e
fffc: 3e fc interrupt service routine at 0xfc3e
fffe: 00 fc interrupt service routine at 0xfc00
The first thing that happens is the watchdog timer is initialized. Then the program copies the initialized global variables to RAM (0xfc0a - 0xfc20). After this, the uninitialized globals are cleared (0xfc22 - 0xfc3a). After this, we jump to 'main', which is located at 0xfc44.
In main, we copy the value 0x0280 to r1. This initializes the stack pointer, taking into account the space required for local variables.
Next, as long as main does nothing, it jumps to "__stop_progExec__". At this point the SR is zeroed. The next instruction is jump to "__stop_progExec__". This is the end of program execution.
In this module, the application uses:
"_etext" - end of the ".text" section. The place where the initial values of global variables are stored.
"__data_start" - the start of RAM.
"_edata" - the end of data RAM ("_edata - __data_start" is the size of the ".data" segment).
"__bss_start" - the place where uninitialized variables resides in RAM.
"__bss_end" - the end of this segment.
"__stack" - the stack.
All of these variables can be overridden with -Wl,--defsym=[symname]=(value) For example, to set the initial stack point to0x280, use -Wl,--defsym=__stack=0x280.
In most cases it is not necessary to redefine these values. They can be obtained from the user application as follows
... extern int __stack; int m; (int *) m = &__stack; /* now m contains the address of the stack */ ... |
The startup code adds a litter overhead to the application. The size of the startup code is 80 bytes without interrupt vector table. If you do not like this approach, you can define your own startup code.
<<< Previous | Home | Next >>> |
The standard library functions | Up | Redefining the startup procedure |