2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
7 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
8 * @brief C based startup of F4
9 * @see The GNU Public License (GPL) Version 3
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include <stm32f4xx.h>
32 /* prototype for main() that tells us not to worry about it possibly returning */
33 extern int main(void) __attribute__((noreturn
));
35 /* prototype our _main() to avoid prolog/epilog insertion and other related junk */
36 void _main(void) __attribute__((noreturn
, naked
, no_instrument_function
));
38 /** default handler for CPU exceptions */
39 static void default_cpu_handler(void) __attribute__((noreturn
, naked
, no_instrument_function
));
41 /** BSS symbols XXX should have a header that defines all of these */
42 extern char _sbss
, _ebss
;
44 /** DATA symbols XXX should have a header that defines all of these */
45 extern char _sidata
, _sdata
, _edata
, _sfast
, _efast
;
47 /** The bootstrap/IRQ stack XXX should define size somewhere else */
48 char irq_stack
[1024] __attribute__((section(".irqstack")));
50 /** exception handler */
51 typedef void (vector
)(void);
53 /** CortexM3 CPU vectors */
61 * Initial startup code.
65 // load the stack base for the current stack before we attempt to branch to any function
66 // that might bounds-check the stack
67 asm volatile ("mov r10, %0" : : "r" (&irq_stack
[0]) :);
69 /* enable usage, bus and memory faults */
70 SCB
->SHCSR
|= SCB_SHCSR_USGFAULTENA_Msk
| SCB_SHCSR_BUSFAULTENA_Msk
| SCB_SHCSR_MEMFAULTENA_Msk
;
72 /* configure FP state save behaviour - automatic, lazy save */
73 FPU
->FPCCR
|= FPU_FPCCR_ASPEN_Msk
| FPU_FPCCR_LSPEN_Msk
;
75 /* configure default FPU state */
76 FPU
->FPDSCR
|= FPU_FPDSCR_DN_Msk
; /* enable Default NaN */
79 SCB
->CPACR
|= (0xf << 20); // turn on CP10/11 for FP support on cores that implement it
81 /* copy initialised data from flash to RAM */
82 memcpy(&_sdata
, &_sidata
, &_edata
- &_sdata
);
85 memset(&_sbss
, 0, &_ebss
- &_sbss
);
87 /* zero any 'fast' RAM that's been used */
88 memset(&_sfast
, 0, &_efast
- &_sfast
);
90 /* fill most of the IRQ/bootstrap stack with a watermark pattern so we can measure how much is used */
91 /* leave a little space at the top in case memset() isn't a leaf with no locals */
92 memset(&irq_stack
, 0xa5, sizeof(irq_stack
) - 64);
99 * Default handler for CPU exceptions.
101 static void default_cpu_handler(void)
108 /** Prototype for optional exception vector handlers */
109 #define HANDLER(_name) extern vector _name __attribute__((weak, alias("default_cpu_handler")))
111 /* standard CMSIS vector names */
112 HANDLER(NMI_Handler
);
113 HANDLER(HardFault_Handler
);
114 HANDLER(MemManage_Handler
);
115 HANDLER(BusFault_Handler
);
116 HANDLER(UsageFault_Handler
);
117 HANDLER(DebugMon_Handler
);
119 /* these vectors point directly to the relevant FreeRTOS functions if they are defined */
120 HANDLER(vPortSVCHandler
);
121 HANDLER(xPortPendSVHandler
);
122 HANDLER(xPortSysTickHandler
);
124 /** CortexM3 vector table */
125 struct cm3_vectors cpu_vectors
__attribute((section(".cpu_vectors"))) =
127 .initial_stack
= &irq_stack
[sizeof(irq_stack
)],
128 .entry
= (vector
*)_main
,