kopia lustrzana https://github.com/OpenRTX/OpenRTX
Boot code for STM32F401xC MCUs
rodzic
323566040a
commit
c35604aee8
|
@ -232,6 +232,15 @@ stm32f4xx_inc = ['platform/mcu/CMSIS/Include',
|
|||
'platform/mcu/STM32F4xx/drivers',
|
||||
'platform/mcu/STM32F4xx/drivers/usb']
|
||||
|
||||
##
|
||||
## STM32F401
|
||||
##
|
||||
|
||||
stm32f401_src = stm32f4xx_src + ['platform/mcu/STM32F4xx/boot/startup_f401.cpp',
|
||||
'platform/mcu/STM32F4xx/boot/bsp_f401.cpp']
|
||||
stm32f401_inc = stm32f4xx_inc
|
||||
stm32f401_def = {'STM32F401xx': '', 'HSE_VALUE':'8000000', 'SYSCLK_FREQ_84MHz':''}
|
||||
|
||||
##
|
||||
## STM32F405
|
||||
##
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -150,6 +150,14 @@ uint32_t SystemCoreClock = 180000000;
|
|||
|
||||
uint32_t SystemCoreClock = 168000000;
|
||||
|
||||
#elif defined(SYSCLK_FREQ_84MHz)
|
||||
|
||||
#define PLL_N 336
|
||||
#define PLL_P 4
|
||||
#define PLL_Q 7
|
||||
|
||||
uint32_t SystemCoreClock = 84000000;
|
||||
|
||||
#else
|
||||
#error System clock frequency not supported
|
||||
#endif
|
||||
|
@ -333,11 +341,13 @@ static void SetSysClock(void)
|
|||
/* HCLK = SYSCLK / 1 */
|
||||
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
|
||||
|
||||
/* PCLK2 = HCLK / 2 */
|
||||
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
|
||||
|
||||
/* PCLK1 = HCLK / 4 */
|
||||
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
|
||||
#if defined(SYSCLK_FREQ_84MHz)
|
||||
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; /* APB1 = SYSCLK/2 */
|
||||
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; /* APB2 = SYSCLK */
|
||||
#else
|
||||
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; /* APB1 = SYSCLK/4 */
|
||||
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; /* APB2 = SYSCLK/2 */
|
||||
#endif
|
||||
|
||||
/* Configure the main PLL */
|
||||
RCC->PLLCFGR = (PLL_Q << 24) /* PLL divider for USB clock */
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2023 by Silvano Seva IU2KWO, *
|
||||
* Federico Terraneo *
|
||||
* *
|
||||
* 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, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
/***********************************************************************
|
||||
* bsp.cpp Part of the Miosix Embedded OS.
|
||||
* Board support package, this file initializes hardware.
|
||||
************************************************************************/
|
||||
|
||||
#include <interfaces/delays.h>
|
||||
#include <interfaces/bsp.h>
|
||||
#include <kernel/kernel.h>
|
||||
#include <kernel/sync.h>
|
||||
#include <stm32f4xx.h>
|
||||
#include "../drivers/usb_vcom.h"
|
||||
|
||||
namespace miosix
|
||||
{
|
||||
|
||||
//
|
||||
// Initialization
|
||||
//
|
||||
|
||||
void IRQbspInit()
|
||||
{
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN
|
||||
| RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN
|
||||
| RCC_AHB1ENR_GPIOHEN;
|
||||
RCC_SYNC();
|
||||
|
||||
GPIOA->OSPEEDR=0xaaaaaaaa; //Default to 50MHz speed for all GPIOS
|
||||
GPIOB->OSPEEDR=0xaaaaaaaa;
|
||||
GPIOC->OSPEEDR=0xaaaaaaaa;
|
||||
GPIOD->OSPEEDR=0xaaaaaaaa;
|
||||
GPIOH->OSPEEDR=0xaaaaaaaa;
|
||||
|
||||
// Configure SysTick
|
||||
SysTick->LOAD = SystemCoreClock / miosix::TICK_FREQ;
|
||||
}
|
||||
|
||||
void bspInit2()
|
||||
{
|
||||
vcom_init();
|
||||
}
|
||||
|
||||
//
|
||||
// Shutdown and reboot
|
||||
//
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
reboot();
|
||||
}
|
||||
|
||||
void reboot()
|
||||
{
|
||||
disableInterrupts();
|
||||
miosix_private::IRQsystemReboot();
|
||||
}
|
||||
|
||||
} //namespace miosix
|
|
@ -0,0 +1,347 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2023 by Silvano Seva IU2KWO, *
|
||||
* Federico Terraneo *
|
||||
* *
|
||||
* 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, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* startup.cpp
|
||||
* STM32 C++ startup.
|
||||
* NOTE: for stm32f4 devices ONLY.
|
||||
* Supports interrupt handlers in C++ without extern "C"
|
||||
* Developed by Terraneo Federico, based on ST startup code.
|
||||
* Additionally modified to boot Miosix.
|
||||
*/
|
||||
|
||||
#include "interfaces/arch_registers.h"
|
||||
#include "kernel/stage_2_boot.h"
|
||||
#include "core/interrupts.h" //For the unexpected interrupt call
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Called by Reset_Handler, performs initialization and calls main.
|
||||
* Never returns.
|
||||
*/
|
||||
void program_startup() __attribute__((noreturn));
|
||||
void program_startup()
|
||||
{
|
||||
//Cortex M3 core appears to get out of reset with interrupts already enabled
|
||||
__disable_irq();
|
||||
|
||||
//SystemInit() is called *before* initializing .data and zeroing .bss
|
||||
//Despite all startup files provided by ST do the opposite, there are three
|
||||
//good reasons to do so:
|
||||
//First, the CMSIS specifications say that SystemInit() must not access
|
||||
//global variables, so it is actually possible to call it before
|
||||
//Second, when running Miosix with the xram linker scripts .data and .bss
|
||||
//are placed in the external RAM, so we *must* call SystemInit(), which
|
||||
//enables xram, before touching .data and .bss
|
||||
//Third, this is a performance improvement since the loops that initialize
|
||||
//.data and zeros .bss now run with the CPU at full speed instead of 8MHz
|
||||
SystemInit();
|
||||
|
||||
//These are defined in the linker script
|
||||
extern unsigned char _etext asm("_etext");
|
||||
extern unsigned char _data asm("_data");
|
||||
extern unsigned char _edata asm("_edata");
|
||||
extern unsigned char _bss_start asm("_bss_start");
|
||||
extern unsigned char _bss_end asm("_bss_end");
|
||||
|
||||
//Initialize .data section, clear .bss section
|
||||
unsigned char *etext=&_etext;
|
||||
unsigned char *data=&_data;
|
||||
unsigned char *edata=&_edata;
|
||||
unsigned char *bss_start=&_bss_start;
|
||||
unsigned char *bss_end=&_bss_end;
|
||||
memcpy(data, etext, edata-data);
|
||||
memset(bss_start, 0, bss_end-bss_start);
|
||||
|
||||
//Move on to stage 2
|
||||
_init();
|
||||
|
||||
//If main returns, reboot
|
||||
NVIC_SystemReset();
|
||||
for(;;) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset handler, called by hardware immediately after reset
|
||||
*/
|
||||
void Reset_Handler() __attribute__((__interrupt__, noreturn));
|
||||
void Reset_Handler()
|
||||
{
|
||||
/*
|
||||
* Initialize process stack and switch to it.
|
||||
* This is required for booting Miosix, a small portion of the top of the
|
||||
* heap area will be used as stack until the first thread starts. After,
|
||||
* this stack will be abandoned and the process stack will point to the
|
||||
* current thread's stack.
|
||||
*/
|
||||
asm volatile("ldr r0, =_heap_end \n\t"
|
||||
"msr psp, r0 \n\t"
|
||||
"movw r0, #2 \n\n" //Privileged, process stack
|
||||
"msr control, r0 \n\t"
|
||||
"isb \n\t":::"r0");
|
||||
|
||||
program_startup();
|
||||
}
|
||||
|
||||
/**
|
||||
* All unused interrupts call this function.
|
||||
*/
|
||||
extern "C" void Default_Handler()
|
||||
{
|
||||
unexpectedInterrupt();
|
||||
}
|
||||
|
||||
//System handlers
|
||||
void /*__attribute__((weak))*/ Reset_Handler(); //These interrupts are not
|
||||
void /*__attribute__((weak))*/ NMI_Handler(); //weak because they are
|
||||
void /*__attribute__((weak))*/ HardFault_Handler(); //surely defined by Miosix
|
||||
void /*__attribute__((weak))*/ MemManage_Handler();
|
||||
void /*__attribute__((weak))*/ BusFault_Handler();
|
||||
void /*__attribute__((weak))*/ UsageFault_Handler();
|
||||
void /*__attribute__((weak))*/ SVC_Handler();
|
||||
void /*__attribute__((weak))*/ DebugMon_Handler();
|
||||
void /*__attribute__((weak))*/ PendSV_Handler();
|
||||
void /*__attribute__((weak))*/ SysTick_Handler();
|
||||
|
||||
//Interrupt handlers
|
||||
void __attribute__((weak)) WWDG_IRQHandler();
|
||||
void __attribute__((weak)) PVD_IRQHandler();
|
||||
void __attribute__((weak)) TAMP_STAMP_IRQHandler();
|
||||
void __attribute__((weak)) RTC_WKUP_IRQHandler();
|
||||
void __attribute__((weak)) FLASH_IRQHandler();
|
||||
void __attribute__((weak)) RCC_IRQHandler();
|
||||
void __attribute__((weak)) EXTI0_IRQHandler();
|
||||
void __attribute__((weak)) EXTI1_IRQHandler();
|
||||
void __attribute__((weak)) EXTI2_IRQHandler();
|
||||
void __attribute__((weak)) EXTI3_IRQHandler();
|
||||
void __attribute__((weak)) EXTI4_IRQHandler();
|
||||
void __attribute__((weak)) DMA1_Stream0_IRQHandler();
|
||||
void __attribute__((weak)) DMA1_Stream1_IRQHandler();
|
||||
void __attribute__((weak)) DMA1_Stream2_IRQHandler();
|
||||
void __attribute__((weak)) DMA1_Stream3_IRQHandler();
|
||||
void __attribute__((weak)) DMA1_Stream4_IRQHandler();
|
||||
void __attribute__((weak)) DMA1_Stream5_IRQHandler();
|
||||
void __attribute__((weak)) DMA1_Stream6_IRQHandler();
|
||||
void __attribute__((weak)) ADC_IRQHandler();
|
||||
void __attribute__((weak)) EXTI9_5_IRQHandler();
|
||||
void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler();
|
||||
void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler();
|
||||
void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler();
|
||||
void __attribute__((weak)) TIM1_CC_IRQHandler();
|
||||
void __attribute__((weak)) TIM2_IRQHandler();
|
||||
void __attribute__((weak)) TIM3_IRQHandler();
|
||||
void __attribute__((weak)) TIM4_IRQHandler();
|
||||
void __attribute__((weak)) I2C1_EV_IRQHandler();
|
||||
void __attribute__((weak)) I2C1_ER_IRQHandler();
|
||||
void __attribute__((weak)) I2C2_EV_IRQHandler();
|
||||
void __attribute__((weak)) I2C2_ER_IRQHandler();
|
||||
void __attribute__((weak)) SPI1_IRQHandler();
|
||||
void __attribute__((weak)) SPI2_IRQHandler();
|
||||
void __attribute__((weak)) USART1_IRQHandler();
|
||||
void __attribute__((weak)) USART2_IRQHandler();
|
||||
void __attribute__((weak)) EXTI15_10_IRQHandler();
|
||||
void __attribute__((weak)) RTC_Alarm_IRQHandler();
|
||||
void __attribute__((weak)) OTG_FS_WKUP_IRQHandler();
|
||||
void __attribute__((weak)) DMA1_Stream7_IRQHandler();
|
||||
void __attribute__((weak)) SDIO_IRQHandler();
|
||||
void __attribute__((weak)) TIM5_IRQHandler();
|
||||
void __attribute__((weak)) SPI3_IRQHandler();
|
||||
void __attribute__((weak)) DMA2_Stream0_IRQHandler();
|
||||
void __attribute__((weak)) DMA2_Stream1_IRQHandler();
|
||||
void __attribute__((weak)) DMA2_Stream2_IRQHandler();
|
||||
void __attribute__((weak)) DMA2_Stream3_IRQHandler();
|
||||
void __attribute__((weak)) DMA2_Stream4_IRQHandler();
|
||||
void __attribute__((weak)) OTG_FS_IRQHandler();
|
||||
void __attribute__((weak)) DMA2_Stream5_IRQHandler();
|
||||
void __attribute__((weak)) DMA2_Stream6_IRQHandler();
|
||||
void __attribute__((weak)) DMA2_Stream7_IRQHandler();
|
||||
void __attribute__((weak)) USART6_IRQHandler();
|
||||
void __attribute__((weak)) I2C3_EV_IRQHandler();
|
||||
void __attribute__((weak)) I2C3_ER_IRQHandler();
|
||||
void __attribute__((weak)) FPU_IRQHandler();
|
||||
void __attribute__((weak)) SPI4_IRQHandler();
|
||||
|
||||
//Stack top, defined in the linker script
|
||||
extern char _main_stack_top asm("_main_stack_top");
|
||||
|
||||
//Interrupt vectors, must be placed @ address 0x00000000
|
||||
//The extern declaration is required otherwise g++ optimizes it out
|
||||
extern void (* const __Vectors[])();
|
||||
void (* const __Vectors[])() __attribute__ ((section(".isr_vector"))) =
|
||||
{
|
||||
reinterpret_cast<void (*)()>(&_main_stack_top),/* Stack pointer*/
|
||||
Reset_Handler, /* Reset Handler */
|
||||
NMI_Handler, /* NMI Handler */
|
||||
HardFault_Handler, /* Hard Fault Handler */
|
||||
MemManage_Handler, /* MPU Fault Handler */
|
||||
BusFault_Handler, /* Bus Fault Handler */
|
||||
UsageFault_Handler, /* Usage Fault Handler */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
SVC_Handler, /* SVCall Handler */
|
||||
DebugMon_Handler, /* Debug Monitor Handler */
|
||||
0, /* Reserved */
|
||||
PendSV_Handler, /* PendSV Handler */
|
||||
SysTick_Handler, /* SysTick Handler */
|
||||
|
||||
/* External Interrupts */
|
||||
WWDG_IRQHandler,
|
||||
PVD_IRQHandler,
|
||||
TAMP_STAMP_IRQHandler,
|
||||
RTC_WKUP_IRQHandler,
|
||||
FLASH_IRQHandler,
|
||||
RCC_IRQHandler,
|
||||
EXTI0_IRQHandler,
|
||||
EXTI1_IRQHandler,
|
||||
EXTI2_IRQHandler,
|
||||
EXTI3_IRQHandler,
|
||||
EXTI4_IRQHandler,
|
||||
DMA1_Stream0_IRQHandler,
|
||||
DMA1_Stream1_IRQHandler,
|
||||
DMA1_Stream2_IRQHandler,
|
||||
DMA1_Stream3_IRQHandler,
|
||||
DMA1_Stream4_IRQHandler,
|
||||
DMA1_Stream5_IRQHandler,
|
||||
DMA1_Stream6_IRQHandler,
|
||||
ADC_IRQHandler,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
EXTI9_5_IRQHandler,
|
||||
TIM1_BRK_TIM9_IRQHandler,
|
||||
TIM1_UP_TIM10_IRQHandler,
|
||||
TIM1_TRG_COM_TIM11_IRQHandler,
|
||||
TIM1_CC_IRQHandler,
|
||||
TIM2_IRQHandler,
|
||||
TIM3_IRQHandler,
|
||||
TIM4_IRQHandler,
|
||||
I2C1_EV_IRQHandler,
|
||||
I2C1_ER_IRQHandler,
|
||||
I2C2_EV_IRQHandler,
|
||||
I2C2_ER_IRQHandler,
|
||||
SPI1_IRQHandler,
|
||||
SPI2_IRQHandler,
|
||||
USART1_IRQHandler,
|
||||
USART2_IRQHandler,
|
||||
0,
|
||||
EXTI15_10_IRQHandler,
|
||||
RTC_Alarm_IRQHandler,
|
||||
OTG_FS_WKUP_IRQHandler,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
DMA1_Stream7_IRQHandler,
|
||||
0,
|
||||
SDIO_IRQHandler,
|
||||
TIM5_IRQHandler,
|
||||
SPI3_IRQHandler,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
DMA2_Stream0_IRQHandler,
|
||||
DMA2_Stream1_IRQHandler,
|
||||
DMA2_Stream2_IRQHandler,
|
||||
DMA2_Stream3_IRQHandler,
|
||||
DMA2_Stream4_IRQHandler,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
OTG_FS_IRQHandler,
|
||||
DMA2_Stream5_IRQHandler,
|
||||
DMA2_Stream6_IRQHandler,
|
||||
DMA2_Stream7_IRQHandler,
|
||||
USART6_IRQHandler,
|
||||
I2C3_EV_IRQHandler,
|
||||
I2C3_ER_IRQHandler,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
FPU_IRQHandler,
|
||||
0,
|
||||
0,
|
||||
SPI4_IRQHandler
|
||||
};
|
||||
|
||||
#pragma weak WWDG_IRQHandler = Default_Handler
|
||||
#pragma weak PVD_IRQHandler = Default_Handler
|
||||
#pragma weak TAMP_STAMP_IRQHandler = Default_Handler
|
||||
#pragma weak RTC_WKUP_IRQHandler = Default_Handler
|
||||
#pragma weak FLASH_IRQHandler = Default_Handler
|
||||
#pragma weak RCC_IRQHandler = Default_Handler
|
||||
#pragma weak EXTI0_IRQHandler = Default_Handler
|
||||
#pragma weak EXTI1_IRQHandler = Default_Handler
|
||||
#pragma weak EXTI2_IRQHandler = Default_Handler
|
||||
#pragma weak EXTI3_IRQHandler = Default_Handler
|
||||
#pragma weak EXTI4_IRQHandler = Default_Handler
|
||||
#pragma weak DMA1_Stream0_IRQHandler = Default_Handler
|
||||
#pragma weak DMA1_Stream1_IRQHandler = Default_Handler
|
||||
#pragma weak DMA1_Stream2_IRQHandler = Default_Handler
|
||||
#pragma weak DMA1_Stream3_IRQHandler = Default_Handler
|
||||
#pragma weak DMA1_Stream4_IRQHandler = Default_Handler
|
||||
#pragma weak DMA1_Stream5_IRQHandler = Default_Handler
|
||||
#pragma weak DMA1_Stream6_IRQHandler = Default_Handler
|
||||
#pragma weak ADC_IRQHandler = Default_Handler
|
||||
#pragma weak EXTI9_5_IRQHandler = Default_Handler
|
||||
#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler
|
||||
#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler
|
||||
#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler
|
||||
#pragma weak TIM1_CC_IRQHandler = Default_Handler
|
||||
#pragma weak TIM2_IRQHandler = Default_Handler
|
||||
#pragma weak TIM3_IRQHandler = Default_Handler
|
||||
#pragma weak TIM4_IRQHandler = Default_Handler
|
||||
#pragma weak I2C1_EV_IRQHandler = Default_Handler
|
||||
#pragma weak I2C1_ER_IRQHandler = Default_Handler
|
||||
#pragma weak I2C2_EV_IRQHandler = Default_Handler
|
||||
#pragma weak I2C2_ER_IRQHandler = Default_Handler
|
||||
#pragma weak SPI1_IRQHandler = Default_Handler
|
||||
#pragma weak SPI2_IRQHandler = Default_Handler
|
||||
#pragma weak USART1_IRQHandler = Default_Handler
|
||||
#pragma weak USART2_IRQHandler = Default_Handler
|
||||
#pragma weak EXTI15_10_IRQHandler = Default_Handler
|
||||
#pragma weak RTC_Alarm_IRQHandler = Default_Handler
|
||||
#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler
|
||||
#pragma weak DMA1_Stream7_IRQHandler = Default_Handler
|
||||
#pragma weak SDIO_IRQHandler = Default_Handler
|
||||
#pragma weak TIM5_IRQHandler = Default_Handler
|
||||
#pragma weak SPI3_IRQHandler = Default_Handler
|
||||
#pragma weak DMA2_Stream0_IRQHandler = Default_Handler
|
||||
#pragma weak DMA2_Stream1_IRQHandler = Default_Handler
|
||||
#pragma weak DMA2_Stream2_IRQHandler = Default_Handler
|
||||
#pragma weak DMA2_Stream3_IRQHandler = Default_Handler
|
||||
#pragma weak DMA2_Stream4_IRQHandler = Default_Handler
|
||||
#pragma weak OTG_FS_IRQHandler = Default_Handler
|
||||
#pragma weak DMA2_Stream5_IRQHandler = Default_Handler
|
||||
#pragma weak DMA2_Stream6_IRQHandler = Default_Handler
|
||||
#pragma weak DMA2_Stream7_IRQHandler = Default_Handler
|
||||
#pragma weak USART6_IRQHandler = Default_Handler
|
||||
#pragma weak I2C3_EV_IRQHandler = Default_Handler
|
||||
#pragma weak I2C3_ER_IRQHandler = Default_Handler
|
||||
#pragma weak FPU_IRQHandler = Default_Handler
|
||||
#pragma weak SPI4_IRQHandler = Default_Handler
|
|
@ -43,6 +43,14 @@ void delayUs(unsigned int useconds)
|
|||
" itt lo \n"
|
||||
" addlo r1, r1, #1 \n"
|
||||
" blo ___loop_u \n"::"r"(useconds):"r1","r2");
|
||||
#elif defined(SYSCLK_FREQ_84MHz)
|
||||
asm volatile(" mov r1, #21 \n"
|
||||
" mul r2, %0, r1 \n"
|
||||
" mov r1, #0 \n"
|
||||
"___loop_u: cmp r1, r2 \n"
|
||||
" itt lo \n"
|
||||
" addlo r1, r1, #1 \n"
|
||||
" blo ___loop_u \n"::"r"(useconds):"r1","r2");
|
||||
#else
|
||||
#error delayUs() is not calibrated for this frequency
|
||||
#endif
|
||||
|
@ -54,6 +62,8 @@ void delayMs(unsigned int mseconds)
|
|||
register const unsigned int count=45000;
|
||||
#elif defined(SYSCLK_FREQ_168MHz)
|
||||
register const unsigned int count=42000;
|
||||
#elif defined(SYSCLK_FREQ_84MHz)
|
||||
register const unsigned int count=21000;
|
||||
#else
|
||||
#error delayMs() is not calibrated for this frequency
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* C++ enabled linker script for stm32 (256K FLASH, 64K RAM)
|
||||
* Developed by TFT: Terraneo Federico Technologies
|
||||
* Optimized for use with the Miosix kernel
|
||||
*/
|
||||
|
||||
/*
|
||||
* The main stack is used for interrupt handling by the kernel.
|
||||
*
|
||||
* *** Readme ***
|
||||
* This linker script places the main stack (used by the kernel for interrupts)
|
||||
* at the bottom of the ram, instead of the top. This is done for two reasons:
|
||||
*
|
||||
* - as an optimization for microcontrollers with little ram memory. In fact
|
||||
* the implementation of malloc from newlib requests memory to the OS in 4KB
|
||||
* block (except the first block that can be smaller). This is probably done
|
||||
* for compatibility with OSes with an MMU and paged memory. To see why this
|
||||
* is bad, consider a microcontroller with 8KB of ram: when malloc finishes
|
||||
* up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will
|
||||
* fail because the top part of the ram is used by the main stack. As a
|
||||
* result, the top part of the memory will not be used by malloc, even if
|
||||
* available (and it is nearly *half* the ram on an 8KB mcu). By placing the
|
||||
* main stack at the bottom of the ram, the upper 4KB block will be entirely
|
||||
* free and available as heap space.
|
||||
*
|
||||
* - In case of main stack overflow the cpu will fault because access to memory
|
||||
* before the beginning of the ram faults. Instead with the default stack
|
||||
* placement the main stack will silently collide with the heap.
|
||||
* Note: if increasing the main stack size also increase the ORIGIN value in
|
||||
* the MEMORY definitions below accordingly.
|
||||
*/
|
||||
_main_stack_size = 0x00000200; /* main stack = 512Bytes */
|
||||
_main_stack_top = 0x20000000 + _main_stack_size;
|
||||
ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error");
|
||||
|
||||
_heap_end = 0x20010000; /* end of available ram */
|
||||
|
||||
/* identify the Entry Point */
|
||||
ENTRY(_Z13Reset_Handlerv)
|
||||
|
||||
/* specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
flash(rx) : ORIGIN = 0x08000000, LENGTH = 256K
|
||||
/*
|
||||
* Note, the ram starts at 0x20000000 but it is necessary to add the size of
|
||||
* the main stack, so it is 0x20000200.
|
||||
*/
|
||||
ram(wx) : ORIGIN = 0x20000200, LENGTH = 64K-0x200
|
||||
}
|
||||
|
||||
/* now define the output sections */
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
|
||||
/* .text section: code goes to flash */
|
||||
.text :
|
||||
{
|
||||
/* Startup code must go at address 0 */
|
||||
KEEP(*(.isr_vector))
|
||||
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
/* these sections for thumb interwork? */
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
/* these sections for C++? */
|
||||
*(.gcc_except_table)
|
||||
*(.gcc_except_table.*)
|
||||
*(.ARM.extab*)
|
||||
*(.gnu.linkonce.armextab.*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* .rodata: constant data */
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
|
||||
/* C++ Static constructors/destructors (eabi) */
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.init))
|
||||
|
||||
. = ALIGN(4);
|
||||
__miosix_init_array_start = .;
|
||||
KEEP (*(SORT(.miosix_init_array.*)))
|
||||
KEEP (*(.miosix_init_array))
|
||||
__miosix_init_array_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
__fini_array_start = .;
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
__fini_array_end = .;
|
||||
|
||||
/* C++ Static constructors/destructors (elf) */
|
||||
. = ALIGN(4);
|
||||
_ctor_start = .;
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
_ctor_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
} > flash
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} > flash
|
||||
__exidx_end = .;
|
||||
|
||||
/* .data section: global variables go to ram, but also store a copy to
|
||||
flash to initialize them */
|
||||
.data : ALIGN(8)
|
||||
{
|
||||
_data = .;
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
. = ALIGN(8);
|
||||
_edata = .;
|
||||
} > ram AT > flash
|
||||
_etext = LOADADDR(.data);
|
||||
|
||||
/* .bss section: uninitialized global variables go to ram */
|
||||
_bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
. = ALIGN(8);
|
||||
} > ram
|
||||
_bss_end = .;
|
||||
|
||||
_end = .;
|
||||
PROVIDE(end = .);
|
||||
}
|
Ładowanie…
Reference in New Issue