335 lines
11 KiB
ArmAsm
335 lines
11 KiB
ArmAsm
/* File: startup_ARMCM0.S
|
|
* Purpose: startup file for Cortex-M0 devices. Should use with
|
|
* GCC for ARM Embedded Processors
|
|
* Version: V2.0
|
|
* Date: 16 August 2013
|
|
*
|
|
/* Copyright (c) 2011 - 2013 ARM LIMITED
|
|
|
|
All rights reserved.
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
- Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
- Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
- Neither the name of ARM nor the names of its contributors may be used
|
|
to endorse or promote products derived from this software without
|
|
specific prior written permission.
|
|
*
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
---------------------------------------------------------------------------*/
|
|
.syntax unified
|
|
.arch armv6-m
|
|
|
|
.section .stack
|
|
.align 3
|
|
#ifdef __STACK_SIZE
|
|
.equ Stack_Size, __STACK_SIZE
|
|
#else
|
|
.equ Stack_Size, 0xc00
|
|
#endif
|
|
.globl __StackTop
|
|
.globl __StackLimit
|
|
__StackLimit:
|
|
.space Stack_Size
|
|
.size __StackLimit, . - __StackLimit
|
|
__StackTop:
|
|
.size __StackTop, . - __StackTop
|
|
|
|
.section .heap
|
|
.align 3
|
|
#ifdef __HEAP_SIZE
|
|
.equ Heap_Size, __HEAP_SIZE
|
|
#else
|
|
.equ Heap_Size, 0
|
|
#endif
|
|
.globl __HeapBase
|
|
.globl __HeapLimit
|
|
__HeapBase:
|
|
.if Heap_Size
|
|
.space Heap_Size
|
|
.endif
|
|
.size __HeapBase, . - __HeapBase
|
|
__HeapLimit:
|
|
.size __HeapLimit, . - __HeapLimit
|
|
|
|
.section .isr_vector
|
|
.align 2
|
|
.globl __isr_vector
|
|
__isr_vector:
|
|
.long __StackTop /* Top of Stack */
|
|
.long Reset_Handler /* Reset Handler */
|
|
.long NMI_Handler /* NMI Handler */
|
|
.long HardFault_Handler /* Hard Fault Handler */
|
|
.long 0 /* Reserved */
|
|
.long 0 /* Reserved */
|
|
.long 0 /* Reserved */
|
|
.long 0 /* Reserved */
|
|
.long 0 /* Reserved */
|
|
.long 0 /* Reserved */
|
|
.long 0 /* Reserved */
|
|
.long SVC_Handler /* SVCall Handler */
|
|
.long 0 /* Reserved */
|
|
.long 0 /* Reserved */
|
|
.long PendSV_Handler /* PendSV Handler */
|
|
.long SysTick_Handler /* SysTick Handler */
|
|
|
|
/* External interrupts */
|
|
.long WWDG_IRQHandler /* Window Watchdog */
|
|
.long PVD_VDDIO2_IRQHandler /* PVD through EXTI Line detect */
|
|
.long RTC_IRQHand /* RTC through EXTI Line */
|
|
.long FLASH_IRQHandler /* FLASH */
|
|
.long RCC_CRS_IRQHandler /* RCC and CRS */
|
|
.long EXTI0_1_IRQHandler /* EXTI Line 0 and 1 */
|
|
.long EXTI2_3_IRQHandler /* EXTI Line 2 and 3 */
|
|
.long EXTI4_15_IRQHandler /* EXTI Line 4 to 15 */
|
|
.long TSC_IRQHandler /* TS */
|
|
.long DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */
|
|
.long DMA1_Channel2_3_IRQHandler /* DMA1 Channel 2 and Channel 3 */
|
|
.long DMA1_Channel4_5_6_7_IRQHandler /* DMA1 Channel 4, Channel 5, Channel 6 and Channel 7 */
|
|
.long ADC1_COMP_IRQHandler /* ADC1, COMP1 and COMP2 */
|
|
.long TIM1_BRK_UP_TRG_COM_IRQHandler /* TIM1 Break, Update, Trigger and Commutation */
|
|
.long TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
|
.long TIM2_IRQHandler /* TIM2 */
|
|
.long TIM3_IRQHandler /* TIM3 */
|
|
.long TIM6_DAC_IRQHandler /* TIM6 and DAC */
|
|
.long TIM7_IRQHandler /* TIM7 */
|
|
.long TIM14_IRQHandler /* TIM14 */
|
|
.long TIM15_IRQHandler /* TIM15 */
|
|
.long TIM16_IRQHandler /* TIM16 */
|
|
.long TIM17_IRQHandler /* TIM17 */
|
|
.long I2C1_IRQHandler /* I2C1 */
|
|
.long I2C2_IRQHandler /* I2C2 */
|
|
.long SPI1_IRQHandler /* SPI1 */
|
|
.long SPI2_IRQHandler /* SPI2 */
|
|
.long USART1_IRQHandler /* USART1 */
|
|
.long USART2_IRQHandler /* USART2 */
|
|
.long USART3_4_IRQHandler /* USART3 & USART4 */
|
|
.long CEC_CAN_IRQHandler /* CEC and CAN */
|
|
.long USB_IRQHandler /* USB */
|
|
|
|
.size __isr_vector, . - __isr_vector
|
|
|
|
//;.text
|
|
//;want to move this to a fixed flash location so the lower
|
|
//;vector/usb section of flash doesn't need to be updated for
|
|
//;main/application firmware updates.
|
|
//;want the reset handler to always reside @ 0x08000800
|
|
.section .reset_handler
|
|
.thumb
|
|
.thumb_func
|
|
.align 1
|
|
.globl Reset_Handler
|
|
.type Reset_Handler, %function
|
|
Reset_Handler:
|
|
/* Firstly it copies data from read only memory to RAM. There are two schemes
|
|
* to copy. One can copy more than one sections. Another can only copy
|
|
* one section. The former scheme needs more instructions and read-only
|
|
* data to implement than the latter.
|
|
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
|
|
|
|
#ifdef __STARTUP_COPY_MULTIPLE
|
|
/* Multiple sections scheme.
|
|
*
|
|
* Between symbol address __copy_table_start__ and __copy_table_end__,
|
|
* there are array of triplets, each of which specify:
|
|
* offset 0: LMA of start of a section to copy from
|
|
* offset 4: VMA of start of a section to copy to
|
|
* offset 8: size of the section to copy. Must be multiply of 4
|
|
*
|
|
* All addresses must be aligned to 4 bytes boundary.
|
|
*/
|
|
ldr r4, =__copy_table_start__
|
|
ldr r5, =__copy_table_end__
|
|
|
|
.L_loop0:
|
|
cmp r4, r5
|
|
bge .L_loop0_done
|
|
ldr r1, [r4]
|
|
ldr r2, [r4, #4]
|
|
ldr r3, [r4, #8]
|
|
|
|
.L_loop0_0:
|
|
subs r3, #4
|
|
blt .L_loop0_0_done
|
|
ldr r0, [r1, r3]
|
|
str r0, [r2, r3]
|
|
b .L_loop0_0
|
|
|
|
.L_loop0_0_done:
|
|
adds r4, #12
|
|
b .L_loop0
|
|
|
|
.L_loop0_done:
|
|
#else
|
|
/* Single section scheme.
|
|
*
|
|
* The ranges of copy from/to are specified by following symbols
|
|
* __etext: LMA of start of the section to copy from. Usually end of text
|
|
* __data_start__: VMA of start of the section to copy to
|
|
* __data_end__: VMA of end of the section to copy to
|
|
*
|
|
* All addresses must be aligned to 4 bytes boundary.
|
|
*/
|
|
ldr r1, =__etext
|
|
ldr r2, =__data_start__
|
|
ldr r3, =__data_end__
|
|
|
|
subs r3, r2
|
|
ble .L_loop1_done
|
|
|
|
.L_loop1:
|
|
subs r3, #4
|
|
ldr r0, [r1,r3]
|
|
str r0, [r2,r3]
|
|
bgt .L_loop1
|
|
|
|
.L_loop1_done:
|
|
#endif /*__STARTUP_COPY_MULTIPLE */
|
|
|
|
/* This part of work usually is done in C library startup code. Otherwise,
|
|
* define this macro to enable it in this startup.
|
|
*
|
|
* There are two schemes too. One can clear multiple BSS sections. Another
|
|
* can only clear one section. The former is more size expensive than the
|
|
* latter.
|
|
*
|
|
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
|
|
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
|
|
*/
|
|
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
|
|
/* Multiple sections scheme.
|
|
*
|
|
* Between symbol address __copy_table_start__ and __copy_table_end__,
|
|
* there are array of tuples specifying:
|
|
* offset 0: Start of a BSS section
|
|
* offset 4: Size of this BSS section. Must be multiply of 4
|
|
*/
|
|
ldr r3, =__zero_table_start__
|
|
ldr r4, =__zero_table_end__
|
|
|
|
.L_loop2:
|
|
cmp r3, r4
|
|
bge .L_loop2_done
|
|
ldr r1, [r3]
|
|
ldr r2, [r3, #4]
|
|
movs r0, 0
|
|
|
|
.L_loop2_0:
|
|
subs r2, #4
|
|
blt .L_loop2_0_done
|
|
str r0, [r1, r2]
|
|
b .L_loop2_0
|
|
.L_loop2_0_done:
|
|
|
|
adds r3, #8
|
|
b .L_loop2
|
|
.L_loop2_done:
|
|
#elif defined (__STARTUP_CLEAR_BSS)
|
|
/* Single BSS section scheme.
|
|
*
|
|
* The BSS section is specified by following symbols
|
|
* __bss_start__: start of the BSS section.
|
|
* __bss_end__: end of the BSS section.
|
|
*
|
|
* Both addresses must be aligned to 4 bytes boundary.
|
|
*/
|
|
ldr r1, =__bss_start__
|
|
ldr r2, =__bss_end__
|
|
|
|
movs r0, 0
|
|
|
|
subs r2, r1
|
|
ble .L_loop3_done
|
|
|
|
.L_loop3:
|
|
subs r2, #4
|
|
str r0, [r1, r2]
|
|
bgt .L_loop3
|
|
.L_loop3_done:
|
|
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
|
|
|
|
#ifndef __NO_SYSTEM_INIT
|
|
bl SystemInit
|
|
#endif
|
|
|
|
#ifndef __START
|
|
#define __START _start
|
|
#endif
|
|
bl __START
|
|
|
|
.pool
|
|
.size Reset_Handler, . - Reset_Handler
|
|
|
|
|
|
//;want the default handler to be in same space as hardfault
|
|
.section .hardfault
|
|
.align 1
|
|
.thumb_func
|
|
.weak Default_Handler
|
|
.type Default_Handler, %function
|
|
Default_Handler:
|
|
b .
|
|
.size Default_Handler, . - Default_Handler
|
|
|
|
/* Macro to define default handlers. Default handler
|
|
* will be weak symbol and just dead loops. They can be
|
|
* overwritten by other handlers */
|
|
.macro def_irq_handler handler_name
|
|
.weak \handler_name
|
|
.set \handler_name, Default_Handler
|
|
.endm
|
|
|
|
def_irq_handler NMI_Handler
|
|
def_irq_handler HardFault_Handler
|
|
def_irq_handler SVC_Handler
|
|
def_irq_handler PendSV_Handler
|
|
def_irq_handler SysTick_Handler
|
|
def_irq_handler DEF_IRQHandler
|
|
def_irq_handler WWDG_IRQHandler
|
|
def_irq_handler PVD_VDDIO2_IRQHandler
|
|
def_irq_handler RTC_IRQHand
|
|
def_irq_handler FLASH_IRQHandler
|
|
def_irq_handler RCC_CRS_IRQHandler
|
|
def_irq_handler EXTI0_1_IRQHandler
|
|
def_irq_handler EXTI2_3_IRQHandler
|
|
def_irq_handler EXTI4_15_IRQHandler
|
|
def_irq_handler TSC_IRQHandler
|
|
def_irq_handler DMA1_Channel1_IRQHandler
|
|
def_irq_handler DMA1_Channel2_3_IRQHandler
|
|
def_irq_handler DMA1_Channel4_5_6_7_IRQHandler
|
|
def_irq_handler ADC1_COMP_IRQHandler
|
|
def_irq_handler TIM1_BRK_UP_TRG_COM_IRQHandler
|
|
def_irq_handler TIM1_CC_IRQHandler
|
|
def_irq_handler TIM2_IRQHandler
|
|
def_irq_handler TIM3_IRQHandler
|
|
def_irq_handler TIM6_DAC_IRQHandler
|
|
def_irq_handler TIM7_IRQHandler
|
|
def_irq_handler TIM14_IRQHandler
|
|
def_irq_handler TIM15_IRQHandler
|
|
def_irq_handler TIM16_IRQHandler
|
|
def_irq_handler TIM17_IRQHandler
|
|
def_irq_handler I2C1_IRQHandler
|
|
def_irq_handler I2C2_IRQHandler
|
|
def_irq_handler SPI1_IRQHandler
|
|
def_irq_handler SPI2_IRQHandler
|
|
def_irq_handler USART1_IRQHandler
|
|
def_irq_handler USART2_IRQHandler
|
|
def_irq_handler USART3_4_IRQHandler
|
|
def_irq_handler CEC_CAN_IRQHandler
|
|
def_irq_handler USB_IRQHandler
|
|
|
|
.end
|