mirror of https://github.com/ARMmbed/mbed-os.git
Add initial KL25Z startup code and linker script for Code Warrior
parent
498d5efcc4
commit
3f684a518f
|
@ -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();
|
||||
|
|
|
@ -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) }
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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 */
|
||||
};
|
Loading…
Reference in New Issue