From 3f684a518f249e3be7c06e7f0804aa68936e34a8 Mon Sep 17 00:00:00 2001 From: Emilio Monti Date: Thu, 11 Apr 2013 17:22:34 +0100 Subject: [PATCH] Add initial KL25Z startup code and linker script for Code Warrior --- libraries/mbed/capi/exit.c | 6 + .../Freescale/cmsis/KL25Z/GCC_CW/MKL25Z4.ld | 197 ++++++++++++++++++ .../cmsis/KL25Z/GCC_CW/startup_MKL25Z4.c | 147 +++++++++++++ 3 files changed, 350 insertions(+) create mode 100644 libraries/mbed/vendor/Freescale/cmsis/KL25Z/GCC_CW/MKL25Z4.ld create mode 100644 libraries/mbed/vendor/Freescale/cmsis/KL25Z/GCC_CW/startup_MKL25Z4.c diff --git a/libraries/mbed/capi/exit.c b/libraries/mbed/capi/exit.c index c2361f21bf..f1f4bc2ca1 100644 --- a/libraries/mbed/capi/exit.c +++ b/libraries/mbed/capi/exit.c @@ -16,7 +16,13 @@ #include "semihost_api.h" #include "mbed_interface.h" +#ifdef TOOLCHAIN_GCC_CW +// TODO: Ideally, we would like to define directly "_ExitProcess" +void mbed_exit(int return_code) { +#else void exit(int return_code) { +#endif + #if DEVICE_SEMIHOST if (mbed_interface_connected()) { semihost_exit(); diff --git a/libraries/mbed/vendor/Freescale/cmsis/KL25Z/GCC_CW/MKL25Z4.ld b/libraries/mbed/vendor/Freescale/cmsis/KL25Z/GCC_CW/MKL25Z4.ld new file mode 100644 index 0000000000..dc26b23e48 --- /dev/null +++ b/libraries/mbed/vendor/Freescale/cmsis/KL25Z/GCC_CW/MKL25Z4.ld @@ -0,0 +1,197 @@ +/* +***************************************************************************** +** +** File : KL25Z128M4_flash.ld +** +** Default linker command file for Flash targets +** +***************************************************************************** +*/ +/* Entry Point */ +ENTRY(__thumb_startup) + +/* Highest address of the user mode stack */ +_estack = 0x20003000; /* end of SRAM */ +__SP_INIT = _estack; + +/* Generate a link error if heap and stack don't fit into RAM */ +__heap_size = 0x400; /* required amount of heap */ +__stack_size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ + m_interrupts (rx) : ORIGIN = 0x00000000, LENGTH = 0xC0 + m_cfmprotrom (rx) : ORIGIN = 0x00000400, LENGTH = 0x10 + m_text (rx) : ORIGIN = 0x00000800, LENGTH = 128K - 0x800 + m_data (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K /* SRAM */ +} + + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into Flash */ + .interrupts : + { + __vector_table = .; + . = ALIGN(4); + KEEP(*(.vectortable)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + .cfmprotect : + { + . = ALIGN(4); + KEEP(*(.cfmconfig)) /* Flash Configuration Field (FCF) */ + . = ALIGN(4); + } > m_cfmprotrom + + /* The program code and other data goes into Flash */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } > m_text + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > m_text + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + + ___ROM_AT = .; + } > m_text + + /* reserve MTB memory at the beginning of m_data */ + .mtb : /* MTB buffer address as defined by the hardware */ + { + . = ALIGN(8); + _mtb_start = .; + KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */ + . = ALIGN(8); + _mtb_end = .; + } > m_data + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : AT(___ROM_AT) + { + . = ALIGN(4); + __sinit__ = .; + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } > m_data + + ___data_size = _edata - _sdata; + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + __START_BSS = .; + PROVIDE ( __bss_start__ = __START_BSS ); + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + __END_BSS = .; + PROVIDE ( __bss_end__ = __END_BSS ); + } > m_data + + _romp_at = ___ROM_AT + SIZEOF(.data); + .romp : AT(_romp_at) + { + __S_romp = _romp_at; + LONG(___ROM_AT); + LONG(_sdata); + LONG(___data_size); + LONG(0); + LONG(0); + LONG(0); + } > m_data + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + __heap_addr = .; + . = . + __heap_size; + . = . + __stack_size; + . = ALIGN(4); + } > m_data + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/libraries/mbed/vendor/Freescale/cmsis/KL25Z/GCC_CW/startup_MKL25Z4.c b/libraries/mbed/vendor/Freescale/cmsis/KL25Z/GCC_CW/startup_MKL25Z4.c new file mode 100644 index 0000000000..49a3a37359 --- /dev/null +++ b/libraries/mbed/vendor/Freescale/cmsis/KL25Z/GCC_CW/startup_MKL25Z4.c @@ -0,0 +1,147 @@ +#include +#include + +#include "cmsis.h" + +// Linker Script +extern unsigned long _estack; +extern char __S_romp[]; + +extern char __START_BSS[]; +extern char __END_BSS[]; + +// CRT0 +extern void __init_registers(); +extern void __copy_rom_sections_to_ram(void); +extern void __call_static_initializers(void); +extern void __init_user(); + +// User/mbed Defined +extern int main(); +extern void mbed_exit(int return_code); + +void _ExitProcess(int return_code) { + mbed_exit(return_code); +} + +void __thumb_startup(void) { + // Setup registers + __init_registers(); + + // Disable the Watchdog because it may reset the core before entering main(). + SIM->COPC = 0x0; + + // zero-fill the .bss section + memset(__START_BSS, 0, (__END_BSS - __START_BSS)); + + if (__S_romp != 0L) + __copy_rom_sections_to_ram(); + + // call C++ static initializers + __call_static_initializers(); + + // initializations before main, user specific + __init_user(); + + exit(main()); + + // should never get here + while (1); +} + +void Default_Handler() { + __asm("bkpt"); +} + +/* Weak definitions of handlers point to Default_Handler if not implemented */ +void NMI_Handler() __attribute__ ((weak, alias("Default_Handler"))); +void HardFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); +void SVC_Handler() __attribute__ ((weak, alias("Default_Handler"))); +void PendSV_Handler() __attribute__ ((weak, alias("Default_Handler"))); +void SysTick_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void DMA1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void DMA2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void DMA3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void MCM_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void FTFL_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void PMC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void LLW_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void I2C0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void I2C1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void SPI0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void SPI1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void UART0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void UART1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void UART2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void ADC0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void CMP0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void FTM0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void FTM1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void FTM2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void RTC_Alarm_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void RTC_Seconds_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void PIT_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void USBOTG_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void DAC0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void TSI0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void MCG_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void LPTimer_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void PORTA_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); +void PORTD_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +/* The Interrupt Vector Table */ +void (* const InterruptVector[])() __attribute__ ((section(".vectortable"))) = { + /* Processor exceptions */ + (void(*)(void)) &_estack, + __thumb_startup, + NMI_Handler, + HardFault_Handler, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + SVC_Handler, + 0, + 0, + PendSV_Handler, + SysTick_Handler, + + /* Interrupts */ + DMA0_IRQHandler, /* DMA Channel 0 Transfer Complete and Error */ + DMA1_IRQHandler, /* DMA Channel 1 Transfer Complete and Error */ + DMA2_IRQHandler, /* DMA Channel 2 Transfer Complete and Error */ + DMA3_IRQHandler, /* DMA Channel 3 Transfer Complete and Error */ + MCM_IRQHandler, /* Normal Interrupt */ + FTFL_IRQHandler, /* FTFL Interrupt */ + PMC_IRQHandler, /* PMC Interrupt */ + LLW_IRQHandler, /* Low Leakage Wake-up */ + I2C0_IRQHandler, /* I2C0 interrupt */ + I2C1_IRQHandler, /* I2C1 interrupt */ + SPI0_IRQHandler, /* SPI0 Interrupt */ + SPI1_IRQHandler, /* SPI1 Interrupt */ + UART0_IRQHandler, /* UART0 Status and Error interrupt */ + UART1_IRQHandler, /* UART1 Status and Error interrupt */ + UART2_IRQHandler, /* UART2 Status and Error interrupt */ + ADC0_IRQHandler, /* ADC0 interrupt */ + CMP0_IRQHandler, /* CMP0 interrupt */ + FTM0_IRQHandler, /* FTM0 fault, overflow and channels interrupt */ + FTM1_IRQHandler, /* FTM1 fault, overflow and channels interrupt */ + FTM2_IRQHandler, /* FTM2 fault, overflow and channels interrupt */ + RTC_Alarm_IRQHandler, /* RTC Alarm interrupt */ + RTC_Seconds_IRQHandler, /* RTC Seconds interrupt */ + PIT_IRQHandler, /* PIT timer all channels interrupt */ + Default_Handler, /* Reserved interrupt 39/23 */ + USBOTG_IRQHandler, /* USB interrupt */ + DAC0_IRQHandler, /* DAC0 interrupt */ + TSI0_IRQHandler, /* TSI0 Interrupt */ + MCG_IRQHandler, /* MCG Interrupt */ + LPTimer_IRQHandler, /* LPTimer interrupt */ + Default_Handler, /* Reserved interrupt 45/29 */ + PORTA_IRQHandler, /* Port A interrupt */ + PORTD_IRQHandler /* Port D interrupt */ +};