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 "semihost_api.h"
|
||||||
#include "mbed_interface.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) {
|
void exit(int return_code) {
|
||||||
|
#endif
|
||||||
|
|
||||||
#if DEVICE_SEMIHOST
|
#if DEVICE_SEMIHOST
|
||||||
if (mbed_interface_connected()) {
|
if (mbed_interface_connected()) {
|
||||||
semihost_exit();
|
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