summaryrefslogtreecommitdiff
path: root/Project/src/platform/stm32f0-gcc/startup/startup.cpp
blob: 95276ae5cfc3ac858f45bb77860ae4de77eec815 (plain)
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// very simple startup code with definition of handlers for all cortex-m cores

typedef void (*ptr_func_t)();

// main application
extern "C" int main();

// location of these variables is defined in linker script
extern unsigned __data_start;
extern unsigned __data_end;
extern unsigned __data_load;

extern unsigned __bss_start;
extern unsigned __bss_end;

extern unsigned __heap_start;

extern ptr_func_t __preinit_array_start[];
extern ptr_func_t __preinit_array_end[];

extern ptr_func_t __init_array_start[];
extern ptr_func_t __init_array_end[];

extern ptr_func_t __fini_array_start[];
extern ptr_func_t __fini_array_end[];


/** Copy default data to DATA section
 */
void copy_data() {
    unsigned *src = &__data_load;
    unsigned *dst = &__data_start;
    while (dst < &__data_end) {
        *dst++ = *src++;
    }
}

/** Erase BSS section
 */
void zero_bss() {
    unsigned *dst = &__bss_start;
    while (dst < &__bss_end) {
        *dst++ = 0;
    }
}

/** Fill heap memory
 */
void fill_heap(unsigned fill=0x45455246) {
    unsigned *dst = &__heap_start;
    unsigned *msp_reg;
    __asm__("mrs %0, msp\n" : "=r" (msp_reg) );
    while (dst < msp_reg) {
        *dst++ = fill;
    }
}

/** Call constructors for static objects
 */
void call_init_array() {
    auto array = __preinit_array_start;
    while (array < __preinit_array_end) {
        (*array)();
        array++;
    }

    array = __init_array_start;
    while (array < __init_array_end) {
        (*array)();
        array++;
    }
}

/** Call destructors for static objects
 */
void call_fini_array() {
    auto array = __fini_array_start;
    while (array < __fini_array_end) {
        (*array)();
        array++;
    }
}

// reset handler
extern "C" void RESET_handler() {
    copy_data();
    zero_bss();
    fill_heap();
    call_init_array();
    // run application
    main();
    // call destructors for static instances
    call_fini_array();
    // stop
    while (true);
}