⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 startup.s

📁 一个开源的Modbus协议栈
💻 S
字号:
/*

 * STR71X/GCC Startup Scripts for FreeModbus



 * Copyright C) 2005 Anglia Design, Spencer Oliver

 * Copyright (C) 2006 Christian Walter <wolti@sil.at>

 *

 * 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 2 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, write to the Free Software

 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 *

 * File: $Id: startup.S,v 1.1 2006/11/02 23:14:44 wolti Exp $

 */



/* ----------------------- Target settings ----------------------------------*/

    .equ    FOSC,           4000000

    .equ    FRTC,           32768



/* ----------------------- ARM7 CPU modes -----------------------------------*/

    .equ    MODE_USR,       0x10

    .equ    MODE_FIQ,       0x11

    .equ    MODE_IRQ,       0x12

    .equ    MODE_SVC,       0x13

    .equ    MODE_ABT,       0x17

    .equ    MODE_UND,       0x1B

    .equ    MODE_SYS,       0x1F          /* available on ARM Arch 4 and later */



    .equ    I_Bit,          0x80          /* when I bit is set, IRQ is disabled */

    .equ    F_Bit,          0x40          /* when F bit is set, FIQ is disabled */



/* ----------------------- System memory locations --------------------------*/

    .equ    EIC_ADDR,       0xFFFFF800    /* EIC base address */

    .equ    EIC_ICF_OFF,    0x00          /* Interrupt Control register offset */

    .equ    EIC_CIPR_OFF,   0x08          /* Current Interrupt Priority Register offset */

    .equ    EIC_IVR_OFF,    0x18          /* Interrupt Vector Register offset */

    .equ    EIC_FIR_OFF,    0x1C          /* Fast Interrupt Register offset */

    .equ    EIC_IER_OFF,    0x20          /* Interrupt Enable Register offset */

    .equ    EIC_IPR_OFF,    0x40          /* Interrupt Pending Bit Register offset */

    .equ    EIC_SIR0_OFF,   0x60          /* Source Interrupt Register 0 */



    .equ    CPM_ADDR,       0xA0000040    /* CPM Base Address */

    .equ    CPM_BC_OFF,     0x10          /* CPM - Boot Configuration Register */

    .equ    CPM_BC_FLASH,   0x0000        /* to remap FLASH at 0x0 */

    .equ    CPM_BC_RAM,     0x0002        /* to remap RAM at 0x0 */

    .equ    CPM_BC_EXTMEM,  0x0003        /* to remap EXTMEM at 0x0 */



/* ----------------------- Startup code -------------------------------------*/

    .text

    .arm

    .section .init, "ax"

    

    .global _start

    .global RCCU_Main_Osc

    .global RCCU_RTC_Osc



/* ----------------------- Exception vectors ( ROM mode with remap ) --------*/

.if ROM_RUN == 1

_vector_reset_rom:

    ldr   pc, =_start_rom

    nop

    nop

    nop

    nop

    nop

    nop

    nop



    /* Copy the final vectors from ROM into RAM and map RAM at address 

     * 0x00000000 */

_start_rom:

    ldr   r1, =_vecstart                  /* r1 = start address from which to copy */

    ldr   r3, =_vecend

    sub   r3, r3, r1                      /* r3 = number of bytes to copy */

    ldr   r0, =_vectext                   /* r0 = start address where to copy */

