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

📄 at91_cstartup.s79

📁 四个独立按键的程序
💻 S79
字号:
;-----------------------------------------------------------------------------
; This file contains the startup code used by the ICCARM C compiler.
;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbols ?cstartup etc.
; If this entire file is assembled and linked with the provided
; libraries, the XLINK option -C must be used to avoid a clash with 
; PROGRAM module ?RESET.
; EWARM also has a check box to "Ignore CSTARTUP in library", that has
; the same effect.
;
; All code in the modules (except ?RESET) will be placed in the ICODE segment,
; that must be reachable by a B instruction in ARM mode from segment INTVEC
; (within the first 32 Mbytes).
;
; Define preprocessor symbol __THUMB_LIBRARY__ for Thumb libraries
; or __ARM_LIBRARIES__ for ARM libraries.
;
; Based on cstartup.s79 1.37.
; $Revision: 1.5 $
;
;-----------------------------------------------------------------------------

#include "config.h"

;  Make sure that __ARM_LIBRARY__ or __THUMB_LIBRARY__ is defined

#ifdef __ARM_LIBRARY__
#ifdef __THUMB_LIBRARY__
#error "Cannot have both __ARM_LIBRARY__ and __THUMB_LIBRARY__ set!"
#endif
#else
#ifndef __THUMB_LIBRARY__
#error "Must have one of  __ARM_LIBRARY__ or __THUMB_LIBRARY__ set!"
#endif
#endif
	
;
; Naming covention of labels in this file:
;
;  ?xxx	  - External labels only accessed from assembler.
;  __xxx  - External labels accessed from or defined in C.
;  xxx	  - Labels local to one module (note: this file contains 
;           several modules).
;  main	  - The starting point of the user program.
;

;---------------------------------------------------------------
; Macros and definitions for the whole file
;---------------------------------------------------------------

; Mode, correspords to bits 0-5 in CPSR
MODE_BITS	DEFINE	0x1F		; Bit mask for mode bits in CPSR
USR_MODE	DEFINE	0x10		; User mode
FIQ_MODE	DEFINE	0x11		; Fast Interrupt Request mode
IRQ_MODE	DEFINE	0x12		; Interrupt Request mode
SVC_MODE	DEFINE	0x13		; Supervisor mode
ABT_MODE	DEFINE	0x17		; Abort mode
UND_MODE	DEFINE	0x1B		; Undefined Instruction mode
SYS_MODE	DEFINE	0x1F		; System mode

#if __LITTLE_ENDIAN__==1
; RTMODEL attribute __endian

#define ENDIAN_MODE	"little"

#else
#define ENDIAN_MODE	"big"
#endif


#ifdef __THUMB_LIBRARY__

; RTMODEL attribute __cpu_mode
#define CPU_MODE_NAME	"thumb"
; Segment used for libraries
#define LIB_SEGMENT	NEARFUNC_T

CPU_MODE	MACRO
		CODE16
		ENDM

#else		/////// __ARM_LIBRARY__

; RTMODEL attribute __cpu_mode
#define CPU_MODE_NAME	"arm"
; Segment used for libraries
#define LIB_SEGMENT	NEARFUNC_A

CPU_MODE	MACRO
		CODE32
		ENDM

#endif

SEGMENT_ALIGN	DEFINE	2		; Align all segments to 2^2
	

;---------------------------------------------------------------
; ?RESET
; Reset Vector.
; Normally, segment INTVEC is linked at address 0.
; For debugging purposes, INTVEC may be placed at other
; addresses.
; A debugger that honors the entry point will start the
; program in a normal way even if INTVEC is not at address 0.
;---------------------------------------------------------------

		PROGRAM	?RESET
		COMMON	INTVEC:CODE:ROOT(2)
		EXTERN	?boot
		EXTERN	undef_handler, swi_handler, prefetch_handler
		EXTERN	data_handler, irq_handler, fiq_handler
		CODE32	; Always ARM mode after reset	
		org	0x00
reset		ldr	pc,=?boot
		org	0x04
;		ldr	pc,=undef_handler
		org	0x08
;		ldr	pc,=swi_handler
		org	0x0c
;		ldr	pc,=prefetch_handler
		org	0x10
;		ldr	pc,=data_handler
		org	0x18
;		ldr	pc,=irq_handler
		org	0x1c
;		ldr	pc,=fiq_handler

		; Constant table entries (for ldr pc) will be placed at 0x20
		org	0x20
		LTORG
		ENDMOD	


;---------------------------------------------------------------
; ?BOOT
;---------------------------------------------------------------
		PROGRAM	?BOOT
		RSEG	ICODE:CODE:NOROOT(2)
		EXTERN	?cstartup
		CODE32
		PUBLIC ?boot
?boot:
#if AT91_REMAP
                ; The memory controller is initialized immediately before the remap
                ldr     r10, =EBI_init_table ; EBI register initialization table
                ; If pc > 0x100000
                movs    r0, pc, LSR #20
                ; Mask the 12 highest bits of the address
                moveq   r10, r10, LSL #12
                moveq   r10, r10, LSR #12

                ; Load the address where to jump
                ldr     r12, =after_remap ; get the real jump address ( after remap )

                ; Copy chip select register image to memory controller and command remap
                ldmia   r10!, {r0-r9,r11}       ; load the complete image and the EBI base
                stmia   r11!, {r0-r9}           ; store the complete image with the remap command

                ; jump to ROM at its new address
                ; this instruction was loaded into the pipeline before the remap was done
                mov         pc, r12             ; jump and break the pipeline

                ; Put constant table here.
                LTORG

                ; EBI initialization table
                ; 32,768 MHz master clock assumed for timing
EBI_init_table:
                dc32        0x01002529  ; Flash at 0x01000000, 16MB, 2 hold, 16 bits, 3 WS
                dc32        0x02002121  ; RAM   at 0x02000000,  1MB, 0 hold, 16 bits, 1 WS
                dc32        0x20000000  ; unused
                dc32        0x30000000  ; unused
                dc32        0x40000000  ; unused
                dc32        0x50000000  ; unused
                dc32        0x60000000  ; unused
                dc32        0x70000000  ; unused
                dc32        0x00000001  ; REMAP command
                dc32        0x00000006  ; standard read
                dc32        __EBI_CSR0  ; EBI Base address

after_remap:
#endif
                ; Execute C startup code.
                b           ?cstartup
		ENDMOD ?boot		; Entry point = ?boot


;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
		PROGRAM	?CSTARTUP

; RTMODEL attributes ensure that
		RTMODEL "__endian", ENDIAN_MODE
		RTMODEL "__thumb_aware", "enabled"
		RTMODEL "__cpu_mode", "*"       ; CPU_MODE_NAME
		RTMODEL "__code_model", "*"	; Match all code models

; Declare segment used with SFE below
#ifdef _ECPLUSPLUS
		RSEG	DIFUNCT(2)
#endif /* _ECPLUSPLUS */

		RSEG	IRQ_STACK:DATA(2)
		RSEG	SVC_STACK:DATA:NOROOT(2)
		RSEG	CSTACK:DATA(2)
		RSEG	ICODE:CODE:NOROOT(2)
		PUBLIC	?cstartup
#ifdef __THUMB_LIBRARY__
		PUBLIC	?thumb_entry
#endif /*  __THUMB_LIBRARY__ */
		EXTERN	__segment_init
		EXTERN	__low_level_init
#ifdef _ECPLUSPLUS
		EXTERN	__call_ctors
#endif /*  _ECPLUSPLUS */
		EXTERN	main
		EXTERN  exit
		EXTERN	_exit

; Execution starts here.
; After a reset, the mode is ARM, Supervisor, interrupts disabled.

		LTORG

		CODE32
?cstartup

; Initialize the stack pointers.
; The pattern below can be used for any of the exception stacks:
; FIQ, IRQ, SVC, ABT, UND, SYS.
; The USR mode uses the same stack as SYS. 
; The stack segments must be defined in the linker command file,
; and be declared above.
		mrs	r0,cpsr				; Original PSR value
		bic	r0,r0,#MODE_BITS		; Clear the mode bits
		orr	r0,r0,#IRQ_MODE			; Set IRQ mode bits
		msr	cpsr_c,r0			; Change the mode
		ldr	sp,=SFE(IRQ_STACK) & 0xFFFFFFF8	; End of IRQ_STACK

		bic	r0,r0,#MODE_BITS		; Clear the mode bits
		orr	r0,r0,#SVC_MODE			; Set Supervisor mode bits
		msr	cpsr_c,r0		        ; Change the mode
		ldr	sp,=SFE(CSTACK) & 0xFFFFFFF8	; End of CSTACK

        
; Initialize segments.
; __segment_init and __low_level_init are assumed to use the same
; instruction set and to be reachable by BL from the ICODE segment
; (it is safest to link them in segment ICODE).

;
; We switch to the same mode here as in the rest of the library
;

#ifdef __THUMB_LIBRARY__
		add     r12,pc,#1
                bx	r12
#endif

		CPU_MODE
#ifdef __THUMB_LIBRARY__
?thumb_entry:
#endif
		ldr     r4,=__low_level_init
		ldr     r5,=after__low_level_init
		ldr     r6,=__segment_init
		ldr     r7,=after__segment_init									

		mov	lr,r5
                bx      r4		; Call __low_level_init

after__low_level_init:
        
		cmp	r0,#0
		beq	after__segment_init

		mov	lr,r7
                bx      r6

		LTORG


                CPU_MODE
after__segment_init:

		REQUIRE	?jump_to_main

; Call the constructors of all global objects. This code will only
; be used if any EC++ modules defines global objects that need to
; have its constructor called before main.

#ifdef _ECPLUSPLUS

		RSEG	ICODE:CODE:NOROOT(2)

		PUBLIC	?call_ctors

		CPU_MODE
?call_ctors:
		ldr	r0,=SFB(DIFUNCT)		
		ldr	r1,=SFE(DIFUNCT)

                ldr     r4,=__call_ctors
                ldr     r5,=after__call_ctors
		mov	lr,r5
                bx      r4

		LTORG

		CPU_MODE
after__call_ctors:

#endif /* _ECPLUSPLUS */

; Jump to main, using BX. Set _exit as the return address.
; main may be located anywhere in memory, and be of
; either ARM or Thumb mode, since BX is used.
; main is assumed to return using BX (__interwork) if it is of
; a different mode than cstartup, otherwise it will return
; in the wrong mode, causing unpredicatble behaviour.

		RSEG	ICODE:CODE:NOROOT(2)
		PUBLIC	__main

		CPU_MODE
?jump_to_main:
		ldr     r4,=main
                ldr     r5,=__main
		mov     r0,#0   ;  No parameters 
		mov	lr,r5        
		bx	r4

        CPU_MODE
__main:
?call_exit:
		ldr	r4,=exit
		ldr     r5,=_exit
		mov	lr,r5
		bx	r4

		LTORG
		ENDMOD


;---------------------------------------------------------------
; ?_EXIT
; main may return an exit code in R0, or _exit may be called with
; the exit code in R0.
; If the exit code is needed for som reason, R0 should be stored 
; in e.g. one of the registers R4-R7, so that the value is 
; preserved when calling __call_dtors and _Close_all.
;---------------------------------------------------------------
		MODULE	?_EXIT
		RSEG	LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
                PUBLIC  _exit
                REQUIRE ?jump_to_exit


		CPU_MODE		
_exit:
; Fall through to the next module


                RSEG	LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
                REQUIRE	?exit_restore
                PUBLIC	?exit_save

		CPU_MODE
?exit_save: 	
		mov		r7,r0

;---------------------------------------------------------------
; ?CALL_DTORS
; This module is only linked if needed by atexit.
;---------------------------------------------------------------

		RSEG	LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
		PUBLIC	__cstart_call_dtors
		REQUIRE	?exit_save

		CPU_MODE

; This label is required by "__record_needed_destruction".
__cstart_call_dtors:
                ldr     r4,?constants          ;  =__call_dtors
                ldr     r5,?constants+4        ;  =after__call_dtors
                mov	lr,r5
                bx      r4

after__call_dtors:

; Fall through to the next segment part


;---------------------------------------------------------------
; ?CALL_CLOSE
; This segment part is only linked if needed for closing files.
;---------------------------------------------------------------

		RSEG	LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
		PUBLIC	__cstart_closeall
		EXTERN	_Close_all
                REQUIRE ?exit_save

		CPU_MODE

; This label is required by functions operating on files
__cstart_closeall:
                ldr     r4,?constants+8        ;  =_Close_all
                ldr     r5,?constants+12       ;  =after_Close_all
                mov     lr,r5
                bx      r4

after_Close_all:        

; Fall through to the next segment part


;---------------------------------------------------------------
; ?_EXIT_END
; Restore the argument previously stored by the "save" section
; above.
;---------------------------------------------------------------

		RSEG        LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
		PUBLIC      ?exit_restore

		CPU_MODE

?exit_restore:
                mov	r0,r7

		;; Fall through to the __exit code below

;---------------------------------------------------------------
; ?JUMP_TO_EXIT
;---------------------------------------------------------------

		RSEG	LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
		PUBLIC	?jump_to_exit
		EXTERN	__exit

; It is not possible to fall through to __exit, because the following 
; module is only used when linking for debugging (XLINK -r).

?jump_to_exit:	

                ldr     r4,?constants+16        ;  =__exit
		mov	lr,r4
                bx      r4
        
        
       	        RSEG	LIB_SEGMENT:CODE:NOROOT(SEGMENT_ALIGN)
		EXTERN	__call_dtors
		EXTERN	_Close_all
		EXTERN	__exit

                DATA
?constants:     
                DC32    __call_dtors
		DC32	after__call_dtors
                DC32    _Close_all
		DC32	after_Close_all
                DC32    __exit
                
                ENDMOD


;---------------------------------------------------------------
; ?__EXIT
; __exit is declared PUBWEAK, which makes XLINK skip this module
; if another module containing a PUBLIC __exit is linked.
;---------------------------------------------------------------
		
		MODULE	?__EXIT
		RSEG	LIB_SEGMENT:CODE:NOROOT(2)
		PUBWEAK	__exit

		CPU_MODE		; Either Thumb or ARM mode
__exit

#ifdef __THUMB_LIBRARY__
		bx	pc
		nop
#endif

		CODE32		
		b	.		; Eternal loop

		ENDMOD


;---------------------------------------------------------------
; ?INITTAB
; This module is only linked if needed by e.g. __segment_init.
; The INITTAB segment contains segment initialization entries.
; See segment_init.h.
;---------------------------------------------------------------
		MODULE	?INITTAB
		RSEG	INITTAB:CONST(2)  ; Declaration for SFB/SFE below
		RSEG	HUGE_C:CONST:NOROOT(2)
		DATA
		PUBLIC	__segment_begin_INITTAB
		PUBLIC	__segment_end_INITTAB

__segment_begin_INITTAB	DC32	SFB(INITTAB)
__segment_end_INITTAB	DC32	SFE(INITTAB)

		ENDMOD

		END








⌨️ 快捷键说明

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