2011-11-01 07:09:55 +01:00
|
|
|
/**
|
2012-01-05 02:29:29 +01:00
|
|
|
******************************************************************************
|
|
|
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
|
|
|
* @{
|
|
|
|
*
|
|
|
|
* @file startup.c
|
|
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
|
|
|
* @brief C based startup of F4
|
|
|
|
* @see The GNU Public License (GPL) Version 3
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2011-11-01 07:09:55 +01:00
|
|
|
*/
|
|
|
|
|
2012-01-05 02:29:29 +01:00
|
|
|
|
2011-11-01 07:09:55 +01:00
|
|
|
#include <string.h>
|
|
|
|
#include <stm32f4xx.h>
|
|
|
|
|
|
|
|
/* prototype for main() that tells us not to worry about it possibly returning */
|
2013-05-19 16:37:30 +02:00
|
|
|
extern int main(void) __attribute__((noreturn));
|
2011-11-01 07:09:55 +01:00
|
|
|
|
|
|
|
/* prototype our _main() to avoid prolog/epilog insertion and other related junk */
|
2013-05-19 16:37:30 +02:00
|
|
|
void _main(void) __attribute__((noreturn, naked, no_instrument_function));
|
2011-11-01 07:09:55 +01:00
|
|
|
|
|
|
|
/** default handler for CPU exceptions */
|
2013-05-19 16:37:30 +02:00
|
|
|
static void default_cpu_handler(void) __attribute__((noreturn, naked, no_instrument_function));
|
2011-11-01 07:09:55 +01:00
|
|
|
|
|
|
|
/** BSS symbols XXX should have a header that defines all of these */
|
2013-05-19 16:37:30 +02:00
|
|
|
extern char _sbss, _ebss;
|
2011-11-01 07:09:55 +01:00
|
|
|
|
|
|
|
/** DATA symbols XXX should have a header that defines all of these */
|
2013-05-19 16:37:30 +02:00
|
|
|
extern char _sidata, _sdata, _edata, _sfast, _efast;
|
2011-11-01 07:09:55 +01:00
|
|
|
|
|
|
|
/** The bootstrap/IRQ stack XXX should define size somewhere else */
|
2013-05-19 16:37:30 +02:00
|
|
|
char irq_stack[1024] __attribute__((section(".irqstack")));
|
2011-11-01 07:09:55 +01:00
|
|
|
|
|
|
|
/** exception handler */
|
2013-05-19 16:37:30 +02:00
|
|
|
typedef void (vector)(void);
|
2011-11-01 07:09:55 +01:00
|
|
|
|
|
|
|
/** CortexM3 CPU vectors */
|
|
|
|
struct cm3_vectors {
|
2013-05-19 16:37:30 +02:00
|
|
|
void *initial_stack;
|
|
|
|
vector *entry;
|
|
|
|
vector *vectors[14];
|
2011-11-01 07:09:55 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initial startup code.
|
|
|
|
*/
|
2013-05-19 16:37:30 +02:00
|
|
|
void _main(void)
|
2011-11-01 07:09:55 +01:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
// load the stack base for the current stack before we attempt to branch to any function
|
|
|
|
// that might bounds-check the stack
|
|
|
|
asm volatile ("mov r10, %0" : : "r" (&irq_stack[0]) :);
|
2011-11-01 07:09:55 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
/* enable usage, bus and memory faults */
|
|
|
|
SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk;
|
2011-11-01 07:09:55 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
/* configure FP state save behaviour - automatic, lazy save */
|
|
|
|
FPU->FPCCR |= FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk;
|
2011-11-01 07:09:55 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
/* configure default FPU state */
|
|
|
|
FPU->FPDSCR |= FPU_FPDSCR_DN_Msk; /* enable Default NaN */
|
2011-11-01 07:09:55 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
/* enable the FPU */
|
|
|
|
SCB->CPACR |= (0xf << 20); // turn on CP10/11 for FP support on cores that implement it
|
2011-11-01 07:09:55 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
/* copy initialised data from flash to RAM */
|
|
|
|
memcpy(&_sdata, &_sidata, &_edata - &_sdata);
|
2011-11-01 07:09:55 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
/* zero the BSS */
|
|
|
|
memset(&_sbss, 0, &_ebss - &_sbss);
|
2011-11-01 07:09:55 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
/* zero any 'fast' RAM that's been used */
|
|
|
|
memset(&_sfast, 0, &_efast - &_sfast);
|
2011-11-01 07:09:55 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
/* fill most of the IRQ/bootstrap stack with a watermark pattern so we can measure how much is used */
|
|
|
|
/* leave a little space at the top in case memset() isn't a leaf with no locals */
|
|
|
|
memset(&irq_stack, 0xa5, sizeof(irq_stack) - 64);
|
2011-11-01 07:09:55 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
/* call main */
|
|
|
|
(void)main();
|
2011-11-01 07:09:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default handler for CPU exceptions.
|
|
|
|
*/
|
2013-05-19 16:37:30 +02:00
|
|
|
static void default_cpu_handler(void)
|
2011-11-01 07:09:55 +01:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
for (;;) {
|
|
|
|
;
|
|
|
|
}
|
2011-11-01 07:09:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Prototype for optional exception vector handlers */
|
2013-05-19 16:37:30 +02:00
|
|
|
#define HANDLER(_name) extern vector _name __attribute__((weak, alias("default_cpu_handler")))
|
2011-11-01 07:09:55 +01:00
|
|
|
|
|
|
|
/* standard CMSIS vector names */
|
|
|
|
HANDLER(NMI_Handler);
|
|
|
|
HANDLER(HardFault_Handler);
|
|
|
|
HANDLER(MemManage_Handler);
|
|
|
|
HANDLER(BusFault_Handler);
|
|
|
|
HANDLER(UsageFault_Handler);
|
|
|
|
HANDLER(DebugMon_Handler);
|
|
|
|
|
|
|
|
/* these vectors point directly to the relevant FreeRTOS functions if they are defined */
|
|
|
|
HANDLER(vPortSVCHandler);
|
|
|
|
HANDLER(xPortPendSVHandler);
|
|
|
|
HANDLER(xPortSysTickHandler);
|
|
|
|
|
|
|
|
/** CortexM3 vector table */
|
2013-05-19 16:37:30 +02:00
|
|
|
struct cm3_vectors cpu_vectors __attribute((section(".cpu_vectors"))) =
|
|
|
|
{
|
|
|
|
.initial_stack = &irq_stack[sizeof(irq_stack)],
|
|
|
|
.entry = (vector *)_main,
|
|
|
|
.vectors = {
|
|
|
|
NMI_Handler,
|
|
|
|
HardFault_Handler,
|
|
|
|
MemManage_Handler,
|
|
|
|
BusFault_Handler,
|
|
|
|
UsageFault_Handler,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
vPortSVCHandler,
|
|
|
|
DebugMon_Handler,
|
|
|
|
0,
|
|
|
|
xPortPendSVHandler,
|
|
|
|
xPortSysTickHandler,
|
|
|
|
}
|
2011-11-01 07:09:55 +01:00
|
|
|
};
|
2012-01-05 02:29:29 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
2013-05-05 09:02:24 +02:00
|
|
|
*/
|