copy_ram:

    ldr   r2, [r0], #4                    /* Read a word from the source */

    str   r2, [r1], #4                    /* copy the word to destination */

    subs  r3, r3, #4                      /* Decrement number of words to copy */

    bne   copy_ram

        

    ldr   r1, =CPM_ADDR

    ldrh  r2, [r1, #CPM_BC_OFF]           /* Read BOOTCONF Register */

    bic   r2, r2, #0x03                   /* Reset the two LSB bits of BOOTCONF Register */

    orr   r2, r2, #CPM_BC_RAM             /* change the two LSB bits of BOOTCONF Register */

    strh  r2, [r1, #CPM_BC_OFF]           /* Write BOOTCONF Register */

.endif



/* ----------------------- Default reset handler (After remap ) -------------*/

_start:

    ldr   pc, =NextInst

NextInst:

    nop                                   /* Wait for OSC stabilization */

    nop

    nop

    nop

    nop

    nop

    nop

    nop

    nop



    /* Enter Undefined Instruction Mode and set its Stack Pointer */

    msr   cpsr_c, #MODE_UND|I_Bit|F_Bit

    ldr   sp, =__stack_und_end__



    /* Enter Abort Mode and set its Stack Pointer */

    msr   cpsr_c, #MODE_ABT|I_Bit|F_Bit

    ldr   sp, =__stack_abt_end__



    /* Enter IRQ Mode and set its Stack Pointer */

    msr   cpsr_c, #MODE_IRQ|I_Bit|F_Bit

    ldr   sp, =__stack_irq_end__



    /* Enter FIQ Mode and set its Stack Pointer */

    msr   cpsr_c, #MODE_FIQ|I_Bit|F_Bit

    ldr   sp, =__stack_fiq_end__



    /* Enter Supervisor Mode and set its Stack Pointer */

    msr   cpsr_c, #MODE_SVC|I_Bit|F_Bit

    ldr   sp, =__stack_svc_end__



    /* Set User Mode Stack pointer but remain in Supervisor Mode */

    ldr   r1, =__stack_end__

    mov   r2, sp

    stmfd r2!, {r1}

    ldmfd r2, {sp}^



    /* Setup a default Stack Limit (when compiled with "-mapcs-stack-check") */

    ldr   sl, =__bss_end__



/* ----------------------- EIC initialization -------------------------------

/*

 * EIC is initialized with:

 *  - IRQ disabled

 *  - FIQ disabled

 *  - IVR contain the load PC opcode (0xF59FF00)

 *  - Current priority level equal to 0

 *  - All channels are disabled

 *  - All channels priority equal to 0

 *  - All SIR registers contain offset to the related IRQ table entry

 */



eic_init:

    ldr   r3, =EIC_ADDR

    ldr   r4, =0x00000000         

    str   r4, [r3, #EIC_ICF_OFF]          /* Disable FIQ and IRQ */

    str   r4, [r3, #EIC_IER_OFF]          /* Disable all channels interrupts */

    ldr   r4, =0xFFFFFFFF

    str   r4, [r3, #EIC_IPR_OFF]          /* Clear all IRQ pending bits */

    ldr   r4, =0x0C

    str   r4, [r3, #EIC_FIR_OFF]          /* Disable FIQ channels and clear FIQ pending bits */

    ldr   r4, =0x00000000

    str   r4, [r3, #EIC_CIPR_OFF]         /* Reset the current priority register */

    ldr   r4, =0xE59F0000

    str   r4, [r3, #EIC_IVR_OFF]          /* Write the LDR pc,pc,#offset instruction code in IVR[31:16] */

    ldr   r2, =32                         /* 32 Channel to initialize */

    ldr   r0, =T0TIMI_Addr                /* Read the address of the IRQs address table */

    ldr   r1, =0x00000FFF

    and   r0, r0, r1

    ldr   r5, =EIC_SIR0_OFF               /* Read SIR0 address */

    sub   r4, r0, #8                      /* subtract 8 for prefetch */

    ldr   r1, =0xF7E8                     /* add the offset to the 0x00000000 address(IVR address + 7E8 = 0x00000000) */

                                          /* 0xF7E8 used to complete the LDR pc,pc,#offset opcode */

    add   r1, r4, r1                      /* compute the jump offset */

eic_ini:

    mov   r4, r1, LSL #16                 /* Left shift the result */

    str   r4, [r3, r5]                    /* Store the result in SIRx register */

    add   r1, r1, #4                      /* Next IRQ address */

    add   r5, r5, #4                      /* Next SIR */

    subs  r2, r2, #1                      /* Decrement the number of SIR registers to initialize */

    bne   eic_ini                         /* If more then continue */



    /* Relocate .data section (Copy from ROM to RAM) */

.if ROM_RUN == 1

    ldr   r1, =_etext

    ldr   r2, =_data

    ldr   r3, =_edata

_loop_relocate:

    cmp   r2, r3

    ldrlo r0, [r1], #4

    strlo r0, [r2], #4

    blo   _loop_relocate

.endif



    /* Clear .bss section (Zero init) */

    mov   r0, #0

    ldr   r1, =__bss_start__

    ldr   r2, =__bss_end__

_loop_clear_bss:

    cmp   r1, r2

    strlo r0, [r1], #4

    blo   _loop_clear_bss

        

    /* Call C++ constructors */

    ldr   r0, =__ctors_start__

    ldr   r1, =__ctors_end__

ctor_loop:

    cmp   r0, r1

    beq   ctor_end

    ldr   r2, [r0], #4

    stmfd sp!, {r0-r1}

    mov   lr, pc

    mov   pc, r2

    ldmfd sp!, {r0-r1}

    b     ctor_loop

ctor_end:



    /* Need to set up standard file handles */



    /* if we use debug version of str7lib this will call the init function */

    bl    libdebug

libdebug:       



    /* Call main */

    bl    main



    /* Call destructors */

    ldr   r0, =__dtors_start__

    ldr   r1, =__dtors_end__

dtor_loop:

    cmp   r0, r1

    beq   dtor_end

    ldr   r2, [r0], #4

    stmfd sp!, {r0-r1}

    mov   lr, pc

    mov   pc, r2

    ldmfd sp!, {r0-r1}

    b     dtor_loop

dtor_end:



/* Return from main, loop forever. */

exit_loop:

    b     exit_loop

    

/* Fosc values, used by libstr7 */



RCCU_Main_Osc:  .long   FOSC

RCCU_RTC_Osc:   .long   FRTC



    .weak libdebug

    

    .end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -